45         private int rotationkeys;
 
   51         private int positionkeys;
 
  105         private uint m_jointCount;
 
  118             using (MemoryStream ms = 
new MemoryStream())
 
  119             using (BinaryWriter iostream = 
new BinaryWriter(ms))
 
  121                 iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(unknown0)));
 
  122                 iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(unknown1)));
 
  123                 iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(Priority)));
 
  124                 iostream.Write(BinBVHUtil.ES(Utils.FloatToBytes(Length)));
 
  125                 iostream.Write(BinBVHUtil.WriteNullTerminatedString(ExpressionName));
 
  126                 iostream.Write(BinBVHUtil.ES(Utils.FloatToBytes(InPoint)));
 
  127                 iostream.Write(BinBVHUtil.ES(Utils.FloatToBytes(OutPoint)));
 
  128                 iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(Loop ? 1 : 0)));
 
  129                 iostream.Write(BinBVHUtil.ES(Utils.FloatToBytes(EaseInTime)));
 
  130                 iostream.Write(BinBVHUtil.ES(Utils.FloatToBytes(EaseOutTime)));
 
  131                 iostream.Write(BinBVHUtil.ES(Utils.UIntToBytes(
HandPose)));
 
  132                 iostream.Write(BinBVHUtil.ES(Utils.UIntToBytes((uint)(Joints.Length))));
 
  134                 for (
int i = 0; i < Joints.Length; i++)
 
  136                     Joints[i].WriteBytesToStream(iostream, InPoint, OutPoint);
 
  138                 iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(0)));
 
  140                 using (MemoryStream ms2 = (MemoryStream)iostream.BaseStream)
 
  141                     outputbytes = ms2.ToArray();
 
  155             ExpressionName = string.Empty;
 
  166             Joints[0].Name = 
"mPelvis";
 
  167             Joints[0].Priority = 7;
 
  170             Random rnd = 
new Random();
 
  173             Joints[0].rotationkeys[0].time = (0f);
 
  174             Joints[0].rotationkeys[0].key_element.X = ((float)rnd.NextDouble() * 2 - 1);
 
  175             Joints[0].rotationkeys[0].key_element.Y = ((float)rnd.NextDouble() * 2 - 1);
 
  176             Joints[0].rotationkeys[0].key_element.Z = ((float)rnd.NextDouble() * 2 - 1);
 
  179             Joints[0].positionkeys[0].time = (0f);
 
  180             Joints[0].positionkeys[0].key_element.X = ((float)rnd.NextDouble() * 2 - 1);
 
  181             Joints[0].positionkeys[0].key_element.Y = ((float)rnd.NextDouble() * 2 - 1);
 
  182             Joints[0].positionkeys[0].key_element.Z = ((float)rnd.NextDouble() * 2 - 1);
 
  190             if (!BitConverter.IsLittleEndian)
 
  192                 unknown0 = Utils.BytesToUInt16(BinBVHUtil.EndianSwap(animationdata,i,2)); i += 2; 
 
  193                 unknown1 = Utils.BytesToUInt16(BinBVHUtil.EndianSwap(animationdata, i, 2)); i += 2; 
 
  194                 Priority = Utils.BytesToInt(BinBVHUtil.EndianSwap(animationdata, i, 4)); i += 4;
 
  195                 Length = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4;
 
  199                 unknown0 = Utils.BytesToUInt16(animationdata, i); i += 2; 
 
  200                 unknown1 = Utils.BytesToUInt16(animationdata, i); i += 2; 
 
  201                 Priority = Utils.BytesToInt(animationdata, i); i += 4;
 
  202                 Length = Utils.BytesToFloat(animationdata, i); i += 4;
 
  204             ExpressionName = ReadBytesUntilNull(animationdata, ref i);
 
  205             if (!BitConverter.IsLittleEndian)
 
  207                 InPoint = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4;
 
  208                 OutPoint = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4;
 
  209                 Loop = (Utils.BytesToInt(BinBVHUtil.EndianSwap(animationdata, i, 4)) != 0); i += 4;
 
  210                 EaseInTime = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4;
 
  211                 EaseOutTime = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4;
 
  212                 HandPose = Utils.BytesToUInt(BinBVHUtil.EndianSwap(animationdata, i, 4)); i += 4; 
 
  214                 m_jointCount = Utils.BytesToUInt(animationdata, i); i += 4; 
 
  218                 InPoint = Utils.BytesToFloat(animationdata, i); i += 4;
 
  219                 OutPoint = Utils.BytesToFloat(animationdata, i); i += 4;
 
  220                 Loop = (Utils.BytesToInt(animationdata, i) != 0); i += 4;
 
  221                 EaseInTime = Utils.BytesToFloat(animationdata, i); i += 4;
 
  222                 EaseOutTime = Utils.BytesToFloat(animationdata, i); i += 4;
 
  223                 HandPose = Utils.BytesToUInt(animationdata, i); i += 4; 
 
  225                 m_jointCount = Utils.BytesToUInt(animationdata, i); i += 4; 
 
  231             for (
int iter = 0; iter < m_jointCount; iter++)
 
  233                 binBVHJoint joint = readJoint(animationdata, ref i);
 
  234                 Joints[iter] = joint;
 
  247         private static string ReadBytesUntilNull(byte[] data, ref 
int i)
 
  254             for (
int j = i; j < data.Length; j++)
 
  256                 char spot = Convert.ToChar(data[j]);
 
  276                 byte[] interm = 
new byte[endpos-i];
 
  277                 for (; i<endpos; i++)
 
  279                     interm[i-startpos] = data[i];
 
  283                 return Utils.BytesToString(interm);
 
  295         private binBVHJoint readJoint(byte[] data, ref 
int i)
 
  298             binBVHJointKey[] positions;
 
  299             binBVHJointKey[] rotations;
 
  301             binBVHJoint pJoint = 
new binBVHJoint();
 
  313             pJoint.Name = ReadBytesUntilNull(data, ref i); 
 
  337             if (!BitConverter.IsLittleEndian)
 
  339                 pJoint.Priority = Utils.BytesToInt(BinBVHUtil.EndianSwap(data, i, 4)); i += 4; 
 
  340                 rotationkeys = Utils.BytesToInt(BinBVHUtil.EndianSwap(data, i, 4)); i += 4; 
 
  344                 pJoint.Priority = Utils.BytesToInt(data, i); i += 4; 
 
  345                 rotationkeys = Utils.BytesToInt(data, i); i += 4; 
 
  350             rotations = readKeys(data, ref i, rotationkeys, -1f, 1f);
 
  351             for (
int iter = 0; iter < rotations.Length; iter++)
 
  353                 rotations[iter].W = 1f -
 
  354                     (rotations[iter].key_element.X + rotations[iter].key_element.Y +
 
  355                      rotations[iter].key_element.Z);
 
  359             if (!BitConverter.IsLittleEndian)
 
  361                 positionkeys = Utils.BytesToInt(BinBVHUtil.EndianSwap(data, i, 4)); i += 4; 
 
  365                 positionkeys = Utils.BytesToInt(data, i); i += 4; 
 
  371             positions = readKeys(data, ref i, positionkeys, -5f, 5f);
 
  373             pJoint.rotationkeys = rotations;
 
  374             pJoint.positionkeys = positions;
 
  389         private binBVHJointKey[] readKeys(byte[] data, ref 
int i, 
int keycount, 
float min, 
float max)
 
  408             binBVHJointKey[] m_keys = 
new binBVHJointKey[keycount];
 
  409             for (
int j = 0; j < keycount; j++)
 
  411                 binBVHJointKey pJKey = 
new binBVHJointKey();
 
  412                 if (!BitConverter.IsLittleEndian)
 
  414                     pJKey.time = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, InPoint, OutPoint); i += 2;
 
  415                     x = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, min, max); i += 2;
 
  416                     y = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, min, max); i += 2;
 
  417                     z = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, min, max); i += 2;
 
  421                     pJKey.time = Utils.UInt16ToFloat(data, i, InPoint, OutPoint); i += 2;
 
  422                     x = Utils.UInt16ToFloat(data, i, min, max); i += 2;
 
  423                     y = Utils.UInt16ToFloat(data, i, min, max); i += 2;
 
  424                     z = Utils.UInt16ToFloat(data, i, min, max); i += 2;
 
  426                 pJKey.key_element = 
new Vector3(x, y, z);
 
  465             iostream.Write(BinBVHUtil.WriteNullTerminatedString(Name));
 
  466             iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(Priority)));
 
  467             iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(rotationkeys.Length)));
 
  468             for (
int i=0;i<rotationkeys.Length;i++)
 
  470                 rotationkeys[i].WriteBytesToStream(iostream, InPoint, OutPoint,  -1f, 1f);
 
  472             iostream.Write(BinBVHUtil.ES(Utils.IntToBytes((positionkeys.Length))));
 
  473             for (
int i = 0; i < positionkeys.Length; i++)
 
  475                 positionkeys[i].WriteBytesToStream(iostream, InPoint, OutPoint, -256f, 256f);
 
  495         public void WriteBytesToStream(BinaryWriter iostream, 
float InPoint, 
float OutPoint, 
float min, 
float max)
 
  497             iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(BinBVHUtil.FloatToUInt16(time, InPoint, OutPoint))));
 
  498             iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(BinBVHUtil.FloatToUInt16(key_element.X, min, max))));
 
  499             iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(BinBVHUtil.FloatToUInt16(key_element.Y, min, max))));
 
  500             iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(BinBVHUtil.FloatToUInt16(key_element.Z, min, max))));
 
  523     public static class BinBVHUtil
 
  525         public const float ONE_OVER_U16_MAX = 1.0f / UInt16.MaxValue;
 
  527         public static UInt16 FloatToUInt16(
float val, 
float lower, 
float upper)
 
  557             uival = (UInt16)(val * UInt16.MaxValue);
 
  569         public static byte[] ES(byte[] arr)
 
  571             if (!BitConverter.IsLittleEndian)
 
  575         public static byte[] EndianSwap(byte[] arr, 
int offset, 
int len)
 
  577             byte[] bendian = 
new byte[offset + len];
 
  578             Buffer.BlockCopy(arr, offset, bendian, 0, len);
 
  579             Array.Reverse(bendian);
 
  583         public static byte[] WriteNullTerminatedString(
string str)
 
  585             byte[] output = 
new byte[str.Length + 1];
 
  586             Char[] chr = str.ToCharArray();
 
  588             for (i = 0; i < chr.Length; i++)
 
  590                 output[i] = Convert.ToByte(chr[i]);
 
  594             output[i] = Convert.ToByte(
'\0');
 
int Priority
Joint Animation Override? Was the same as the Priority in testing.. 
binBVHJoint[] Joints
Contains an array of joints 
uint HandPose
Meta Data for the Hand Pose 
Single OutPoint
The time in seconds to end the animation 
binBVHJointKey[] positionkeys
Array of Position Keyframes in order from earliest to latest This seems to only be for the Pelvis...
void WriteBytesToStream(BinaryWriter iostream, float InPoint, float OutPoint)
int Priority
Animation Priority 
Single InPoint
The time in seconds to start the animation 
Single EaseOutTime
Meta data. Ease out seconds. 
Vector3 key_element
Either a Vector3 position or a Vector3 Euler rotation 
Single EaseInTime
Meta data. Ease in Seconds. 
HandPose
Poses set in the animation metadata for the hands. 
Written to decode and encode a binary animation asset. The SecondLife Client reads in a BVH file and ...
A Joint and it's associated meta data and keyframes 
BinBVHAnimation(byte[] animationdata)
string ExpressionName
Expression set in the client. Null if [None] is selected 
OpenSim.Framework.Animation Animation
bool Loop
Loop the animation 
void WriteBytesToStream(BinaryWriter iostream, float InPoint, float OutPoint, float min, float max)
string Name
Name of the Joint. Matches the avatar_skeleton.xml in client distros 
A Joint Keyframe. This is either a position or a rotation. 
binBVHJointKey[] rotationkeys
Array of Rotation Keyframes in order from earliest to latest 
Single Length
The animation length in seconds.