public static void AddAnimationSIMD(ref ModelRoot model, animAnimationBufferSimd blob, string animName, Stream defferedBuffer, animAnimation animAnimDes) { var rootPositions = new Dictionary <ushort, Dictionary <float, Vec3> >(); var rootRotations = new Dictionary <ushort, Dictionary <float, Quat> >(); var hasRootMotion = animAnimDes.MotionExtraction.Chunk is not null; if (hasRootMotion) { ROOT_MOTION.AddRootMotion(ref rootPositions, ref rootRotations, animAnimDes); } var br = new BinaryReader(defferedBuffer); var jointsCountAligned = (blob.NumJoints + 3U) & (~3U); // simd 4 alignment var totalFloatCount = (blob.NumFrames * jointsCountAligned * 3 + 3U) & (~3U); // simd 4 alignment var rotCompressedBuffSize = totalFloatCount * blob.QuantizationBits / 8U; rotCompressedBuffSize = (rotCompressedBuffSize + 15U) & (~15U); // 16byte padding aligment var mask = (1U << blob.QuantizationBits) - 1U; var floatsPacked = new ushort[totalFloatCount]; for (uint i = 0; i < totalFloatCount; i++) { var bitOff = i * blob.QuantizationBits; var byteOff = bitOff / 8; var shift = (bitOff % 8); defferedBuffer.Position = byteOff; var val = br.ReadUInt32(); val = val >> (int)shift; floatsPacked[i] = Convert.ToUInt16(val & mask); } var floatsDecompressed = new float[totalFloatCount]; for (uint i = 0; i < totalFloatCount; i++) { floatsDecompressed[i] = ((1f / mask) * floatsPacked[i] * 2) - 1f; } var Rotations = new Quat[blob.NumFrames, blob.NumJoints]; for (uint i = 0; i < blob.NumFrames; i++) { for (uint e = 0; e < blob.NumJoints; e += 4) { for (uint eye = 0; eye < 4; eye++) { var q = new Quat { X = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + eye], Y = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + 4 + eye], Z = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + 8 + eye] }; var dotPr = (q.X * q.X + q.Y * q.Y + q.Z * q.Z); q.X = q.X * Convert.ToSingle(Math.Sqrt(2f - dotPr)); q.Y = q.Y * Convert.ToSingle(Math.Sqrt(2f - dotPr)); q.Z = q.Z * Convert.ToSingle(Math.Sqrt(2f - dotPr)); q.W = 1f - dotPr; q = Quat.Normalize(q); if (e + eye < blob.NumJoints) { Rotations[i, e + eye] = new Quat(q.X, q.Z, -q.Y, q.W); } } } } var EvalAlignedPositions = new float[blob.NumFrames * blob.NumTranslationsToEvalAlignedToSimd * 3]; defferedBuffer.Position = rotCompressedBuffSize; for (uint i = 0; i < blob.NumFrames * blob.NumTranslationsToEvalAlignedToSimd * 3; i++) { EvalAlignedPositions[i] = br.ReadSingle(); } var Scales = new Vec3[blob.NumFrames, blob.NumJoints]; if (blob.IsScaleConstant) { var scalesRaw = new float[4]; for (uint i = 0; i < 4; i++) { scalesRaw[i] = br.ReadSingle(); } for (uint i = 0; i < blob.NumFrames; i++) { for (uint e = 0; e < blob.NumJoints; e++) { var v = new Vec3 { X = scalesRaw[0], Y = scalesRaw[1], Z = scalesRaw[2] }; Scales[i, e] = v; } } } else { var scalesRaw = new float[blob.NumFrames * jointsCountAligned * 3]; for (uint i = 0; i < blob.NumFrames * jointsCountAligned * 3; i++) { scalesRaw[i] = br.ReadSingle(); } for (uint i = 0; i < blob.NumFrames; i++) { for (uint e = 0; e < blob.NumJoints; e += 4) { for (uint eye = 0; eye < 4; eye++) { var v = new Vec3 { X = scalesRaw[i * jointsCountAligned * 3 + e * 3 + eye], Y = scalesRaw[i * jointsCountAligned * 3 + e * 3 + 4 + eye], Z = scalesRaw[i * jointsCountAligned * 3 + e * 3 + 8 + eye] }; Scales[i, e + eye] = v; } } } } if (blob.NumTracks > 0) { if (!blob.IsTrackConstant) { uint asas = ((blob.NumTracks + 3U) & (~3U)) * blob.NumFrames * 4; defferedBuffer.Seek(asas, SeekOrigin.Current); } else { defferedBuffer.Seek(4, SeekOrigin.Current); } } var positionToCopy = new Vec3[blob.NumTranslationsToCopy]; for (uint e = 0; e < blob.NumTranslationsToCopy; e++) { positionToCopy[e].X = br.ReadSingle(); positionToCopy[e].Y = br.ReadSingle(); positionToCopy[e].Z = br.ReadSingle(); } var evalIndices = new short[blob.NumTranslationsToEvalAlignedToSimd]; var copyIndices = new short[blob.NumTranslationsToCopy]; for (uint e = 0; e < blob.NumTranslationsToCopy; e++) { copyIndices[e] = br.ReadInt16(); } for (uint e = 0; e < blob.NumTranslationsToEvalAlignedToSimd; e++) { evalIndices[e] = br.ReadInt16(); } var Positions = new Vec3[blob.NumFrames, blob.NumJoints]; for (uint i = 0; i < blob.NumFrames; i++) { for (uint e = 0; e < blob.NumTranslationsToEvalAlignedToSimd; e += 4) { for (uint eye = 0; eye < 4; eye++) { var v = new Vec3 { X = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd * 3 + e * 3 + eye], Y = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd * 3 + e * 3 + 4 + eye], Z = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd * 3 + e * 3 + 8 + eye] }; if (evalIndices[e + eye] > -1) { Positions[i, evalIndices[e + eye]] = new Vec3(v.X, v.Z, -v.Y); } } } for (uint e = 0; e < copyIndices.Length; e++) { var v = new Vec3 { X = positionToCopy[e].X, Y = positionToCopy[e].Y, Z = positionToCopy[e].Z }; Positions[i, copyIndices[e]] = new Vec3(v.X, v.Z, -v.Y); } } var a = model.CreateAnimation(animName); for (var e = 0; e < blob.NumJoints - blob.NumExtraJoints; e++) { var pos = new Dictionary <float, Vec3>(); var rot = new Dictionary <float, Quat>(); var sca = new Dictionary <float, Vec3>(); var diff = blob.Duration / (blob.NumFrames - 1); for (var i = 0; i < blob.NumFrames; i++) { pos.Add(i * diff, Positions[i, e]); rot.Add(i * diff, Rotations[i, e]); sca.Add(i * diff, Scales[i, e]); } a.CreateRotationChannel(model.LogicalNodes[e], rot); a.CreateTranslationChannel(model.LogicalNodes[e], pos); a.CreateScaleChannel(model.LogicalNodes[e], sca); } }
public static void AddAnimationSIMD(ref ModelRoot model, animAnimationBufferSimd blob, string animName, Stream defferedBuffer, animAnimation animAnimDes) { Dictionary <UInt16, Dictionary <float, Vec3> > rootPositions = new Dictionary <ushort, Dictionary <float, Vec3> >(); Dictionary <UInt16, Dictionary <float, Quat> > rootRotations = new Dictionary <ushort, Dictionary <float, Quat> >(); bool hasRootMotion = animAnimDes.MotionExtraction.IsSerialized; if (hasRootMotion) { ROOT_MOTION.AddRootMotion(ref rootPositions, ref rootRotations, animAnimDes); } BinaryReader br = new BinaryReader(defferedBuffer); UInt32 jointsCountAligned = (blob.NumJoints.Value + 3U) & (~3U); // simd 4 alignment UInt32 totalFloatCount = (blob.NumFrames.Value * jointsCountAligned * 3 + 3U) & (~3U); // simd 4 alignment UInt32 rotCompressedBuffSize = totalFloatCount * blob.QuantizationBits.Value / 8U; rotCompressedBuffSize = (rotCompressedBuffSize + 15U) & (~15U); // 16byte padding aligment UInt32 mask = (1U << blob.QuantizationBits.Value) - 1U; UInt16[] floatsPacked = new UInt16[totalFloatCount]; for (UInt32 i = 0; i < totalFloatCount; i++) { UInt32 bitOff = i * blob.QuantizationBits.Value; UInt32 byteOff = bitOff / 8; UInt32 shift = (bitOff % 8); defferedBuffer.Position = byteOff; UInt32 val = br.ReadUInt32(); val = val >> (int)shift; floatsPacked[i] = Convert.ToUInt16(val & mask); } float[] floatsDecompressed = new float[totalFloatCount]; for (UInt32 i = 0; i < totalFloatCount; i++) { floatsDecompressed[i] = ((1f / mask) * floatsPacked[i] * 2) - 1f; } Quat[,] Rotations = new Quat[blob.NumFrames.Value, blob.NumJoints.Value]; for (UInt32 i = 0; i < blob.NumFrames.Value; i++) { for (UInt32 e = 0; e < blob.NumJoints.Value; e += 4) { for (UInt32 eye = 0; eye < 4; eye++) { Quat q = new Quat(); q.X = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + eye]; q.Y = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + 4 + eye]; q.Z = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + 8 + eye]; float dotPr = (q.X * q.X + q.Y * q.Y + q.Z * q.Z); q.X = q.X * Convert.ToSingle(Math.Sqrt(2f - dotPr)); q.Y = q.Y * Convert.ToSingle(Math.Sqrt(2f - dotPr)); q.Z = q.Z * Convert.ToSingle(Math.Sqrt(2f - dotPr)); q.W = 1f - dotPr; q = Quat.Normalize(q); if (e + eye < blob.NumJoints.Value) { Rotations[i, e + eye] = new Quat(q.X, q.Z, -q.Y, q.W); } } } } float[] EvalAlignedPositions = new float[blob.NumFrames.Value * blob.NumTranslationsToEvalAlignedToSimd.Value * 3]; defferedBuffer.Position = rotCompressedBuffSize; for (UInt32 i = 0; i < blob.NumFrames.Value * blob.NumTranslationsToEvalAlignedToSimd.Value * 3; i++) { EvalAlignedPositions[i] = br.ReadSingle(); } Vec3[,] Scales = new Vec3[blob.NumFrames.Value, blob.NumJoints.Value]; if (blob.IsScaleConstant.Value) { float[] scalesRaw = new float[4]; for (UInt32 i = 0; i < 4; i++) { scalesRaw[i] = br.ReadSingle(); } for (UInt32 i = 0; i < blob.NumFrames.Value; i++) { for (UInt32 e = 0; e < blob.NumJoints.Value; e++) { Vec3 v = new Vec3(); v.X = scalesRaw[0]; v.Y = scalesRaw[1]; v.Z = scalesRaw[2]; Scales[i, e] = v; } } } else { float[] scalesRaw = new float[blob.NumFrames.Value * jointsCountAligned * 3]; for (UInt32 i = 0; i < blob.NumFrames.Value * jointsCountAligned * 3; i++) { scalesRaw[i] = br.ReadSingle(); } for (UInt32 i = 0; i < blob.NumFrames.Value; i++) { for (UInt32 e = 0; e < blob.NumJoints.Value; e += 4) { for (UInt32 eye = 0; eye < 4; eye++) { Vec3 v = new Vec3(); v.X = scalesRaw[i * jointsCountAligned * 3 + e * 3 + eye]; v.Y = scalesRaw[i * jointsCountAligned * 3 + e * 3 + 4 + eye]; v.Z = scalesRaw[i * jointsCountAligned * 3 + e * 3 + 8 + eye]; Scales[i, e + eye] = v; } } } } if (blob.NumTracks.Value > 0) { if (!blob.IsTrackConstant.Value) { UInt32 asas = ((blob.NumTracks.Value + 3U) & (~3U)) * blob.NumFrames.Value * 4; defferedBuffer.Seek(asas, SeekOrigin.Current); } else { defferedBuffer.Seek(4, SeekOrigin.Current); } } Vec3[] positionToCopy = new Vec3[blob.NumTranslationsToCopy.Value]; for (UInt32 e = 0; e < blob.NumTranslationsToCopy.Value; e++) { positionToCopy[e].X = br.ReadSingle(); positionToCopy[e].Y = br.ReadSingle(); positionToCopy[e].Z = br.ReadSingle(); } Int16[] evalIndices = new Int16[blob.NumTranslationsToEvalAlignedToSimd.Value]; Int16[] copyIndices = new Int16[blob.NumTranslationsToCopy.Value]; for (UInt32 e = 0; e < blob.NumTranslationsToCopy.Value; e++) { copyIndices[e] = br.ReadInt16(); } for (UInt32 e = 0; e < blob.NumTranslationsToEvalAlignedToSimd.Value; e++) { evalIndices[e] = br.ReadInt16(); } Vec3[,] Positions = new Vec3[blob.NumFrames.Value, blob.NumJoints.Value]; for (UInt32 i = 0; i < blob.NumFrames.Value; i++) { for (UInt32 e = 0; e < blob.NumTranslationsToEvalAlignedToSimd.Value; e += 4) { for (UInt32 eye = 0; eye < 4; eye++) { Vec3 v = new Vec3(); v.X = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd.Value * 3 + e * 3 + eye]; v.Y = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd.Value * 3 + e * 3 + 4 + eye]; v.Z = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd.Value * 3 + e * 3 + 8 + eye]; if (evalIndices[e + eye] > -1) { Positions[i, evalIndices[e + eye]] = new Vec3(v.X, v.Z, -v.Y); } } } for (UInt32 e = 0; e < copyIndices.Length; e++) { Vec3 v = new Vec3(); v.X = positionToCopy[e].X; v.Y = positionToCopy[e].Y; v.Z = positionToCopy[e].Z; Positions[i, copyIndices[e]] = new Vec3(v.X, v.Z, -v.Y); } } var a = model.CreateAnimation(animName); for (int e = 0; e < blob.NumJoints.Value - blob.NumExtraJoints.Value; e++) { var pos = new Dictionary <float, Vec3>(); var rot = new Dictionary <float, Quat>(); var sca = new Dictionary <float, Vec3>(); float diff = blob.Duration.Value / (blob.NumFrames.Value - 1); for (int i = 0; i < blob.NumFrames.Value; i++) { pos.Add(i * diff, Positions[i, e]); rot.Add(i * diff, Rotations[i, e]); sca.Add(i * diff, Scales[i, e]); } a.CreateRotationChannel(model.LogicalNodes[e], rot); a.CreateTranslationChannel(model.LogicalNodes[e], pos); a.CreateScaleChannel(model.LogicalNodes[e], sca); } }
public static void AddAnimationSpline(ref ModelRoot model, animAnimationBufferCompressed blob, string animName, Stream defferedBuffer, animAnimation animAnimDes) { //boneidx time value var positions = new Dictionary <ushort, Dictionary <float, Vec3> >(); var rotations = new Dictionary <ushort, Dictionary <float, Quat> >(); var scales = new Dictionary <ushort, Dictionary <float, Vec3> >(); var tracks = new Dictionary <ushort, float>(); if (animAnimDes.MotionExtraction.Chunk != null) { ROOT_MOTION.AddRootMotion(ref positions, ref rotations, animAnimDes); } var br = new BinaryReader(defferedBuffer); float duration = blob.Duration; uint numFrames = blob.NumFrames; uint numJoints = blob.NumJoints; uint numTracks = blob.NumTracks; uint numExtraJoints = blob.NumExtraJoints; uint numAnimKeys = blob.NumAnimKeys; uint numAnimKeysRaw = blob.NumAnimKeysRaw; uint NumConstAnimKeys = blob.NumConstAnimKeys; uint numConstTrackKeys = blob.NumConstTrackKeys; defferedBuffer.Seek(0, SeekOrigin.Begin); for (uint i = 0; i < numAnimKeys; i++) { var timeNormalized = br.ReadUInt16() / (float)ushort.MaxValue; var bitWiseData = br.ReadUInt16(); var wSign = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift); var component = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift); var boneIdx = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift); var x = ((1f / 65535f) * br.ReadUInt16() * 2) - 1f; var y = ((1f / 65535f) * br.ReadUInt16() * 2) - 1f; var z = ((1f / 65535f) * br.ReadUInt16() * 2) - 1f; switch (component) { case 0: if (positions.ContainsKey(boneIdx)) { positions[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3> { { timeNormalized *duration, new Vec3(x, z, -y) } }; positions.Add(boneIdx, dic); } break; case 1: var dotPr = (x * x + y * y + z * z); x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr)); y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr)); z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr)); var w = 1f - dotPr; if (wSign == 1) { w = -w; } var q = new Quat(x, z, -y, w); if (rotations.ContainsKey(boneIdx)) { rotations[boneIdx].Add(timeNormalized * duration, Quat.Normalize(q)); } else { var dic = new Dictionary <float, Quat> { { timeNormalized *duration, Quat.Normalize(q) } }; rotations.Add(boneIdx, dic); } break; case 2: if (scales.ContainsKey(boneIdx)) { scales[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3> { { timeNormalized *duration, new Vec3(x, z, -y) } }; scales.Add(boneIdx, dic); } break; default: break; } } for (uint i = 0; i < numAnimKeysRaw; i++) { var timeNormalized = br.ReadUInt16() / (float)ushort.MaxValue; var bitWiseData = br.ReadUInt16(); var wSign = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift); var component = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift); var boneIdx = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift); var x = br.ReadSingle(); var y = br.ReadSingle(); var z = br.ReadSingle(); switch (component) { case 0: if (positions.ContainsKey(boneIdx)) { positions[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3> { { timeNormalized *duration, new Vec3(x, z, -y) } }; positions.Add(boneIdx, dic); } break; case 1: var dotPr = (x * x + y * y + z * z); x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr)); y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr)); z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr)); var w = 1f - dotPr; if (wSign == 1) { w = -w; } var q = new Quat(x, z, -y, w); if (rotations.ContainsKey(boneIdx)) { rotations[boneIdx].Add(timeNormalized * duration, Quat.Normalize(q)); } else { var dic = new Dictionary <float, Quat> { { timeNormalized *duration, Quat.Normalize(q) } }; rotations.Add(boneIdx, dic); } break; case 2: if (scales.ContainsKey(boneIdx)) { scales[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3> { { timeNormalized *duration, new Vec3(x, z, -y) } }; scales.Add(boneIdx, dic); } break; default: break; } } for (uint i = 0; i < NumConstAnimKeys; i++) { var bitWiseData = br.ReadUInt16(); var timeNormalized = br.ReadUInt16() / (float)ushort.MaxValue; // is it some time normalized or some padding garbage data i have no idea var wSign = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift); var component = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift); var boneIdx = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift); var x = br.ReadSingle(); var y = br.ReadSingle(); var z = br.ReadSingle(); switch (component) { case 0: if (positions.ContainsKey(boneIdx)) { positions[boneIdx].Add(0f, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3> { { 0f, new Vec3(x, z, -y) } }; positions.Add(boneIdx, dic); } break; case 1: var dotPr = (x * x + y * y + z * z); x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr)); y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr)); z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr)); var w = 1f - dotPr; if (wSign == 1) { w = -w; } var q = new Quat(x, z, -y, w); if (rotations.ContainsKey(boneIdx)) { rotations[boneIdx].Add(0f, Quat.Normalize(q)); } else { var dic = new Dictionary <float, Quat> { { 0f, Quat.Normalize(q) } }; rotations.Add(boneIdx, dic); } break; case 2: if (scales.ContainsKey(boneIdx)) { scales[boneIdx].Add(0f, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3> { { 0f, new Vec3(x, z, -y) } }; scales.Add(boneIdx, dic); } break; default: break; } } /* * for (UInt32 i = 0; i < numConstTrackKeys; i++) * { * UInt16 idx = br.ReadUInt16(); * br.ReadUInt16(); //is it time or some garbage idk * float value = br.ReadSingle(); * } */ var anim = model.CreateAnimation(animName); for (ushort i = 0; i < numJoints - numExtraJoints; i++) { if (positions.ContainsKey(i)) { anim.CreateTranslationChannel(model.LogicalNodes[i], positions[i]); } if (rotations.ContainsKey(i)) { anim.CreateRotationChannel(model.LogicalNodes[i], rotations[i]); } if (scales.ContainsKey(i)) { anim.CreateScaleChannel(model.LogicalNodes[i], scales[i]); } } }
public static void AddAnimationSpline(ref ModelRoot model, animAnimationBufferCompressed blob, string animName, Stream defferedBuffer) { //boneidx time value Dictionary <UInt16, Dictionary <float, Vec3> > positions = new Dictionary <ushort, Dictionary <float, Vec3> >(); Dictionary <UInt16, Dictionary <float, Quat> > rotations = new Dictionary <ushort, Dictionary <float, Quat> >(); Dictionary <UInt16, Dictionary <float, Vec3> > scales = new Dictionary <ushort, Dictionary <float, Vec3> >(); Dictionary <UInt16, float> tracks = new Dictionary <UInt16, float>(); BinaryReader br = new BinaryReader(defferedBuffer); float duration = blob.Duration.Value; UInt32 numFrames = blob.NumFrames.Value; UInt32 numJoints = blob.NumJoints.Value; UInt32 numTracks = blob.NumTracks.Value; UInt32 numExtraJoints = blob.NumExtraJoints.Value; UInt32 numAnimKeys = blob.NumAnimKeys.Value; UInt32 numAnimKeysRaw = blob.NumAnimKeysRaw.Value; UInt32 NumConstAnimKeys = blob.NumConstAnimKeys.Value; UInt32 numConstTrackKeys = blob.NumConstTrackKeys.Value; defferedBuffer.Seek(0, SeekOrigin.Begin); for (UInt32 i = 0; i < numAnimKeys; i++) { float timeNormalized = br.ReadUInt16() / (float)UInt16.MaxValue; UInt16 bitWiseData = br.ReadUInt16(); UInt16 wSign = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift); UInt16 component = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift); UInt16 boneIdx = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift); float x = ((1f / 65535f) * br.ReadUInt16() * 2) - 1f; float y = ((1f / 65535f) * br.ReadUInt16() * 2) - 1f; float z = ((1f / 65535f) * br.ReadUInt16() * 2) - 1f; switch (component) { case 0: if (positions.ContainsKey(boneIdx)) { positions[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3>(); dic.Add(timeNormalized * duration, new Vec3(x, z, -y)); positions.Add(boneIdx, dic); } break; case 1: float dotPr = (x * x + y * y + z * z); x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr)); y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr)); z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr)); float w = 1f - dotPr; if (wSign == 1) { w = -w; } Quat q = new Quat(x, z, -y, w); if (rotations.ContainsKey(boneIdx)) { rotations[boneIdx].Add(timeNormalized * duration, Quat.Normalize(q)); } else { var dic = new Dictionary <float, Quat>(); dic.Add(timeNormalized * duration, Quat.Normalize(q)); rotations.Add(boneIdx, dic); } break; case 2: if (scales.ContainsKey(boneIdx)) { scales[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3>(); dic.Add(timeNormalized * duration, new Vec3(x, z, -y)); scales.Add(boneIdx, dic); } break; default: break; } } for (UInt32 i = 0; i < numAnimKeysRaw; i++) { float timeNormalized = br.ReadUInt16() / (float)UInt16.MaxValue; UInt16 bitWiseData = br.ReadUInt16(); UInt16 wSign = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift); UInt16 component = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift); UInt16 boneIdx = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift); float x = br.ReadSingle(); float y = br.ReadSingle(); float z = br.ReadSingle(); switch (component) { case 0: if (positions.ContainsKey(boneIdx)) { positions[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3>(); dic.Add(timeNormalized * duration, new Vec3(x, z, -y)); positions.Add(boneIdx, dic); } break; case 1: float dotPr = (x * x + y * y + z * z); x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr)); y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr)); z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr)); float w = 1f - dotPr; if (wSign == 1) { w = -w; } Quat q = new Quat(x, z, -y, w); if (rotations.ContainsKey(boneIdx)) { rotations[boneIdx].Add(timeNormalized * duration, Quat.Normalize(q)); } else { var dic = new Dictionary <float, Quat>(); dic.Add(timeNormalized * duration, Quat.Normalize(q)); rotations.Add(boneIdx, dic); } break; case 2: if (scales.ContainsKey(boneIdx)) { scales[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3>(); dic.Add(timeNormalized * duration, new Vec3(x, z, -y)); scales.Add(boneIdx, dic); } break; default: break; } } for (UInt32 i = 0; i < NumConstAnimKeys; i++) { UInt16 bitWiseData = br.ReadUInt16(); float timeNormalized = br.ReadUInt16() / (float)UInt16.MaxValue; // is it some time normalized or some padding garbage data i have no idea UInt16 wSign = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift); UInt16 component = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift); UInt16 boneIdx = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift); float x = br.ReadSingle(); float y = br.ReadSingle(); float z = br.ReadSingle(); switch (component) { case 0: if (positions.ContainsKey(boneIdx)) { positions[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3>(); dic.Add(timeNormalized * duration, new Vec3(x, z, -y)); positions.Add(boneIdx, dic); } break; case 1: float dotPr = (x * x + y * y + z * z); x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr)); y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr)); z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr)); float w = 1f - dotPr; if (wSign == 1) { w = -w; } Quat q = new Quat(x, z, -y, w); if (rotations.ContainsKey(boneIdx)) { rotations[boneIdx].Add(timeNormalized * duration, Quat.Normalize(q)); } else { var dic = new Dictionary <float, Quat>(); dic.Add(timeNormalized * duration, Quat.Normalize(q)); rotations.Add(boneIdx, dic); } break; case 2: if (scales.ContainsKey(boneIdx)) { scales[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y)); } else { var dic = new Dictionary <float, Vec3>(); dic.Add(timeNormalized * duration, new Vec3(x, z, -y)); scales.Add(boneIdx, dic); } break; default: break; } } /* * for (UInt32 i = 0; i < NumConstAnimKeys; i++) * { * UInt16 bitWiseData = br.ReadUInt16(); * br.ReadUInt16(); // is it some time normalized or some padding garbage data i have no idea * UInt16 wSign = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift); * UInt16 component = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift); * UInt16 boneIdx = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift); * float x = br.ReadSingle(); * float y = br.ReadSingle(); * float z = br.ReadSingle(); * * for(UInt32 e = 0; e < numFrames; e++) * { * float diff = duration / (numFrames - 1); * switch (component) * { * case 0: * if (positions.ContainsKey(boneIdx)) * { * if (!positions[boneIdx].ContainsKey(e * diff)) * { * positions[boneIdx].Add(e * diff, new Vec3(x, z, -y)); * } * } * else * { * var dic = new Dictionary<float, Vec3>(); * dic.Add(e * diff, new Vec3(x, z, -y)); * positions.Add(boneIdx, dic); * } * break; * case 1: * float dotPr = (x * x + y * y + z * z); * x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr)); * y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr)); * z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr)); * float w = 1f - dotPr; * if (wSign == 1) * w = -w; * Quat q = new Quat(x, z, -y, w); * if (rotations.ContainsKey(boneIdx)) * { * if (!rotations[boneIdx].ContainsKey(e * diff)) * { * rotations[boneIdx].Add(e * diff, Quat.Normalize(q)); * } * } * else * { * var dic = new Dictionary<float, Quat>(); * dic.Add(e * diff, Quat.Normalize(q)); * rotations.Add(boneIdx, dic); * } * break; * case 2: * if (scales.ContainsKey(boneIdx)) * { * if (!scales[boneIdx].ContainsKey(e * diff)) * { * scales[boneIdx].Add(e * diff, new Vec3(x, z, -y)); * } * } * else * { * var dic = new Dictionary<float, Vec3>(); * dic.Add(e * diff, new Vec3(x, z, -y)); * scales.Add(boneIdx, dic); * } * break; * default: * break; * } * } * } */ /* * for (UInt32 i = 0; i < numConstTrackKeys; i++) * { * UInt16 idx = br.ReadUInt16(); * br.ReadUInt16(); //is it time or some garbage idk * float value = br.ReadSingle(); * } */ var anim = model.CreateAnimation(animName); for (ushort i = 0; i < numJoints - numExtraJoints; i++) { if (positions.ContainsKey(i)) { anim.CreateTranslationChannel(model.LogicalNodes[i], positions[i]); } if (rotations.ContainsKey(i)) { anim.CreateRotationChannel(model.LogicalNodes[i], rotations[i]); } if (scales.ContainsKey(i)) { anim.CreateScaleChannel(model.LogicalNodes[i], scales[i]); } } }