OSDN Git Service

Add bone loader and offset eyes to correct position based on head bone
authorRobin Cornelius <robin.cornelius@gmail.com>
Sun, 3 Jul 2011 08:06:08 +0000 (08:06 +0000)
committerRobin Cornelius <robin.cornelius@gmail.com>
Sun, 3 Jul 2011 08:06:08 +0000 (08:06 +0000)
git-svn-id: https://radegast.googlecode.com/svn/trunk@937 f7a694da-4d33-11de-9ad6-1127a62b9fcd

Radegast/GUI/Rendering/Rendering.cs
Radegast/GUI/Rendering/RenderingHelpers.cs

index 2ae1782..92d7be7 100644 (file)
@@ -1037,6 +1037,21 @@ namespace Radegast.Rendering
                             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
@@ -1339,18 +1354,14 @@ namespace Radegast.Rendering
                             }\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
index 7f17242..618b758 100644 (file)
@@ -451,6 +451,16 @@ namespace Radegast.Rendering
         {\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
@@ -525,6 +535,8 @@ namespace Radegast.Rendering
 \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
@@ -591,7 +603,14 @@ namespace Radegast.Rendering
                     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
@@ -615,27 +634,6 @@ namespace Radegast.Rendering
 \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
@@ -649,4 +647,112 @@ namespace Radegast.Rendering
 \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