GL.MultMatrix(Math3D.CreateTranslationMatrix(av.avatar.Position));\r
GL.MultMatrix(Math3D.CreateRotationMatrix(av.avatar.Rotation));\r
\r
+ \r
+ // Special case for eyeballs we need to offset the mesh to the correct position\r
+ // We have manually added the eyeball offset based on the headbone when we\r
+ // constructed the meshes, but why are the position offsets we got when loading\r
+ // the other meshes <0,7,0> ?\r
+ if (mesh.Name == "eyeBallRightMesh" || mesh.Name == "eyeBallLeftMesh")\r
+ {\r
+ // Mesh roation and position\r
+ GL.MultMatrix(Math3D.CreateTranslationMatrix(mesh.Position));\r
+ //TODO save the rot in a Quaternion in the Bone class rather than convert on the fly\r
+ Quaternion rot = new Quaternion(mesh.RotationAngles.X, mesh.RotationAngles.Y, mesh.RotationAngles.Z);\r
+ GL.MultMatrix(Math3D.CreateRotationMatrix(rot));\r
+ }\r
+\r
+\r
//Gl.glTranslatef(mesh.Position.X, mesh.Position.Y, mesh.Position.Z);\r
\r
GL.Rotate(mesh.RotationAngles.X, 1f, 0f, 0f);\r
}\r
\r
attachment_point apoint = GLAvatar.attachment_points[attachment_index];\r
- if (apoint.jointmesh == null)\r
- {\r
- //Arse-tachments for us then, things not decoded from avatar_lad fully.\r
- }\r
- else\r
- {\r
- Vector3 point = apoint.getposition();\r
- Quaternion rot = apoint.getrotation();\r
-\r
- GL.MultMatrix(Math3D.CreateTranslationMatrix(point));\r
- GL.MultMatrix(Math3D.CreateRotationMatrix(rot));\r
- }\r
+ \r
+ Vector3 point = Bone.getOffset(apoint.joint);\r
+ Vector3 rot = Bone.getRotation(apoint.joint);\r
+ //Todo Quaternion should be retured from getRotation()\r
+ Quaternion qrot = new Quaternion(rot.X, rot.Y, rot.Z);\r
+\r
+ GL.MultMatrix(Math3D.CreateTranslationMatrix(point));\r
+ GL.MultMatrix(Math3D.CreateRotationMatrix(qrot));\r
}\r
}\r
\r
{\r
}\r
\r
+ public void setMeshPos(Vector3 pos)\r
+ {\r
+ _position = pos;\r
+ }\r
+\r
+ public void setMeshRot(Vector3 rot)\r
+ {\r
+ _rotationAngles = rot;\r
+ }\r
+\r
public override void LoadMesh(string filename)\r
{\r
base.LoadMesh(filename);\r
\r
public static void loadlindenmeshes(string LODfilename)\r
{\r
+ Bone.loadbones("avatar_skeleton.xml");\r
+\r
string basedir = Directory.GetCurrentDirectory() + System.IO.Path.DirectorySeparatorChar + "character" + System.IO.Path.DirectorySeparatorChar;\r
\r
// Parse through avatar_lad.xml to find all of the mesh references\r
break;\r
\r
case "eyeBallRightMesh":\r
+ mesh.setMeshPos(Bone.getOffset("mEyeLeft"));\r
+ mesh.setMeshRot(Bone.getRotation("mEyeLeft"));\r
+ mesh.teFaceID = (int)AvatarTextureIndex.EyesBaked;\r
+ break;\r
+\r
case "eyeBallLeftMesh":\r
+ mesh.setMeshPos(Bone.getOffset("mEyeRight"));\r
+ mesh.setMeshRot(Bone.getRotation("mEyeRight"));\r
mesh.teFaceID = (int)AvatarTextureIndex.EyesBaked;\r
break;\r
\r
\r
_meshes[type] = mesh;\r
\r
- if (lod == 0)\r
- {\r
- //Associate each attachment point with the mesh that has its bones/joints\r
- foreach (attachment_point apoint in attachment_points.Values)\r
- {\r
- int index = 0;\r
-\r
- foreach (string jointname in mesh.SkinJoints)\r
- {\r
- if (jointname == apoint.joint)\r
- {\r
- apoint.jointmesh = mesh;\r
- apoint.jointmeshindex = index;\r
- Logger.Log("Adding " + apoint.name +"with joint "+ jointname + "to mesh " + mesh.Name,Helpers.LogLevel.Info);\r
- }\r
- index++;\r
- }\r
-\r
- }\r
- }\r
-\r
}\r
}\r
\r
\r
}\r
\r
+ public class Bone\r
+ {\r
+ public string name;\r
+ public Vector3 pos;\r
+ public Vector3 rot;\r
+ public Vector3 scale;\r
+ public Vector3 piviot;\r
+\r
+ public Bone parent;\r
+\r
+ public static Dictionary<string, Bone> mBones = new Dictionary<string, Bone>();\r
+\r
+ public static void loadbones(string skeletonfilename)\r
+ {\r
+ mBones.Clear();\r
+ string basedir = Directory.GetCurrentDirectory() + System.IO.Path.DirectorySeparatorChar + "character" + System.IO.Path.DirectorySeparatorChar;\r
+ XmlDocument skeleton = new XmlDocument();\r
+ skeleton.Load(basedir + skeletonfilename);\r
+ XmlNode boneslist = skeleton.GetElementsByTagName("linden_skeleton")[0]; \r
+ addbone(boneslist.ChildNodes[0],null);\r
+ }\r
+\r
+ public static void addbone(XmlNode bone, Bone parent)\r
+ {\r
+ Bone b = new Bone();\r
+ b.name = bone.Attributes.GetNamedItem("name").Value;\r
+\r
+ string pos = bone.Attributes.GetNamedItem("pos").Value;\r
+ string[] posparts = pos.Split(' ');\r
+ b.pos = new Vector3(float.Parse(posparts[0]), float.Parse(posparts[1]), float.Parse(posparts[2]));\r
+\r
+ string rot = bone.Attributes.GetNamedItem("rot").Value;\r
+ string[] rotparts = pos.Split(' ');\r
+ b.pos = new Vector3(float.Parse(rotparts[0]), float.Parse(rotparts[1]), float.Parse(rotparts[2]));\r
+\r
+ string scale = bone.Attributes.GetNamedItem("scale").Value;\r
+ string[] scaleparts = pos.Split(' ');\r
+ b.scale = new Vector3(float.Parse(scaleparts[0]), float.Parse(scaleparts[1]), float.Parse(scaleparts[2]));\r
+\r
+ //TODO piviot\r
+\r
+ b.parent = parent;\r
+\r
+ mBones.Add(b.name, b);\r
+\r
+ Logger.Log("Found bone " + b.name, Helpers.LogLevel.Info);\r
+\r
+ foreach (XmlNode childbone in bone.ChildNodes)\r
+ {\r
+ addbone(childbone,b);\r
+ }\r
+\r
+ }\r
+\r
+ //TODO check offset and rot calcuations should each offset be multiplied by its parent rotation in\r
+ // a standard child/parent rot/offset way?\r
+ public static Vector3 getOffset(string bonename)\r
+ {\r
+ Bone b;\r
+ if (mBones.TryGetValue(bonename, out b))\r
+ {\r
+ return (b.getOffset());\r
+ }\r
+ else\r
+ {\r
+ return Vector3.Zero;\r
+ }\r
+ }\r
+\r
+ public Vector3 getOffset()\r
+ {\r
+ Vector3 totalpos = pos;\r
+\r
+ if (parent != null)\r
+ {\r
+ totalpos = parent.getOffset() + pos;\r
+ }\r
+\r
+ return totalpos;\r
+ }\r
+\r
+ public static Vector3 getRotation(string bonename)\r
+ {\r
+ Bone b;\r
+ if (mBones.TryGetValue(bonename, out b))\r
+ {\r
+ return (b.getRotation());\r
+ }\r
+ else\r
+ {\r
+ return Vector3.Zero;\r
+ }\r
+ }\r
+\r
+ public Vector3 getRotation()\r
+ {\r
+ Vector3 totalrot = rot;\r
+\r
+ if (parent != null)\r
+ {\r
+ totalrot = parent.getRotation() + rot;\r
+ }\r
+\r
+ return totalrot;\r
+ }\r
+ \r
+ }\r
+\r
}\r