public static void AddRootMotion(ref Dictionary <UInt16, Dictionary <float, Vec3> > positions, ref Dictionary <UInt16, Dictionary <float, Quat> > rotations, animAnimation animAnimDes) { var motionEx = animAnimDes.MotionExtraction.GetReference().Data as animIMotionExtraction; var duration = animAnimDes.Duration.Value; var numFrames = 0; var numPositions = 0; var numRotations = 0; var posTime = new float[0]; var rotTime = new float[0]; var rotBuffer = new byte[0]; var posBuffer = new byte[0]; var fps = 0f; var ft = 0f; BinaryReader br; MemoryStream ms; switch (motionEx.REDType) { case "animLinearCompressedMotionExtraction": { var lc = motionEx as animLinearCompressedMotionExtraction; numPositions = lc.PosFrames.IsSerialized ? lc.PosFrames.Elements.Count : 0; numRotations = lc.RotFrames.IsSerialized ? lc.RotFrames.Elements.Count : 0; posTime = lc.PosTime.IsSerialized ? lc.PosTime.Elements.Select(_ => _.Value).ToArray() : new float[numPositions]; rotTime = lc.RotTime.IsSerialized ? lc.RotTime.Elements.Select(_ => _.Value).ToArray() : new float[numRotations]; if (numPositions > 0) { if (!positions.ContainsKey(0)) { positions.Add(0, new Dictionary <float, Vec3>()); } } if (numRotations > 0) { if (!rotations.ContainsKey(0)) { rotations.Add(0, new Dictionary <float, Quat>()); } } for (int i = 0; i < numPositions; i++) { var v = lc.PosFrames[i]; positions[0].Add(posTime[i], new Vec3(v.X.Value, v.Z.Value, -v.Y.Value)); } for (int i = 0; i < numRotations; i++) { var q = lc.RotFrames[i]; rotations[0].Add(rotTime[i], new Quat(q.I.Value, q.K.Value, -q.J.Value, q.R.Value)); } break; } case "animPlaneUncompressedMotionExtraction": { var pc = motionEx as animPlaneUncompressedMotionExtraction; duration = pc.Duration.IsSerialized ? pc.Duration.Value : duration; numPositions = pc.Frames.IsSerialized ? pc.Frames.Elements.Count : 0; numFrames = numPositions; fps = (numFrames - 1f) / duration; ft = 1f / fps; if (numPositions > 0) { if (!positions.ContainsKey(0)) { positions.Add(0, new Dictionary <float, Vec3>()); } } for (int i = 0; i < numFrames; i++) { var v = pc.Frames.Elements[i]; positions[0].Add(ft * i, new Vec3(v.X.Value, v.Z.Value, -v.Y.Value)); } break; } case "animSplineCompressedMotionExtraction": { var sc = motionEx as animSplineCompressedMotionExtraction; duration = sc.Duration.IsSerialized ? sc.Duration.Value : duration; #region rotations if (sc.RotKeysData.IsSerialized) { rotBuffer = sc.RotKeysData.Elements.Select(_ => _.Value).ToArray(); numRotations = rotBuffer.Length / 16; if (numRotations > 0) { if (!rotations.ContainsKey(0)) { rotations.Add(0, new Dictionary <float, Quat>()); } } using (ms = new MemoryStream(rotBuffer)) using (br = new BinaryReader(ms)) { br.BaseStream.Seek(0, SeekOrigin.Begin); for (int i = 0; i < numRotations; 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; default: break; } } } } #endregion if (sc.PosKeysData.IsSerialized) { posBuffer = sc.PosKeysData.Elements.Select(_ => _.Value).ToArray(); numPositions = posBuffer.Length / 16; if (numPositions > 0) { if (!positions.ContainsKey(0)) { positions.Add(0, new Dictionary <float, Vec3>()); } } using (ms = new MemoryStream(posBuffer)) using (br = new BinaryReader(ms)) { br.BaseStream.Seek(0, SeekOrigin.Begin); for (int i = 0; i < numPositions; 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; default: break; } } } } break; } case "animUncompressedAllAnglesMotionExtraction": { var aa = motionEx as animUncompressedAllAnglesMotionExtraction; duration = aa.Duration.IsSerialized ? aa.Duration.Value : duration; numFrames = aa.Frames.IsSerialized ? aa.Frames.Elements.Count : 0; fps = (numFrames - 1f) / duration; ft = 1f / fps; if (numFrames > 0) { if (!positions.ContainsKey(0)) { positions.Add(0, new Dictionary <float, Vec3>()); } if (!rotations.ContainsKey(0)) { rotations.Add(0, new Dictionary <float, Quat>()); } } for (int i = 0; i < numFrames; i++) { var v = aa.Frames.Elements[i].Position; var q = aa.Frames.Elements[i].Orientation; positions[0].Add(ft * i, new Vec3(v.X.Value, v.Z.Value, -v.Y.Value)); rotations[0].Add(ft * i, new Quat(q.I.Value, q.K.Value, -q.J.Value, q.R.Value)); } break; } case "animUncompressedMotionExtraction": { var uc = motionEx as animUncompressedMotionExtraction; duration = uc.Duration.IsSerialized ? uc.Duration.Value : duration; numFrames = uc.Frames.IsSerialized ? uc.Frames.Elements.Count : 0; numPositions = numFrames; fps = (numFrames - 1f) / duration; ft = 1f / fps; if (numPositions > 0) { if (!positions.ContainsKey(0)) { positions.Add(0, new Dictionary <float, Vec3>()); } } for (int i = 0; i < numFrames; i++) { var v = uc.Frames.Elements[i]; if (v.W.Value != 0f || v.W.Value != 1f) { throw new Exception("vec4 W unexpected value ???"); } positions[0].Add(ft * i, new Vec3(v.X.Value, v.Z.Value, -v.Y.Value)); } break; } default: break; } }
public static void AddRootMotion(ref Dictionary <ushort, Dictionary <float, Vec3> > positions, ref Dictionary <ushort, Dictionary <float, Quat> > rotations, animAnimation animAnimDes) { var motionEx = animAnimDes.MotionExtraction.Chunk; var duration = animAnimDes.Duration; var numFrames = 0; var numPositions = 0; var numRotations = 0; var posTime = new float[0]; var rotTime = new float[0]; var rotBuffer = new byte[0]; var posBuffer = new byte[0]; var fps = 0f; var ft = 0f; BinaryReader br; MemoryStream ms; if (motionEx is animLinearCompressedMotionExtraction) { var lc = motionEx as animLinearCompressedMotionExtraction; numPositions = lc.PosFrames.Count; numRotations = lc.RotFrames.Count; posTime = lc.PosTime.Cast <float>().ToArray(); rotTime = lc.RotTime.Cast <float>().ToArray(); if (numPositions > 0) { if (!positions.ContainsKey(0)) { positions.Add(0, new Dictionary <float, Vec3>()); } } if (numRotations > 0) { if (!rotations.ContainsKey(0)) { rotations.Add(0, new Dictionary <float, Quat>()); } } for (var i = 0; i < numPositions; i++) { var v = lc.PosFrames[i]; positions[0].Add(posTime[i], new Vec3(v.X, v.Z, -v.Y)); } for (var i = 0; i < numRotations; i++) { var q = lc.RotFrames[i]; rotations[0].Add(rotTime[i], new Quat(q.I, q.K, -q.J, q.R)); } } else if (motionEx is animPlaneUncompressedMotionExtraction) { var pc = motionEx as animPlaneUncompressedMotionExtraction; duration = pc.Duration; numPositions = pc.Frames.Count; numFrames = numPositions; fps = (numFrames - 1f) / duration; ft = 1f / fps; if (numPositions > 0) { if (!positions.ContainsKey(0)) { positions.Add(0, new Dictionary <float, Vec3>()); } } for (var i = 0; i < numFrames; i++) { var v = pc.Frames[i]; positions[0].Add(ft * i, new Vec3(v.X, v.Z, -v.Y)); } } else if (motionEx is animSplineCompressedMotionExtraction) { var sc = motionEx as animSplineCompressedMotionExtraction; duration = sc.Duration; #region rotations if (sc.RotKeysData != null) { rotBuffer = sc.RotKeysData.Cast <byte>().ToArray(); numRotations = rotBuffer.Length / 16; if (numRotations > 0) { if (!rotations.ContainsKey(0)) { rotations.Add(0, new Dictionary <float, Quat>()); } } using (ms = new MemoryStream(rotBuffer)) using (br = new BinaryReader(ms)) { br.BaseStream.Seek(0, SeekOrigin.Begin); for (var i = 0; i < numRotations; 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; default: break; } } } } #endregion if (sc.PosKeysData != null) { posBuffer = sc.PosKeysData.Cast <byte>().ToArray(); numPositions = posBuffer.Length / 16; if (numPositions > 0) { if (!positions.ContainsKey(0)) { positions.Add(0, new Dictionary <float, Vec3>()); } } using (ms = new MemoryStream(posBuffer)) using (br = new BinaryReader(ms)) { br.BaseStream.Seek(0, SeekOrigin.Begin); for (var i = 0; i < numPositions; 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; default: break; } } } } } else if (motionEx is animUncompressedAllAnglesMotionExtraction) { var aa = motionEx as animUncompressedAllAnglesMotionExtraction; duration = aa.Duration; numFrames = aa.Frames.Count; fps = (numFrames - 1f) / duration; ft = 1f / fps; if (numFrames > 0) { if (!positions.ContainsKey(0)) { positions.Add(0, new Dictionary <float, Vec3>()); } if (!rotations.ContainsKey(0)) { rotations.Add(0, new Dictionary <float, Quat>()); } } for (var i = 0; i < numFrames; i++) { var v = aa.Frames[i].Position; var q = aa.Frames[i].Orientation; positions[0].Add(ft * i, new Vec3(v.X, v.Z, -v.Y)); rotations[0].Add(ft * i, new Quat(q.I, q.K, -q.J, q.R)); } } else if (motionEx is animUncompressedMotionExtraction) { var uc = motionEx as animUncompressedMotionExtraction; duration = uc.Duration; numFrames = uc.Frames.Count; numPositions = numFrames; fps = (numFrames - 1f) / duration; ft = 1f / fps; if (numPositions > 0) { if (!positions.ContainsKey(0)) { positions.Add(0, new Dictionary <float, Vec3>()); } } for (var i = 0; i < numFrames; i++) { var v = uc.Frames[i]; if (v.W != 0f || v.W != 1f) { throw new Exception("vec4 W unexpected value ???"); } positions[0].Add(ft * i, new Vec3(v.X, v.Z, -v.Y)); } } }
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 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); } }