/// <summary> /// Searialize an animation asset into it's joints/keyframes/meta data /// </summary> /// <param name="animationdata"></param> public BinBVHAnimationReader(byte[] animationdata) { int i = 0; if (!BitConverter.IsLittleEndian) { unknown0 = Utils.BytesToUInt16(EndianSwap(animationdata, i, 2)); i += 2; // Always 1 unknown1 = Utils.BytesToUInt16(EndianSwap(animationdata, i, 2)); i += 2; // Always 0 Priority = Utils.BytesToInt(EndianSwap(animationdata, i, 4)); i += 4; Length = Utils.BytesToFloat(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(EndianSwap(animationdata, i, 4), 0); i += 4; OutPoint = Utils.BytesToFloat(EndianSwap(animationdata, i, 4), 0); i += 4; Loop = (Utils.BytesToInt(EndianSwap(animationdata, i, 4)) != 0); i += 4; EaseInTime = Utils.BytesToFloat(EndianSwap(animationdata, i, 4), 0); i += 4; EaseOutTime = Utils.BytesToFloat(EndianSwap(animationdata, i, 4), 0); i += 4; HandPose = Utils.BytesToUInt(EndianSwap(animationdata, i, 4)); i += 4; // Handpose? 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? JointCount = Utils.BytesToUInt(animationdata, i); i += 4; // Get Joint count } joints = new binBVHJoint[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 < JointCount; iter++) { binBVHJoint joint = readJoint(animationdata, ref i); joints[iter] = joint; } }
/// <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> public 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(EndianSwap(data, i, 4)); i += 4; // Joint Priority override? rotationkeys = Utils.BytesToInt(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 } // Sanity check how many rotation keys there are if (rotationkeys < 0 || rotationkeys > 10000) { rotationkeys = 0; } rotations = readKeys(data, ref i, rotationkeys, -1.0f, 1.0f); if (!BitConverter.IsLittleEndian) { positionkeys = Utils.BytesToInt(EndianSwap(data, i, 4)); i += 4; // How many position keyframes } else { positionkeys = Utils.BytesToInt(data, i); i += 4; // How many position keyframes } // Sanity check how many positions keys there are if (positionkeys < 0 || positionkeys > 10000) { positionkeys = 0; } // Read in position keyframes positions = readKeys(data, ref i, positionkeys, -0.5f, 1.5f); pJoint.rotationkeys = rotations; pJoint.positionkeys = positions; return(pJoint); }