mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Fixed various memory leaks + ModelLoader cleanup
This commit is contained in:
@@ -13,11 +13,8 @@ namespace GlitchyEngine.Content
|
|||||||
static readonly Matrix RightToLeftHand = .Scaling(1, 1, -1);
|
static readonly Matrix RightToLeftHand = .Scaling(1, 1, -1);
|
||||||
|
|
||||||
public static void LoadModel(String filename, Effect validationEffect, Material material, EcsWorld world,
|
public static void LoadModel(String filename, Effect validationEffect, Material material, EcsWorld world,
|
||||||
List<(Matrix Transform, GeometryBinding Model)> output, out Skeleton skeleton, out List<AnimationClip> clips)
|
List<AnimationClip> outClips)
|
||||||
{
|
{
|
||||||
skeleton = null;
|
|
||||||
removeMe___Clips = null;
|
|
||||||
|
|
||||||
CGLTF.Options options = .();
|
CGLTF.Options options = .();
|
||||||
CGLTF.Data* data;
|
CGLTF.Data* data;
|
||||||
CGLTF.Result result = CGLTF.ParseFile(options, filename, out data);
|
CGLTF.Result result = CGLTF.ParseFile(options, filename, out data);
|
||||||
@@ -30,44 +27,13 @@ namespace GlitchyEngine.Content
|
|||||||
|
|
||||||
for(var node in data.Scenes[0].Nodes)
|
for(var node in data.Scenes[0].Nodes)
|
||||||
{
|
{
|
||||||
NodesToEntities(data, node, null, world, validationEffect, material);
|
NodesToEntities(data, node, null, world, validationEffect, material, outClips);
|
||||||
}
|
}
|
||||||
|
|
||||||
clips = removeMe___Clips;
|
|
||||||
|
|
||||||
|
|
||||||
for(var node in data.Nodes)
|
|
||||||
{
|
|
||||||
if(node.Mesh != null)
|
|
||||||
{
|
|
||||||
Matrix transform = ?;
|
|
||||||
CGLTF.NodeTransformLocal(&node, (float*)&transform);
|
|
||||||
|
|
||||||
transform = RightToLeftHand * transform;
|
|
||||||
|
|
||||||
for(var primitive in node.Mesh.Primitives)
|
|
||||||
{
|
|
||||||
GeometryBinding binding = ModelLoader.PrimitiveToGeoBinding(primitive, validationEffect);
|
|
||||||
|
|
||||||
output.Add((transform, binding));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(node.Skin != null)
|
|
||||||
{
|
|
||||||
AnimationClip clip;
|
|
||||||
(skeleton, clip) = ExtractBonestuff(node.Skin, data);
|
|
||||||
clips.Add(clip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CGLTF.Free(data);
|
CGLTF.Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<AnimationClip> removeMe___Clips;
|
private static void NodesToEntities(CGLTF.Data* data, CGLTF.Node* node, Entity? parentEntity, EcsWorld world, Effect validationEffect, Material material, List<AnimationClip> clips)
|
||||||
|
|
||||||
private static void NodesToEntities(CGLTF.Data* data, CGLTF.Node* node, Entity? parentEntity, EcsWorld world, Effect validationEffect, Material material)
|
|
||||||
{
|
{
|
||||||
Entity entity = world.NewEntity();
|
Entity entity = world.NewEntity();
|
||||||
|
|
||||||
@@ -116,8 +82,7 @@ namespace GlitchyEngine.Content
|
|||||||
{
|
{
|
||||||
skeleton = ExtractSkeleton(node.Skin);
|
skeleton = ExtractSkeleton(node.Skin);
|
||||||
|
|
||||||
removeMe___Clips = new List<AnimationClip>();
|
LoadAnimationClips(data, node.Skin, skeleton, clips);
|
||||||
LoadAnimationClips(data, node.Skin, skeleton, removeMe___Clips);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node.Mesh != null)
|
if(node.Mesh != null)
|
||||||
@@ -126,7 +91,11 @@ namespace GlitchyEngine.Content
|
|||||||
if(node.Mesh.Primitives.Length == 1)
|
if(node.Mesh.Primitives.Length == 1)
|
||||||
{
|
{
|
||||||
var mesh = world.AssignComponent<MeshComponent>(entity);
|
var mesh = world.AssignComponent<MeshComponent>(entity);
|
||||||
mesh.Mesh = ModelLoader.PrimitiveToGeoBinding(node.Mesh.Primitives[0], validationEffect);
|
|
||||||
|
using (var geo = PrimitiveToGeoBinding(node.Mesh.Primitives[0], validationEffect))
|
||||||
|
{
|
||||||
|
mesh.Mesh = geo;
|
||||||
|
}
|
||||||
|
|
||||||
if(skeleton == null)
|
if(skeleton == null)
|
||||||
{
|
{
|
||||||
@@ -168,9 +137,11 @@ namespace GlitchyEngine.Content
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skeleton?.ReleaseRef();
|
||||||
|
|
||||||
for(var child in node.Children)
|
for(var child in node.Children)
|
||||||
{
|
{
|
||||||
NodesToEntities(data, child, entity, world, validationEffect, material);
|
NodesToEntities(data, child, entity, world, validationEffect, material, clips);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,6 +435,9 @@ namespace GlitchyEngine.Content
|
|||||||
|
|
||||||
ref JointAnimation jointAnimation = ref clip.JointAnimations[nodeIndex];
|
ref JointAnimation jointAnimation = ref clip.JointAnimations[nodeIndex];
|
||||||
|
|
||||||
|
if(jointAnimation == null)
|
||||||
|
jointAnimation = new JointAnimation();
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(channel.Sampler.Input.Count == channel.Sampler.Output.Count);
|
Log.EngineLogger.AssertDebug(channel.Sampler.Input.Count == channel.Sampler.Output.Count);
|
||||||
|
|
||||||
int samples = (int)channel.Sampler.Input.Count;
|
int samples = (int)channel.Sampler.Input.Count;
|
||||||
@@ -536,131 +510,6 @@ namespace GlitchyEngine.Content
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static (Skeleton, AnimationClip) ExtractBonestuff(CGLTF.Skin* skin, CGLTF.Data* data)
|
|
||||||
{
|
|
||||||
Skeleton skeleton = new Skeleton();
|
|
||||||
skeleton.Joints = new Joint[skin.Joints.Length];
|
|
||||||
|
|
||||||
AnimationClip testClip = new AnimationClip(skeleton);
|
|
||||||
testClip.IsLooping = true;
|
|
||||||
|
|
||||||
for(int i < skin.Joints.Length)
|
|
||||||
{
|
|
||||||
ref Joint joint = ref skeleton.Joints[i];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
joint.InverseBindPose = GetEntry<Matrix>(skin.InverseBindMatrices, i);
|
|
||||||
|
|
||||||
joint.Name = new String(skin.Joints[i].Name);
|
|
||||||
|
|
||||||
int parentId = skin.Joints.IndexOf(skin.Joints[i].Parent);
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(parentId < uint8.MaxValue, scope $"A skeleton must not have more than {uint8.MaxValue - 1} bones.");
|
|
||||||
|
|
||||||
if(parentId == -1)
|
|
||||||
joint.ParentID = uint8.MaxValue;
|
|
||||||
else
|
|
||||||
joint.ParentID = (uint8)parentId;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(var channel in data.Animations[0].Channels)
|
|
||||||
{
|
|
||||||
int nodeIndex = skin.Joints.IndexOf(channel.TargetNode);
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(nodeIndex != -1);
|
|
||||||
|
|
||||||
ref JointAnimation jointAnimation = ref testClip.JointAnimations[nodeIndex];
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(channel.Sampler.Input.Count == channel.Sampler.Output.Count);
|
|
||||||
|
|
||||||
int samples = (int)channel.Sampler.Input.Count;
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(channel.Sampler.Input.ComponentType == .R_32f);
|
|
||||||
Log.EngineLogger.AssertDebug(channel.Sampler.Input.Type == .Scalar);
|
|
||||||
|
|
||||||
InterpolationMode interpolationMode;
|
|
||||||
|
|
||||||
switch(channel.Sampler.Interpolation)
|
|
||||||
{
|
|
||||||
case .Step:
|
|
||||||
interpolationMode = .Step;
|
|
||||||
case .Linear:
|
|
||||||
interpolationMode = .Linear;
|
|
||||||
case .CubicSpline:
|
|
||||||
interpolationMode = .CubicSpline;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(channel.TargetPath)
|
|
||||||
{
|
|
||||||
case .Translation:
|
|
||||||
jointAnimation.TranslationChannel = new .(samples, interpolationMode);
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(channel.Sampler.Output.ComponentType == .R_32f);
|
|
||||||
Log.EngineLogger.AssertDebug(channel.Sampler.Output.Type == .Vec3);
|
|
||||||
|
|
||||||
for(int i < samples)
|
|
||||||
{
|
|
||||||
float timeStamp = GetEntry<float>(channel.Sampler.Input, i);
|
|
||||||
Vector3 sample = GetEntry<Vector3>(channel.Sampler.Output, i);
|
|
||||||
/*
|
|
||||||
float timeStamp = GetEntry<float>(channel.Sampler.Input, i);
|
|
||||||
float timeStamp2 = ?;
|
|
||||||
CGLTF.AccessorReadFloat(channel.Sampler.Input, (uint)i, (float*)&timeStamp2, 1);
|
|
||||||
|
|
||||||
Log.EngineLogger.Assert(timeStamp == timeStamp2);
|
|
||||||
|
|
||||||
Vector3 sample2 = ?;
|
|
||||||
CGLTF.AccessorReadFloat(channel.Sampler.Output, (uint)i, (float*)&sample2, 3);
|
|
||||||
|
|
||||||
Log.EngineLogger.Assert(sample == sample2);
|
|
||||||
*/
|
|
||||||
jointAnimation.TranslationChannel.TimeStamps[i] = timeStamp;
|
|
||||||
jointAnimation.TranslationChannel.Values[i] = sample;
|
|
||||||
}
|
|
||||||
case .Rotation:
|
|
||||||
jointAnimation.RotationChannel = new .(samples, interpolationMode);
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(channel.Sampler.Output.ComponentType == .R_32f);
|
|
||||||
Log.EngineLogger.AssertDebug(channel.Sampler.Output.Type == .Vec4);
|
|
||||||
|
|
||||||
for(int i < samples)
|
|
||||||
{
|
|
||||||
float timeStamp = GetEntry<float>(channel.Sampler.Input, i);
|
|
||||||
Quaternion sample = GetEntry<Quaternion>(channel.Sampler.Output, i);
|
|
||||||
|
|
||||||
jointAnimation.RotationChannel.TimeStamps[i] = timeStamp;
|
|
||||||
jointAnimation.RotationChannel.Values[i] = sample;
|
|
||||||
}
|
|
||||||
case .Scale:
|
|
||||||
jointAnimation.ScaleChannel = new .(samples, interpolationMode);
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(channel.Sampler.Output.ComponentType == .R_32f);
|
|
||||||
Log.EngineLogger.AssertDebug(channel.Sampler.Output.Type == .Vec3);
|
|
||||||
|
|
||||||
for(int i < samples)
|
|
||||||
{
|
|
||||||
float timeStamp = GetEntry<float>(channel.Sampler.Input, i);
|
|
||||||
Vector3 sample = GetEntry<Vector3>(channel.Sampler.Output, i);
|
|
||||||
|
|
||||||
jointAnimation.ScaleChannel.TimeStamps[i] = timeStamp;
|
|
||||||
jointAnimation.ScaleChannel.Values[i] = sample;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
Log.EngineLogger.Error($"Unknown channel target path \"{channel.TargetPath}\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
//channel.
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
//testClip.JointAnimations[i].
|
|
||||||
testClip.Duration = Math.Max(testClip.Duration, jointAnimation.Duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (skeleton, testClip);
|
|
||||||
}
|
|
||||||
|
|
||||||
static T GetEntry<T>(CGLTF.Accessor* accessor, int index)
|
static T GetEntry<T>(CGLTF.Accessor* accessor, int index)
|
||||||
{
|
{
|
||||||
Log.EngineLogger.AssertDebug((uint)index < accessor.Count);
|
Log.EngineLogger.AssertDebug((uint)index < accessor.Count);
|
||||||
|
|||||||
@@ -68,8 +68,7 @@ namespace GlitchyEngine.Renderer.Animation
|
|||||||
class AnimationClip : RefCounter
|
class AnimationClip : RefCounter
|
||||||
{
|
{
|
||||||
private Skeleton _skeleton ~ _.ReleaseRef();
|
private Skeleton _skeleton ~ _.ReleaseRef();
|
||||||
//public float FramesPerSecond;
|
public JointAnimation[] JointAnimations ~ delete _;
|
||||||
public JointAnimation[] JointAnimations;
|
|
||||||
public bool IsLooping;
|
public bool IsLooping;
|
||||||
public float Duration;
|
public float Duration;
|
||||||
|
|
||||||
@@ -78,7 +77,7 @@ namespace GlitchyEngine.Renderer.Animation
|
|||||||
[AllowAppend]
|
[AllowAppend]
|
||||||
public this(Skeleton skeleton)
|
public this(Skeleton skeleton)
|
||||||
{
|
{
|
||||||
var jointAnimations = append JointAnimation[skeleton.Joints.Count];
|
var jointAnimations = new JointAnimation[skeleton.Joints.Count];
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(skeleton != null);
|
Log.EngineLogger.AssertDebug(skeleton != null);
|
||||||
|
|
||||||
@@ -91,7 +90,8 @@ namespace GlitchyEngine.Renderer.Animation
|
|||||||
{
|
{
|
||||||
for(var jointAnimation in JointAnimations)
|
for(var jointAnimation in JointAnimations)
|
||||||
{
|
{
|
||||||
jointAnimation.Dispose();
|
//jointAnimation.Dispose();
|
||||||
|
delete jointAnimation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,11 +186,11 @@ namespace GlitchyEngine.Renderer.Animation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct JointAnimation : IDisposable
|
class JointAnimation// : IDisposable
|
||||||
{
|
{
|
||||||
public JointAnimationChannel<Vector3> TranslationChannel;
|
public JointAnimationChannel<Vector3> TranslationChannel ~ delete _;
|
||||||
public JointAnimationChannel<Quaternion> RotationChannel;
|
public JointAnimationChannel<Quaternion> RotationChannel ~ delete _;
|
||||||
public JointAnimationChannel<Vector3> ScaleChannel;
|
public JointAnimationChannel<Vector3> ScaleChannel ~ delete _;
|
||||||
|
|
||||||
public float Duration
|
public float Duration
|
||||||
{
|
{
|
||||||
@@ -200,14 +200,14 @@ namespace GlitchyEngine.Renderer.Animation
|
|||||||
TranslationChannel?.Duration ?? 0, RotationChannel?.Duration ?? 0), ScaleChannel?.Duration ?? 0);
|
TranslationChannel?.Duration ?? 0, RotationChannel?.Duration ?? 0), ScaleChannel?.Duration ?? 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
delete TranslationChannel;
|
delete TranslationChannel;
|
||||||
delete RotationChannel;
|
delete RotationChannel;
|
||||||
delete ScaleChannel;
|
delete ScaleChannel;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
public JointPose GetCurrentPose(float timeStamp)
|
public JointPose GetCurrentPose(float timeStamp)
|
||||||
{
|
{
|
||||||
JointPose result;
|
JointPose result;
|
||||||
|
|||||||
@@ -1,7 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using GlitchyEngine.World;
|
||||||
|
|
||||||
namespace GlitchyEngine.Renderer
|
namespace GlitchyEngine.Renderer
|
||||||
{
|
{
|
||||||
public struct MeshComponent
|
public struct MeshComponent : IDisposableComponent
|
||||||
{
|
{
|
||||||
public GeometryBinding Mesh;
|
private GeometryBinding _mesh;
|
||||||
|
public GeometryBinding Mesh
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get => _mesh;
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
if(_mesh == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SetReference!(_mesh, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DisposeComponent(void* component)
|
||||||
|
{
|
||||||
|
Self* self = (Self*)component;
|
||||||
|
|
||||||
|
ReleaseRefAndNullify!(self._mesh);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ namespace GlitchyEngine.World
|
|||||||
if(_animationClip == value)
|
if(_animationClip == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_animationClip?.ReleaseRef();
|
SetReference!(_animationClip, value);
|
||||||
_animationClip = value;
|
|
||||||
_animationClip?.AddRef();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -215,25 +215,10 @@ namespace Sandbox
|
|||||||
TestLoadModel();
|
TestLoadModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
//GeometryBinding _modelTest ~ _?.ReleaseRef();
|
List<AnimationClip> Clips = new List<AnimationClip>() ~ DeleteContainerAndReleaseItems!(_);
|
||||||
|
|
||||||
List<(Matrix Transform, GeometryBinding Model)> _modelTest = new .() ~ UnloadModelTest!();
|
|
||||||
|
|
||||||
Skeleton Skeleton;
|
|
||||||
List<AnimationClip> Clips ~ delete _;
|
|
||||||
|
|
||||||
Material animationMat;
|
Material animationMat;
|
||||||
|
|
||||||
mixin UnloadModelTest()
|
|
||||||
{
|
|
||||||
for(var entry in _modelTest)
|
|
||||||
{
|
|
||||||
entry.Model?.ReleaseRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete _modelTest;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestLoadModel()
|
void TestLoadModel()
|
||||||
{
|
{
|
||||||
var testEffect = Application.Get().EffectLibrary.Get("testShader");
|
var testEffect = Application.Get().EffectLibrary.Get("testShader");
|
||||||
@@ -255,13 +240,7 @@ namespace Sandbox
|
|||||||
materialTestMaterial.SetVariable("BaseColor", Color.White);
|
materialTestMaterial.SetVariable("BaseColor", Color.White);
|
||||||
materialTestMaterial.SetVariable("LightDir", Vector3(1, 1, -0.5f).Normalized());
|
materialTestMaterial.SetVariable("LightDir", Vector3(1, 1, -0.5f).Normalized());
|
||||||
|
|
||||||
//ModelLoader.LoadModel("content\\Models\\Test\\axisTest.glb", testEffect, _modelTest, out Skeleton, out Clip);
|
ModelLoader.LoadModel("content\\Models\\Figure\\Figure.gltf", testEffect, materialTestMaterial, _world, Clips);
|
||||||
//ModelLoader.LoadModel("content\\Models\\RiggedSimple\\RiggedSimple.glb", testEffect, _modelTest, out Skeleton, out Clip);
|
|
||||||
//ModelLoader.LoadModel("content\\Models\\Fox\\Fox.glb", testEffect, _modelTest, out Skeleton, out Clip);
|
|
||||||
//ModelLoader.LoadModel("content\\Models\\Fox\\Fox_2.glb", testEffect, materialTestMaterial, _world, _modelTest, out Skeleton, out Clips);
|
|
||||||
//ModelLoader.LoadModel("content\\Models\\DancingCylinder\\DancingCylinder.glb", testEffect, _modelTest, out Skeleton, out Clip);
|
|
||||||
ModelLoader.LoadModel("content\\Models\\Figure\\Figure.gltf", testEffect, materialTestMaterial, _world, _modelTest, out Skeleton, out Clips);
|
|
||||||
//ModelLoader.LoadModel("content\\Models\\RiggedFigure\\RiggedFigure.glb", testEffect, materialTestMaterial, _world, _modelTest, out Skeleton, out Clips);
|
|
||||||
|
|
||||||
materialTestMaterial.ReleaseRef();
|
materialTestMaterial.ReleaseRef();
|
||||||
testEffect.ReleaseRef();
|
testEffect.ReleaseRef();
|
||||||
@@ -275,28 +254,6 @@ namespace Sandbox
|
|||||||
animation.IsPlaying = true;
|
animation.IsPlaying = true;
|
||||||
animation.[Friend]_pose = new SkeletonPose(meshRenderer.Skeleton);
|
animation.[Friend]_pose = new SkeletonPose(meshRenderer.Skeleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
CGLTF.Options options = .();
|
|
||||||
CGLTF.Data* data;
|
|
||||||
CGLTF.Result result = CGLTF.ParseFile(options, "content\\Models\\box.gltf", out data);
|
|
||||||
|
|
||||||
CGLTF.LoadBuffers(options, data, "content\\Models\\box.gltf");
|
|
||||||
|
|
||||||
Log.EngineLogger.Assert(result == .Success, "Failed to load model");
|
|
||||||
|
|
||||||
var mesh = data.Meshes[0];
|
|
||||||
var primitive = mesh.Primitives[0];
|
|
||||||
|
|
||||||
var testEffect = _effectLibrary.Get("testShader");
|
|
||||||
|
|
||||||
_modelTest = ModelLoader.PrimitiveToGeoBinding(_context, primitive, testEffect);
|
|
||||||
|
|
||||||
testEffect.ReleaseRef();
|
|
||||||
|
|
||||||
/* TODO make awesome stuff */
|
|
||||||
CGLTF.Free(data);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity evenCrazierParent;
|
Entity evenCrazierParent;
|
||||||
@@ -436,8 +393,10 @@ namespace Sandbox
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var skeleton = currentClip.Skeleton;
|
||||||
|
|
||||||
// Update joints
|
// Update joints
|
||||||
for(int i < Skeleton.Joints.Count)
|
for(int i < skeleton.Joints.Count)
|
||||||
{
|
{
|
||||||
ref JointPose localPose = ref pose.LocalPose[i];
|
ref JointPose localPose = ref pose.LocalPose[i];
|
||||||
|
|
||||||
@@ -448,7 +407,7 @@ namespace Sandbox
|
|||||||
Matrix.RotationQuaternion(localPose.Rotation) *
|
Matrix.RotationQuaternion(localPose.Rotation) *
|
||||||
Matrix.Scaling(localPose.Scale);
|
Matrix.Scaling(localPose.Scale);
|
||||||
|
|
||||||
uint8 parentIndex = Skeleton.Joints[i].ParentID;
|
uint8 parentIndex = skeleton.Joints[i].ParentID;
|
||||||
|
|
||||||
ref Matrix globalPose = ref pose.GlobalPose[i];
|
ref Matrix globalPose = ref pose.GlobalPose[i];
|
||||||
|
|
||||||
@@ -461,7 +420,7 @@ namespace Sandbox
|
|||||||
globalPose = pose.GlobalPose[parentIndex] * jointToParent;
|
globalPose = pose.GlobalPose[parentIndex] * jointToParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
pose.SkinningMatricies[i] = globalPose * Skeleton.Joints[i].InverseBindPose;
|
pose.SkinningMatricies[i] = globalPose * skeleton.Joints[i].InverseBindPose;
|
||||||
pose.InvTransSkinningMatricies[i] = ((Matrix3x3)pose.SkinningMatricies[i]).Inverse().Transpose();
|
pose.InvTransSkinningMatricies[i] = ((Matrix3x3)pose.SkinningMatricies[i]).Inverse().Transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user