diff --git a/GlitchyEngine/src/Content/ModelLoader.bf b/GlitchyEngine/src/Content/ModelLoader.bf index 0388a22..1fb46ea 100644 --- a/GlitchyEngine/src/Content/ModelLoader.bf +++ b/GlitchyEngine/src/Content/ModelLoader.bf @@ -13,11 +13,8 @@ namespace GlitchyEngine.Content static readonly Matrix RightToLeftHand = .Scaling(1, 1, -1); public static void LoadModel(String filename, Effect validationEffect, Material material, EcsWorld world, - List<(Matrix Transform, GeometryBinding Model)> output, out Skeleton skeleton, out List clips) + List outClips) { - skeleton = null; - removeMe___Clips = null; - CGLTF.Options options = .(); CGLTF.Data* 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) { - 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); } - static List removeMe___Clips; - - private static void NodesToEntities(CGLTF.Data* data, CGLTF.Node* node, Entity? parentEntity, EcsWorld world, Effect validationEffect, Material material) + private static void NodesToEntities(CGLTF.Data* data, CGLTF.Node* node, Entity? parentEntity, EcsWorld world, Effect validationEffect, Material material, List clips) { Entity entity = world.NewEntity(); @@ -116,8 +82,7 @@ namespace GlitchyEngine.Content { skeleton = ExtractSkeleton(node.Skin); - removeMe___Clips = new List(); - LoadAnimationClips(data, node.Skin, skeleton, removeMe___Clips); + LoadAnimationClips(data, node.Skin, skeleton, clips); } if(node.Mesh != null) @@ -126,7 +91,11 @@ namespace GlitchyEngine.Content if(node.Mesh.Primitives.Length == 1) { var mesh = world.AssignComponent(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) { @@ -168,9 +137,11 @@ namespace GlitchyEngine.Content } } + skeleton?.ReleaseRef(); + 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]; + if(jointAnimation == null) + jointAnimation = new JointAnimation(); + Log.EngineLogger.AssertDebug(channel.Sampler.Input.Count == channel.Sampler.Output.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(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(channel.Sampler.Input, i); - Vector3 sample = GetEntry(channel.Sampler.Output, i); - /* - float timeStamp = GetEntry(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(channel.Sampler.Input, i); - Quaternion sample = GetEntry(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(channel.Sampler.Input, i); - Vector3 sample = GetEntry(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(CGLTF.Accessor* accessor, int index) { Log.EngineLogger.AssertDebug((uint)index < accessor.Count); diff --git a/GlitchyEngine/src/Renderer/Animation/AnimationClip.bf b/GlitchyEngine/src/Renderer/Animation/AnimationClip.bf index 4fc6460..c033d61 100644 --- a/GlitchyEngine/src/Renderer/Animation/AnimationClip.bf +++ b/GlitchyEngine/src/Renderer/Animation/AnimationClip.bf @@ -68,8 +68,7 @@ namespace GlitchyEngine.Renderer.Animation class AnimationClip : RefCounter { private Skeleton _skeleton ~ _.ReleaseRef(); - //public float FramesPerSecond; - public JointAnimation[] JointAnimations; + public JointAnimation[] JointAnimations ~ delete _; public bool IsLooping; public float Duration; @@ -78,7 +77,7 @@ namespace GlitchyEngine.Renderer.Animation [AllowAppend] public this(Skeleton skeleton) { - var jointAnimations = append JointAnimation[skeleton.Joints.Count]; + var jointAnimations = new JointAnimation[skeleton.Joints.Count]; Log.EngineLogger.AssertDebug(skeleton != null); @@ -91,7 +90,8 @@ namespace GlitchyEngine.Renderer.Animation { 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 TranslationChannel; - public JointAnimationChannel RotationChannel; - public JointAnimationChannel ScaleChannel; + public JointAnimationChannel TranslationChannel ~ delete _; + public JointAnimationChannel RotationChannel ~ delete _; + public JointAnimationChannel ScaleChannel ~ delete _; public float Duration { @@ -200,14 +200,14 @@ namespace GlitchyEngine.Renderer.Animation TranslationChannel?.Duration ?? 0, RotationChannel?.Duration ?? 0), ScaleChannel?.Duration ?? 0); } } - + /* public void Dispose() { delete TranslationChannel; delete RotationChannel; delete ScaleChannel; } - + */ public JointPose GetCurrentPose(float timeStamp) { JointPose result; diff --git a/GlitchyEngine/src/Renderer/MeshComponent.bf b/GlitchyEngine/src/Renderer/MeshComponent.bf index adca007..3a1daf0 100644 --- a/GlitchyEngine/src/Renderer/MeshComponent.bf +++ b/GlitchyEngine/src/Renderer/MeshComponent.bf @@ -1,7 +1,29 @@ +using System; +using GlitchyEngine.World; + 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); + } } } diff --git a/GlitchyEngine/src/World/AnimationComponent.bf b/GlitchyEngine/src/World/AnimationComponent.bf index 3b42ffa..51ab285 100644 --- a/GlitchyEngine/src/World/AnimationComponent.bf +++ b/GlitchyEngine/src/World/AnimationComponent.bf @@ -16,9 +16,7 @@ namespace GlitchyEngine.World if(_animationClip == value) return; - _animationClip?.ReleaseRef(); - _animationClip = value; - _animationClip?.AddRef(); + SetReference!(_animationClip, value); } } diff --git a/Sandbox/src/SandboxApp.bf b/Sandbox/src/SandboxApp.bf index b1ba8b0..790683a 100644 --- a/Sandbox/src/SandboxApp.bf +++ b/Sandbox/src/SandboxApp.bf @@ -215,25 +215,10 @@ namespace Sandbox TestLoadModel(); } - //GeometryBinding _modelTest ~ _?.ReleaseRef(); - - List<(Matrix Transform, GeometryBinding Model)> _modelTest = new .() ~ UnloadModelTest!(); - - Skeleton Skeleton; - List Clips ~ delete _; + List Clips = new List() ~ DeleteContainerAndReleaseItems!(_); Material animationMat; - mixin UnloadModelTest() - { - for(var entry in _modelTest) - { - entry.Model?.ReleaseRef(); - } - - delete _modelTest; - } - void TestLoadModel() { var testEffect = Application.Get().EffectLibrary.Get("testShader"); @@ -255,13 +240,7 @@ namespace Sandbox materialTestMaterial.SetVariable("BaseColor", Color.White); 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\\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); + ModelLoader.LoadModel("content\\Models\\Figure\\Figure.gltf", testEffect, materialTestMaterial, _world, Clips); materialTestMaterial.ReleaseRef(); testEffect.ReleaseRef(); @@ -275,28 +254,6 @@ namespace Sandbox animation.IsPlaying = true; 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; @@ -436,8 +393,10 @@ namespace Sandbox } } + var skeleton = currentClip.Skeleton; + // Update joints - for(int i < Skeleton.Joints.Count) + for(int i < skeleton.Joints.Count) { ref JointPose localPose = ref pose.LocalPose[i]; @@ -448,7 +407,7 @@ namespace Sandbox Matrix.RotationQuaternion(localPose.Rotation) * Matrix.Scaling(localPose.Scale); - uint8 parentIndex = Skeleton.Joints[i].ParentID; + uint8 parentIndex = skeleton.Joints[i].ParentID; ref Matrix globalPose = ref pose.GlobalPose[i]; @@ -461,7 +420,7 @@ namespace Sandbox 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(); }