private glTFLoader.Schema.Animation CreateAnimation(AoMEngineLibrary.Graphics.Model.Animation animation, int weightCount, Stream bufferStream) { var sampler = new AnimationSampler(); sampler.Interpolation = AnimationSampler.InterpolationEnum.LINEAR; CreateKeysBuffer(animation, bufferStream); sampler.Input = accessors.Count - 1; CreateWeightsBuffer(animation, weightCount, bufferStream); sampler.Output = accessors.Count - 1; var target = new AnimationChannelTarget(); target.Node = 0; target.Path = AnimationChannelTarget.PathEnum.weights; var channel = new AnimationChannel(); channel.Sampler = 0; channel.Target = target; var gltfAnimation = new glTFLoader.Schema.Animation(); gltfAnimation.Samplers = new[] { sampler }; gltfAnimation.Channels = new[] { channel }; return(gltfAnimation); }
private void CreateWeightsBuffer(AoMEngineLibrary.Graphics.Model.Animation animation, int weightCount, Stream bufferStream) { long bufferViewOffset; using (BinaryWriter writer = new BinaryWriter(bufferStream, Encoding.UTF8, true)) { // padding writer.Write(new byte[(-bufferStream.Length) & (PaddingBytes(Accessor.ComponentTypeEnum.FLOAT) - 1)]); bufferViewOffset = bufferStream.Length; for (int i = 0; i < weightCount; ++i) { writer.Write(0.0f); } for (int i = 1; i < animation.MeshKeys.Count; ++i) { for (int j = 0; j < weightCount; ++j) { writer.Write(i == j + 1 ? 1.0f : 0.0f); } } } BufferView posBufferView = new BufferView(); posBufferView.Buffer = 0; posBufferView.ByteLength = animation.MeshKeys.Count * weightCount * 4; posBufferView.ByteOffset = (int)bufferViewOffset; posBufferView.Name = "weightsBufferView"; Accessor posAccessor = new Accessor(); posAccessor.BufferView = bufferViews.Count; posAccessor.ByteOffset = 0; posAccessor.ComponentType = Accessor.ComponentTypeEnum.FLOAT; posAccessor.Count = animation.MeshKeys.Count * weightCount; posAccessor.Max = new[] { 1.0f }; posAccessor.Min = new[] { 0.0f }; posAccessor.Name = "weightsBufferViewAccessor"; posAccessor.Type = Accessor.TypeEnum.SCALAR; bufferViews.Add(posBufferView); accessors.Add(posAccessor); }
private void CreateKeysBuffer(AoMEngineLibrary.Graphics.Model.Animation animation, Stream bufferStream) { long bufferViewOffset; float min = float.MaxValue; float max = float.MinValue; using (BinaryWriter writer = new BinaryWriter(bufferStream, Encoding.UTF8, true)) { // padding writer.Write(new byte[(-bufferStream.Length) & (PaddingBytes(Accessor.ComponentTypeEnum.FLOAT) - 1)]); bufferViewOffset = bufferStream.Length; for (int i = 0; i < animation.MeshKeys.Count; ++i) { min = Math.Min(min, animation.MeshKeys[i]); max = Math.Max(max, animation.MeshKeys[i]); writer.Write(animation.MeshKeys[i]); } } BufferView posBufferView = new BufferView(); posBufferView.Buffer = 0; posBufferView.ByteLength = animation.MeshKeys.Count * 4; posBufferView.ByteOffset = (int)bufferViewOffset; posBufferView.Name = "keysBufferView"; Accessor posAccessor = new Accessor(); posAccessor.BufferView = bufferViews.Count; posAccessor.ByteOffset = 0; posAccessor.ComponentType = Accessor.ComponentTypeEnum.FLOAT; posAccessor.Count = animation.MeshKeys.Count; posAccessor.Max = new[] { max }; posAccessor.Min = new[] { min }; posAccessor.Name = "keysBufferViewAccessor"; posAccessor.Type = Accessor.TypeEnum.SCALAR; bufferViews.Add(posBufferView); accessors.Add(posAccessor); }