Example #1
0
        /// <summary>
        /// <param name="node">The "<node>" element to be converted.</param>
        /// </summary>
        private Bone ReadNode(Bone parent, Document.Node node)
        {
            Bone bone = new Bone(this, parent, node.id, node.name, node.type);

            if (node.instances != null)
            {
                foreach (Document.Instance instance in node.instances)
                {
                    if (instance is Document.InstanceGeometry)
                    {
                        // resolve bindings
                        Dictionary<string, string> materialBinding = ResolveMaterialBinding((Document.InstanceWithMaterialBind)instance);

                        Document.Geometry geo = (Document.Geometry)doc.dic[instance.url.Fragment];
                        CMesh modelMesh;
                        if (meshes.TryGetValue(geo.id, out modelMesh))
                        {
                            InstanceMesh instanceMesh = new InstanceMesh(modelMesh,
                                                                         bone,
                                                                         materialBinding);
                            instanceMeshes.Add(instanceMesh);
                        }
                        else
                            COLLADAUtil.Log(COLLADALogType.Error, "mesh with id " + geo.id + " not found in internal mesh list");
                    }
                    else if (instance is Document.InstanceCamera)
                    {
                        Document.InstanceCamera instanceCamera = (Document.InstanceCamera)instance;
                        Document.Camera docCam = (Document.Camera)doc.dic[instanceCamera.url.Fragment];
                        if (docCam != null)
                        {
                            Camera camera;
                            if (cameras.TryGetValue(docCam.id, out camera))
                            {
                                InstanceCamera c = new InstanceCamera(camera, bone);
                                instanceCameras.Add(c);
                            }
                            else
                                COLLADAUtil.Log(COLLADALogType.Error, "Camera " + docCam.id + " not found in internal camera list.");
                        }
                        else
                            COLLADAUtil.Log(COLLADALogType.Error, "Camera " + instanceCamera.url.Fragment + " not found.");
                    }
                    else if (instance is Document.InstanceLight)
                    {
                        // TODO: light
                    }
                    else if (instance is Document.InstanceController)
                    {
                        Document.InstanceController instanceController = (Document.InstanceController)instance;
                        Document.ISkinOrMorph skinOrMorph = ((Document.Controller)doc.dic[instanceController.url.Fragment]).controller;
                        if (skinOrMorph is Document.Skin)
                        {
                            // resolve bindings
                            Dictionary<string, string> materialBinding = ResolveMaterialBinding((Document.InstanceWithMaterialBind)instance);
                            Document.Skin skin = (Document.Skin)skinOrMorph;
                            Document.Geometry geo = ((Document.Geometry)doc.dic[skin.source.Fragment]);

                            // make sure mesh is in loaded mesh list
                            CMesh mesh;
                            if (meshes.TryGetValue(geo.id, out mesh))
                            {
                                // mesh was loaded once successfully, try to look for it in the list of skinned
                                // meshes (skinned meshes have different vertex declarations)...
                                CSkinnedMesh skinnedMesh;
                                if (!skinnedMeshes.TryGetValue(geo.id, out skinnedMesh))
                                {
                                    // mesh wasn't found, create it once
                                    skinnedMesh = new CSkinnedMesh(this, geo, skin);
                                    skinnedMeshes.Add(geo.id, skinnedMesh);
                                }

                                var skeletonRootNodes = instanceController.Skeleton.Select(s => (Document.Node)doc.dic[s.Fragment]).ToArray();
                                SkinnedInstanceMesh skinnedInstanceMesh = new SkinnedInstanceMesh(
                                    skinnedMesh,
                                    bone,
                                    materialBinding,
                                    skeletonRootNodes);
                                instanceMeshes.Add(skinnedInstanceMesh);
                            }
                            else
                                COLLADAUtil.Log(COLLADALogType.Error, "mesh with id " + geo.id + " not found in internal mesh list");

                        }
                        else if (skinOrMorph is Document.Morph)
                        {
                            // TODO: morph
                        }
                        else
                            throw new Exception("Unknowned type of controller:" + skinOrMorph.GetType().ToString());
                    }
                    else if (instance is Document.InstanceNode)
                    {
                        Document.Node instanceNode = ((Document.Node)doc.dic[instance.url.Fragment]);
                        bone.Children.Add(ReadNode(bone, instanceNode));

                    }
                    else
                        throw new Exception("Unkowned type of INode in scene :" + instance.GetType().ToString());
                }
            }

            // read transforms
            if (node.transforms != null)
            {
                foreach (Document.TransformNode transformNode in node.transforms)
                {
                    if (transformNode is Document.Translate)
                        bone.Transforms.Add(transformNode.sid, new TranslateTransform(new Vector3(transformNode[0], transformNode[1], transformNode[2])));
                    else if (transformNode is Document.Rotate)
                        bone.Transforms.Add(transformNode.sid, new RotateTransform(new Vector3(transformNode[0], transformNode[1], transformNode[2]), transformNode[3]));
                    else if (transformNode is Document.Lookat)
                        bone.Transforms.Add(transformNode.sid, new Transform(Matrix.LookAtLH(new Vector3(transformNode[0], transformNode[1], transformNode[2]), new Vector3(transformNode[3], transformNode[4], transformNode[5]), new Vector3(transformNode[6], transformNode[7], transformNode[8]))));
                    else if (transformNode is Document.Matrix)
                    {
                        Matrix m = Matrix.Identity;
                        m.M11 = transformNode[0];
                        m.M21 = transformNode[01];
                        m.M31 = transformNode[02];
                        m.M41 = transformNode[03];
                        m.M12 = transformNode[04];
                        m.M22 = transformNode[05];
                        m.M32 = transformNode[06];
                        m.M42 = transformNode[07];
                        m.M13 = transformNode[08];
                        m.M23 = transformNode[09];
                        m.M33 = transformNode[10];
                        m.M43 = transformNode[11];
                        m.M14 = transformNode[12];
                        m.M24 = transformNode[13];
                        m.M34 = transformNode[14];
                        m.M44 = transformNode[15];
                        bone.Transforms.Add(transformNode.sid, new Transform(m));
                    }
                    else if (transformNode is Document.Scale)
                    {
                        bone.Transforms.Add(transformNode.sid, new ScaleTransform(new Vector3(transformNode[0], transformNode[1], transformNode[2])));
                    }
                    else if (transformNode is Document.Skew)
                    {
                        // Convert Skew to a matrix
                        float angle = transformNode[0] * (float)DegToRad;
                        Vector3 a = new Vector3(transformNode[1], transformNode[2], transformNode[3]);
                        Vector3 b = new Vector3(transformNode[4], transformNode[5], transformNode[6]);
                        Vector3 n2 = Vector3.Normalize(b);
                        Vector3 a1 = n2 * Vector3.Dot(a, n2);
                        Vector3 a2 = a - a1;
                        Vector3 n1 = Vector3.Normalize(a2);
                        float an1 = Vector3.Dot(a, n1);
                        float an2 = Vector3.Dot(a, n2);
                        double rx = an1 * Math.Cos(angle) - an2 * Math.Sin(angle);
                        double ry = an1 * Math.Sin(angle) + an2 * Math.Cos(angle);
                        float alpha = 0.0f;
                        Matrix m = Matrix.Identity;

                        if (rx <= 0.0) throw new Exception("Skew: angle too large");
                        if (an1 != 0) alpha = (float)(ry / rx - an2 / an1);

                        m.M11 = n1.X * n2.X * alpha + 1.0f;
                        m.M12 = n1.Y * n2.X * alpha;
                        m.M13 = n1.Z * n2.X * alpha;

                        m.M21 = n1.X * n2.Y * alpha;
                        m.M22 = n1.Y * n2.Y * alpha + 1.0f;
                        m.M23 = n1.Z * n2.Y * alpha;

                        m.M31 = n1.X * n2.Z * alpha;
                        m.M32 = n1.Y * n2.Z * alpha;
                        m.M33 = n1.Z * n2.Z * alpha + 1.0f;

                        bone.Transforms.Add(transformNode.sid, new Transform(m));
                    }
                }
            }

            if (node.children != null)
            {
                foreach (Document.Node child in node.children)
                {
                    bone.Children.Add(ReadNode(bone, child));
                }
            }

            return bone;
        }
Example #2
0
            public SkinnedInstanceMesh(CSkinnedMesh mesh, Bone parentBone,
                Dictionary<string, string> materialBinding, Document.Node[] skeletonRootNodes)
                : base(mesh, parentBone, materialBinding)
            {
                this.skinnedMesh = mesh;
                this.skeletonRootNodes = skeletonRootNodes;

                bindShapeMatrix = new Matrix();
                bindShapeMatrix.M11 = mesh.Skin.bindShapeMatrix[0, 0];
                bindShapeMatrix.M12 = mesh.Skin.bindShapeMatrix[1, 0];
                bindShapeMatrix.M13 = mesh.Skin.bindShapeMatrix[2, 0];
                bindShapeMatrix.M14 = mesh.Skin.bindShapeMatrix[3, 0];
                bindShapeMatrix.M21 = mesh.Skin.bindShapeMatrix[0, 1];
                bindShapeMatrix.M22 = mesh.Skin.bindShapeMatrix[1, 1];
                bindShapeMatrix.M23 = mesh.Skin.bindShapeMatrix[2, 1];
                bindShapeMatrix.M24 = mesh.Skin.bindShapeMatrix[3, 1];
                bindShapeMatrix.M31 = mesh.Skin.bindShapeMatrix[0, 2];
                bindShapeMatrix.M32 = mesh.Skin.bindShapeMatrix[1, 2];
                bindShapeMatrix.M33 = mesh.Skin.bindShapeMatrix[2, 2];
                bindShapeMatrix.M34 = mesh.Skin.bindShapeMatrix[3, 2];
                bindShapeMatrix.M41 = mesh.Skin.bindShapeMatrix[0, 3];
                bindShapeMatrix.M42 = mesh.Skin.bindShapeMatrix[1, 3];
                bindShapeMatrix.M43 = mesh.Skin.bindShapeMatrix[2, 3];
                bindShapeMatrix.M44 = mesh.Skin.bindShapeMatrix[3, 3];
            }