// Utility functions added with Bento to simplify handling of extra // spine joints, or other new joints internal to the original // skeleton, and unknown to the system avatar. #region BentoUtility public static AvatarJoint GetBaseSkeletonAncestor(AvatarJoint joint) { LLJoint ancestor = joint.Parent; while (ancestor.Parent != null && (ancestor.Support != SupportCategory.Base)) { Logger.LogDebug("AvatarJointMesh.GetBaseSkeletonAncestor", $"Skipping non-base ancestor {ancestor.Name}"); ancestor = ancestor.Parent; } return((AvatarJoint)ancestor); }
public void SetupJoint(AvatarJoint currentJoint) { for (UInt32 sj = 0; sj < NumSkinJoints; sj++) { SkinJoint js = SkinJoints[sj]; if (js.Joint != currentJoint) { continue; } // we've found a skinjoint for this joint.. Logger.LogDebug("AvatarJointMesh.SetupJoint", $"Mesh: {Name} joint {currentJoint.Name} matches skinjoint {sj}"); // is the last joint in the array our parent? List <JointRenderData> jrd = Mesh.JointRenderData; // SL-287 - need to update this so the results are the same if // additional extended-skeleton joints lie between this joint // and the original parent. LLJoint ancestor = GetBaseSkeletonAncestor(currentJoint); if (jrd.Count != 0 && jrd.LastItem().WorldMatrix == ancestor.GetWorldMatrix()) { // ...then just add ourselves AvatarJoint joint = js.Joint; jrd.Add(new JointRenderData(joint.GetWorldMatrix(), js)); Logger.LogDebug("AvatarJointMesh.SetupJoint", $"add joint[{jrd.Count - 1}] = {js.Joint.Name}"); } // otherwise add our ancestor and ourselves else { jrd.Add(new JointRenderData(ancestor.GetWorldMatrix(), null)); Logger.LogDebug("AvatarJointMesh.SetupJoint", $"add2 ancestor joint[{jrd.Count - 1}] = {ancestor.Name}"); jrd.Add(new JointRenderData(currentJoint.GetWorldMatrix(), js)); Logger.LogDebug("AvatarJointMesh.SetupJoint", $"add2 joint[{jrd.Count - 1}] = {currentJoint.Name}"); } } // depth-first traversal foreach (LLJoint child in currentJoint.Children) { SetupJoint((AvatarJoint)child); } }
public bool Parse(byte [] data) { int protectionLevel = form.getChecked(); //*thanks zwag!!1 Joints = new List <LLJoint>(); Constraints = new List <LLConstraint>(); UInt16 MajorVersion; // Should always be 1 int BasePriority; // 0-4 Normal. 5-7 valid. Clamp to 4. float Duration; string Emote; // Variable length string. Up to 127 characters according to LL; float LoopInPoint; float LoopOutPoint; int Loop; // BOOL float EaseInDuration; uint HandPose; // clamp to 14 Joints.Clear(); Constraints.Clear(); Emote = ""; //FileStream file = new FileStream(FileName, FileMode.Open); byte[] buffer = new byte[256]; int cof = 0; Buffer.BlockCopy(data, cof, buffer, 0, sizeof(ushort)); cof += sizeof(ushort); MajorVersion = BitConverter.ToUInt16(buffer, 0); Buffer.BlockCopy(data, cof, buffer, 0, sizeof(ushort)); cof += sizeof(ushort); //MinorVersion = BitConverter.ToUInt16(buffer, 0); //MinorVersion = 0; Buffer.BlockCopy(data, cof, buffer, 0, sizeof(Int32)); cof += sizeof(Int32); BasePriority = BitConverter.ToInt32(buffer, 0); //file.Read(buffer, 0, sizeof(float)); Buffer.BlockCopy(data, cof, buffer, 0, sizeof(float)); cof += sizeof(float); Duration = BitConverter.ToSingle(buffer, 0); //HACK: hack to make C# read null terminated scripts of undefined length. //TODO: Find a better way to do this. //file.Read(buffer, 0, 1); Buffer.BlockCopy(data, cof, buffer, 0, 1); cof += 1; while (buffer[0] != 0) { Emote += (char)buffer[0]; //file.Read(buffer, 0, 1); Buffer.BlockCopy(data, cof, buffer, 0, 1); cof += 1; } Buffer.BlockCopy(data, cof, buffer, 0, ((sizeof(float) * 4) + (sizeof(int) * 3))); cof += ((sizeof(float) * 4) + (sizeof(int) * 3)); //file.Read(buffer, 0, ((sizeof(float) * 4) + (sizeof(int) * 3))); LoopInPoint = BitConverter.ToSingle(buffer, 0); LoopOutPoint = BitConverter.ToSingle(buffer, sizeof(float)); Loop = BitConverter.ToInt32(buffer, sizeof(float) * 2); EaseInDuration = BitConverter.ToSingle(buffer, ((sizeof(float) * 2) + sizeof(int))); EaseInDuration = BitConverter.ToSingle(buffer, ((sizeof(float) * 3) + sizeof(int))); HandPose = BitConverter.ToUInt32(buffer, (sizeof(float) * 4) + sizeof(int)); Int32 JointCount = BitConverter.ToInt32(buffer, ((sizeof(float) * 4) + sizeof(int) * 2)); if (JointCount > 50) { return(false); } for (int curjoint = 0; curjoint < JointCount; ++curjoint) { string jointName = ""; //file.Read(buffer, 0, 1); Buffer.BlockCopy(data, cof, buffer, 0, 1); cof += 1; while (buffer[0] != 0) { //HACK: Make sure C# does not try to read things as unicode characters. //Do not use BitConverter.ToChar here. jointName += (char)buffer[0]; //file.Read(buffer, 0, 1); Buffer.BlockCopy(data, cof, buffer, 0, 1); cof += 1; } if (form.getChecked() <= 2) { if (!new List <string>(oldjoints).Contains(jointName)) { if (gdebug) { writethis("File Refused because joing wasnt an old joint", ConsoleColor.Gray, ConsoleColor.DarkRed); } return(false); } } else if (form.getChecked() <= 3) { if (!new List <string>(newjoints).Contains(jointName)) { if (gdebug) { writethis("File Refused because joigt wasnt innew joints", ConsoleColor.Gray, ConsoleColor.DarkRed); } return(false); } } LLJoint newJoint = new LLJoint(jointName); //file.Read(buffer, 0, sizeof(int) * 2); Buffer.BlockCopy(data, cof, buffer, 0, sizeof(int) * 2); cof += sizeof(int) * 2; newJoint.SetPriority(BitConverter.ToInt32(buffer, 0)); int RotCount = BitConverter.ToInt32(buffer, sizeof(int)); for (int curRot = 0; curRot < RotCount; ++curRot) { UInt16 time, x, y, z = 0; Buffer.BlockCopy(data, cof, buffer, 0, sizeof(UInt16) * 4); cof += sizeof(UInt16) * 4; //file.Read(buffer, 0, sizeof(UInt16) * 4); time = BitConverter.ToUInt16(buffer, 0); x = BitConverter.ToUInt16(buffer, sizeof(UInt16)); y = BitConverter.ToUInt16(buffer, sizeof(UInt16) * 2); z = BitConverter.ToUInt16(buffer, sizeof(UInt16) * 3); newJoint.AddRot(time, x, y, z); } //file.Read(buffer, 0, sizeof(int)); Buffer.BlockCopy(data, cof, buffer, 0, sizeof(int)); cof += sizeof(int); int PosCount = BitConverter.ToInt32(buffer, 0); for (int curPos = 0; curPos < PosCount; ++curPos) { UInt16 time, x, y, z = 0; Buffer.BlockCopy(data, cof, buffer, 0, sizeof(UInt16) * 4); cof += sizeof(UInt16) * 4; //file.Read(buffer, 0, sizeof(UInt16) * 4); time = BitConverter.ToUInt16(buffer, 0); x = BitConverter.ToUInt16(buffer, sizeof(UInt16)); y = BitConverter.ToUInt16(buffer, sizeof(UInt16) * 2); z = BitConverter.ToUInt16(buffer, sizeof(UInt16) * 3); newJoint.AddPos(time, x, y, z); } Joints.Add(newJoint); } //file.Read(buffer, 0, sizeof(int)); Buffer.BlockCopy(data, cof, buffer, 0, sizeof(int)); cof += sizeof(int); int ConstraintCount = BitConverter.ToInt32(buffer, 0); if (form.getChecked() <= 4) { if (ConstraintCount > 0) { if (gdebug) { writethis("File Refused because it had constraints", ConsoleColor.Gray, ConsoleColor.DarkRed); } return(false); } } if (ConstraintCount > 50) { return(false); } for (int curConst = 0; curConst < ConstraintCount; ++curConst) { Buffer.BlockCopy(data, cof, buffer, 0, 18 + 12 + 16 + 12 + 12 + 4 + 4 + 4 + 4); cof += 18 + 12 + 16 + 12 + 12 + 4 + 4 + 4 + 4; //file.Read(buffer, 0, 18 + 12 + 16 + 12 + 12 + 4 + 4 + 4 + 4); byte chainlen = buffer[0]; if (form.getChecked() <= 5) { if (chainlen > 2) { if (gdebug) { writethis("File Refused because chain greater then 2", ConsoleColor.Gray, ConsoleColor.DarkRed); } return(false); } if (chainlen > Joints.Count) { if (gdebug) { writethis("File Refused because greater than joints count", ConsoleColor.Gray, ConsoleColor.DarkRed); } return(false); } if (chainlen > JointCount) { if (gdebug) { writethis("File Refused because chain biger then jc", ConsoleColor.Gray, ConsoleColor.DarkRed); } return(false); } } LLConstraint.EConstraintType ctype = (LLConstraint.EConstraintType)buffer[1]; byte[] sourceb = new byte[16]; Buffer.BlockCopy(buffer, 2, sourceb, 0, 16); string source = sourceb.ToString(); Vector3 sourceoffset = new Vector3(); sourceoffset.X = BitConverter.ToSingle(buffer, 18); sourceoffset.Y = BitConverter.ToSingle(buffer, 22); sourceoffset.Z = BitConverter.ToSingle(buffer, 26); byte[] targetb = new byte[16]; Buffer.BlockCopy(buffer, 30, targetb, 0, 16); string target = targetb.ToString(); Vector3 targetoffset = new Vector3(); targetoffset.X = BitConverter.ToSingle(buffer, 46); targetoffset.Y = BitConverter.ToSingle(buffer, 50); targetoffset.Z = BitConverter.ToSingle(buffer, 54); Vector3 targetdir = new Vector3(); targetdir.X = BitConverter.ToSingle(buffer, 58); targetdir.Y = BitConverter.ToSingle(buffer, 62); targetdir.Z = BitConverter.ToSingle(buffer, 66); float ease_in_start = BitConverter.ToSingle(buffer, 70); float ease_in_stop = BitConverter.ToSingle(buffer, 74); float ease_out_start = BitConverter.ToSingle(buffer, 78); float ease_out_stop = BitConverter.ToSingle(buffer, 82); if (ConstraintCount > JointCount) { if (gdebug) { writethis("File Refused because cons more then joints", ConsoleColor.Gray, ConsoleColor.DarkRed); } return(false); } Constraints.Add(new LLConstraint(chainlen, ctype, source, target, sourceoffset, targetoffset, targetdir, ease_in_start, ease_in_stop, ease_out_start, ease_out_stop)); } //file.Close(); return(true); }
public bool Parse(byte [] data) { int protectionLevel = form.getChecked(); //*thanks zwag!!1 Joints = new List<LLJoint>(); Constraints = new List<LLConstraint>(); UInt16 MajorVersion; // Should always be 1 int BasePriority; // 0-4 Normal. 5-7 valid. Clamp to 4. float Duration; string Emote; // Variable length string. Up to 127 characters according to LL; float LoopInPoint; float LoopOutPoint; int Loop; // BOOL float EaseInDuration; uint HandPose; // clamp to 14 Joints.Clear(); Constraints.Clear(); Emote = ""; //FileStream file = new FileStream(FileName, FileMode.Open); byte[] buffer = new byte[256]; int cof = 0; Buffer.BlockCopy(data, cof, buffer, 0, sizeof(ushort)); cof += sizeof(ushort); MajorVersion = BitConverter.ToUInt16(buffer, 0); Buffer.BlockCopy(data, cof, buffer, 0, sizeof(ushort)); cof += sizeof(ushort); //MinorVersion = BitConverter.ToUInt16(buffer, 0); //MinorVersion = 0; Buffer.BlockCopy(data, cof, buffer, 0, sizeof(Int32)); cof += sizeof(Int32); BasePriority = BitConverter.ToInt32(buffer, 0); //file.Read(buffer, 0, sizeof(float)); Buffer.BlockCopy(data, cof, buffer, 0, sizeof(float)); cof += sizeof(float); Duration = BitConverter.ToSingle(buffer, 0); //HACK: hack to make C# read null terminated scripts of undefined length. //TODO: Find a better way to do this. //file.Read(buffer, 0, 1); Buffer.BlockCopy(data, cof, buffer, 0, 1); cof +=1; while (buffer[0] != 0) { Emote += (char)buffer[0]; //file.Read(buffer, 0, 1); Buffer.BlockCopy(data, cof, buffer, 0, 1); cof += 1; } Buffer.BlockCopy(data, cof, buffer, 0, ((sizeof(float) * 4) + (sizeof(int) * 3))); cof += ((sizeof(float) * 4) + (sizeof(int) * 3)); //file.Read(buffer, 0, ((sizeof(float) * 4) + (sizeof(int) * 3))); LoopInPoint = BitConverter.ToSingle(buffer, 0); LoopOutPoint = BitConverter.ToSingle(buffer, sizeof(float)); Loop = BitConverter.ToInt32(buffer, sizeof(float) * 2); EaseInDuration = BitConverter.ToSingle(buffer, ((sizeof(float) * 2) + sizeof(int))); EaseInDuration = BitConverter.ToSingle(buffer, ((sizeof(float) * 3) + sizeof(int))); HandPose = BitConverter.ToUInt32(buffer, (sizeof(float) * 4) + sizeof(int)); Int32 JointCount = BitConverter.ToInt32(buffer, ((sizeof(float) * 4) + sizeof(int) * 2)); if (JointCount > 50) return false; for (int curjoint = 0; curjoint < JointCount; ++curjoint) { string jointName = ""; //file.Read(buffer, 0, 1); Buffer.BlockCopy(data, cof, buffer, 0, 1); cof += 1; while (buffer[0] != 0) { //HACK: Make sure C# does not try to read things as unicode characters. //Do not use BitConverter.ToChar here. jointName += (char)buffer[0]; //file.Read(buffer, 0, 1); Buffer.BlockCopy(data, cof, buffer, 0, 1); cof += 1; } if (form.getChecked() <= 2) { if (!new List<string>(oldjoints).Contains(jointName)) { if (gdebug) writethis("File Refused because joing wasnt an old joint", ConsoleColor.Gray, ConsoleColor.DarkRed); return false; } } else if (form.getChecked() <= 3) { if (!new List<string>(newjoints).Contains(jointName)) { if (gdebug) writethis("File Refused because joigt wasnt innew joints", ConsoleColor.Gray, ConsoleColor.DarkRed); return false; } } LLJoint newJoint = new LLJoint(jointName); //file.Read(buffer, 0, sizeof(int) * 2); Buffer.BlockCopy(data, cof, buffer, 0, sizeof(int) * 2); cof += sizeof(int) * 2; newJoint.SetPriority(BitConverter.ToInt32(buffer, 0)); int RotCount = BitConverter.ToInt32(buffer, sizeof(int)); for (int curRot = 0; curRot < RotCount; ++curRot) { UInt16 time, x, y, z = 0; Buffer.BlockCopy(data, cof, buffer, 0, sizeof(UInt16) * 4); cof += sizeof(UInt16) * 4; //file.Read(buffer, 0, sizeof(UInt16) * 4); time = BitConverter.ToUInt16(buffer, 0); x = BitConverter.ToUInt16(buffer, sizeof(UInt16)); y = BitConverter.ToUInt16(buffer, sizeof(UInt16) * 2); z = BitConverter.ToUInt16(buffer, sizeof(UInt16) * 3); newJoint.AddRot(time, x, y, z); } //file.Read(buffer, 0, sizeof(int)); Buffer.BlockCopy(data, cof, buffer, 0, sizeof(int)); cof += sizeof(int); int PosCount = BitConverter.ToInt32(buffer, 0); for (int curPos = 0; curPos < PosCount; ++curPos) { UInt16 time, x, y, z = 0; Buffer.BlockCopy(data, cof, buffer, 0, sizeof(UInt16) * 4); cof += sizeof(UInt16) * 4; //file.Read(buffer, 0, sizeof(UInt16) * 4); time = BitConverter.ToUInt16(buffer, 0); x = BitConverter.ToUInt16(buffer, sizeof(UInt16)); y = BitConverter.ToUInt16(buffer, sizeof(UInt16) * 2); z = BitConverter.ToUInt16(buffer, sizeof(UInt16) * 3); newJoint.AddPos(time, x, y, z); } Joints.Add(newJoint); } //file.Read(buffer, 0, sizeof(int)); Buffer.BlockCopy(data, cof, buffer, 0, sizeof(int)); cof += sizeof(int); int ConstraintCount = BitConverter.ToInt32(buffer, 0); if (form.getChecked() <= 4) { if (ConstraintCount > 0) { if (gdebug) writethis("File Refused because it had constraints", ConsoleColor.Gray, ConsoleColor.DarkRed); return false; } } if (ConstraintCount > 50) return false; for (int curConst = 0; curConst < ConstraintCount; ++curConst) { Buffer.BlockCopy(data, cof, buffer, 0, 18 + 12 + 16 + 12 + 12 + 4 + 4 + 4 + 4); cof += 18 + 12 + 16 + 12 + 12 + 4 + 4 + 4 + 4; //file.Read(buffer, 0, 18 + 12 + 16 + 12 + 12 + 4 + 4 + 4 + 4); byte chainlen = buffer[0]; if (form.getChecked() <= 5) { if (chainlen > 2) { if (gdebug) writethis("File Refused because chain greater then 2", ConsoleColor.Gray, ConsoleColor.DarkRed); return false; } if (chainlen > Joints.Count) { if (gdebug) writethis("File Refused because greater than joints count", ConsoleColor.Gray, ConsoleColor.DarkRed); return false; } if (chainlen > JointCount) { if (gdebug) writethis("File Refused because chain biger then jc", ConsoleColor.Gray, ConsoleColor.DarkRed); return false; } } LLConstraint.EConstraintType ctype = (LLConstraint.EConstraintType)buffer[1]; byte[] sourceb = new byte[16]; Buffer.BlockCopy(buffer, 2, sourceb, 0, 16); string source = sourceb.ToString(); Vector3 sourceoffset = new Vector3(); sourceoffset.X = BitConverter.ToSingle(buffer, 18); sourceoffset.Y = BitConverter.ToSingle(buffer, 22); sourceoffset.Z = BitConverter.ToSingle(buffer, 26); byte[] targetb = new byte[16]; Buffer.BlockCopy(buffer, 30, targetb, 0, 16); string target = targetb.ToString(); Vector3 targetoffset = new Vector3(); targetoffset.X = BitConverter.ToSingle(buffer, 46); targetoffset.Y = BitConverter.ToSingle(buffer, 50); targetoffset.Z = BitConverter.ToSingle(buffer, 54); Vector3 targetdir = new Vector3(); targetdir.X = BitConverter.ToSingle(buffer, 58); targetdir.Y = BitConverter.ToSingle(buffer, 62); targetdir.Z = BitConverter.ToSingle(buffer, 66); float ease_in_start = BitConverter.ToSingle(buffer, 70); float ease_in_stop = BitConverter.ToSingle(buffer, 74); float ease_out_start = BitConverter.ToSingle(buffer, 78); float ease_out_stop = BitConverter.ToSingle(buffer, 82); if (ConstraintCount > JointCount) { if (gdebug) writethis("File Refused because cons more then joints", ConsoleColor.Gray, ConsoleColor.DarkRed); return false; } Constraints.Add(new LLConstraint(chainlen, ctype, source, target, sourceoffset, targetoffset, targetdir, ease_in_start, ease_in_stop, ease_out_start, ease_out_stop)); } //file.Close(); return true; }