public BinBVHAnimation(byte[] animationdata) { int i = 0; if (!BitConverter.IsLittleEndian) { unknown0 = Utils.BytesToUInt16(BinBVHUtil.EndianSwap(animationdata, i, 2)); i += 2; // Always 1 unknown1 = Utils.BytesToUInt16(BinBVHUtil.EndianSwap(animationdata, i, 2)); i += 2; // Always 0 Priority = Utils.BytesToInt(BinBVHUtil.EndianSwap(animationdata, i, 4)); i += 4; Length = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4; } else { unknown0 = Utils.BytesToUInt16(animationdata, i); i += 2; // Always 1 unknown1 = Utils.BytesToUInt16(animationdata, i); i += 2; // Always 0 Priority = Utils.BytesToInt(animationdata, i); i += 4; Length = Utils.BytesToFloat(animationdata, i); i += 4; } ExpressionName = ReadBytesUntilNull(animationdata, ref i); if (!BitConverter.IsLittleEndian) { InPoint = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4; OutPoint = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4; Loop = (Utils.BytesToInt(BinBVHUtil.EndianSwap(animationdata, i, 4)) != 0); i += 4; EaseInTime = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4; EaseOutTime = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4; HandPose = Utils.BytesToUInt(BinBVHUtil.EndianSwap(animationdata, i, 4)); i += 4; // Handpose? m_jointCount = Utils.BytesToUInt(animationdata, i); i += 4; // Get Joint count } else { InPoint = Utils.BytesToFloat(animationdata, i); i += 4; OutPoint = Utils.BytesToFloat(animationdata, i); i += 4; Loop = (Utils.BytesToInt(animationdata, i) != 0); i += 4; EaseInTime = Utils.BytesToFloat(animationdata, i); i += 4; EaseOutTime = Utils.BytesToFloat(animationdata, i); i += 4; HandPose = Utils.BytesToUInt(animationdata, i); i += 4; // Handpose? m_jointCount = Utils.BytesToUInt(animationdata, i); i += 4; // Get Joint count } Joints = new binBVHJoint[m_jointCount]; // deserialize the number of joints in the animation. // Joints are variable length blocks of binary data consisting of joint data and keyframes for (int iter = 0; iter < m_jointCount; iter++) { binBVHJoint joint = readJoint(animationdata, ref i); Joints[iter] = joint; } }
/// <summary> /// Read Keyframes of a certain type /// advance i /// </summary> /// <param name="data">Animation Byte array</param> /// <param name="i">Offset in the Byte Array. Will be advanced</param> /// <param name="keycount">Number of Keyframes</param> /// <param name="min">Scaling Min to pass to the Uint16ToFloat method</param> /// <param name="max">Scaling Max to pass to the Uint16ToFloat method</param> /// <returns></returns> private binBVHJointKey[] readKeys(byte[] data, ref int i, int keycount, float min, float max) { float x; float y; float z; /* * 0.o, Float values in Two bytes.. this is just wrong >:( * 17 255 <-- Time Code * 17 255 <-- Time Code * 255 255 <-- X * 127 127 <-- X * 255 255 <-- Y * 127 127 <-- Y * 213 213 <-- Z * 142 142 <---Z * */ binBVHJointKey[] m_keys = new binBVHJointKey[keycount]; for (int j = 0; j < keycount; j++) { binBVHJointKey pJKey = new binBVHJointKey(); if (!BitConverter.IsLittleEndian) { pJKey.time = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, InPoint, OutPoint); i += 2; x = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, min, max); i += 2; y = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, min, max); i += 2; z = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, min, max); i += 2; } else { pJKey.time = Utils.UInt16ToFloat(data, i, InPoint, OutPoint); i += 2; x = Utils.UInt16ToFloat(data, i, min, max); i += 2; y = Utils.UInt16ToFloat(data, i, min, max); i += 2; z = Utils.UInt16ToFloat(data, i, min, max); i += 2; } pJKey.key_element = new Vector3(x, y, z); m_keys[j] = pJKey; } return(m_keys); }
/// <summary> /// Read in a Joint from an animation asset byte array /// Variable length Joint fields, yay! /// Advances the index /// </summary> /// <param name="data">animation asset byte array</param> /// <param name="i">Byte Offset of the start of the joint</param> /// <returns>The Joint data serialized into the binBVHJoint structure</returns> private binBVHJoint readJoint(byte[] data, ref int i) { binBVHJointKey[] positions; binBVHJointKey[] rotations; binBVHJoint pJoint = new binBVHJoint(); /* * 109 * 84 * 111 * 114 * 114 * 111 * 0 <--- Null terminator */ pJoint.Name = ReadBytesUntilNull(data, ref i); // Joint name /* * 2 <- Priority Revisited * 0 * 0 * 0 */ /* * 5 <-- 5 keyframes * 0 * 0 * 0 * ... 5 Keyframe data blocks */ /* * 2 <-- 2 keyframes * 0 * 0 * 0 * .. 2 Keyframe data blocks */ if (!BitConverter.IsLittleEndian) { pJoint.Priority = Utils.BytesToInt(BinBVHUtil.EndianSwap(data, i, 4)); i += 4; // Joint Priority override? rotationkeys = Utils.BytesToInt(BinBVHUtil.EndianSwap(data, i, 4)); i += 4; // How many rotation keyframes } else { pJoint.Priority = Utils.BytesToInt(data, i); i += 4; // Joint Priority override? rotationkeys = Utils.BytesToInt(data, i); i += 4; // How many rotation keyframes } // argh! floats into two bytes!.. bad bad bad bad // After fighting with it for a while.. -1, to 1 seems to give the best results rotations = readKeys(data, ref i, rotationkeys, -1f, 1f); if (!BitConverter.IsLittleEndian) { positionkeys = Utils.BytesToInt(BinBVHUtil.EndianSwap(data, i, 4)); i += 4; // How many position keyframes } else { positionkeys = Utils.BytesToInt(data, i); i += 4; // How many position keyframes } // Read in position keyframes // argh! more floats into two bytes!.. *head desk* // After fighting with it for a while.. -5, to 5 seems to give the best results positions = readKeys(data, ref i, positionkeys, -5f, 5f); pJoint.rotationkeys = rotations; pJoint.positionkeys = positions; return(pJoint); }