示例#1
0
        private void LoadFromColladaSceneNode(ColladaSceneNodeBase node)
        {
            if (node.Type != ColladaSceneNodeBase.NodeType.Node && node.Type != ColladaSceneNodeBase.NodeType.Scene)
            {
                return;
            }
            // This is not correct. When using a skin there is an 'instance_controller'
            if (node.Instance_Geometry != null)
            {
                ColladaMesh mesh = node.Instance_Geometry;

                for (int iPart = 0; iPart < mesh.Parts.Count; iPart++)
                {
                    ColladaMesh.PrimitiveList meshPart = mesh.Parts[iPart];

                    SkinnedMesh skinnedMesh  = new SkinnedMesh(skinnedModel);
                    Matrix      objectMatrix = node.GetFullMatrix() * Matrix.CreateRotationX(-MathHelper.PiOver2);

                    LoadMesh(skinnedMesh, mesh, meshPart, objectMatrix);

                    skinnedModel.Meshes.Add(skinnedMesh);

                    //model.FullData.ObjectMatrix = node.GetFullMatrix();
                    // TODO: this only counts when model is from max!
                    //model.FullData.ObjectMatrix = model.FullData.ObjectMatrix * Matrix.CreateRotationX( -MathHelper.PiOver2 );
                }
            }

            for (int iNode = 0; iNode < node.Nodes.Count; iNode++)
            {
                LoadFromColladaSceneNode(node.Nodes[iNode]);
            }
        }
示例#2
0
            public void AppendMesh(ColladaMesh mesh, Matrix worldMatrix)
            {
                Matrix normalMatrix = Matrix.Transpose(Matrix.Invert(worldMatrix));

                int vertexCount   = VertexData.Count;
                int normalCount   = NormalData.Count;
                int texcoordCount = TexcoordData.Count;

                foreach (Vector3 v in mesh.VertexData)
                {
                    VertexData.Add(VectorTransform(v, worldMatrix));
                }
                foreach (Vector3 v in mesh.NormalData)
                {
                    NormalData.Add(Vector3.Normalize(VectorTransform(v, normalMatrix)));
                }
                TexcoordData.AddRange(mesh.TexcoordData);

                foreach (int index in mesh.VertexIndices)
                {
                    VertexIndices.Add(vertexCount + index);
                }

                foreach (int index in mesh.NormalIndices)
                {
                    NormalIndices.Add(normalCount + index);
                }

                foreach (int index in mesh.TexcoordIndices)
                {
                    TexcoordIndices.Add(texcoordCount + index);
                }
            }
示例#3
0
        public static Software.Mesh ParseCollada(String filename)
        {
            ColladaDocument doc        = new ColladaDocument(filename);
            ColladaMesh     resultMesh = new ColladaMesh();
            Dictionary <String, ColladaMesh> geometryMeshes = new Dictionary <string, ColladaMesh>();

            foreach (ColladaDocument.Geometry g in doc.geometries)
            {
                if (geometryMeshes.ContainsKey(g.id))
                {
                    throw new Exception("Duplicate geometry entries");
                }
                geometryMeshes[g.id] = ExtractColladaGeometry(g);
            }

            if (doc.visualScenes.Count != 1)
            {
                throw new NotImplementedException("There has to be exactly one Visual Scene");
            }

            foreach (ColladaDocument.Node n in doc.visualScenes[0].nodes)
            {
                HandleNode(geometryMeshes, ref resultMesh, n, Matrix.Identity);
            }

            resultMesh.BuildVertexList();

            return(IndexedCollada(resultMesh.Vertices, resultMesh.Indices));
        }
示例#4
0
            public ColladaGeometry(ColladaRoot collada, XElement node) : base(collada, node, "")
            {
                XElement xElement = node.Element(ColladaRoot.Namespace + "mesh");

                if (xElement != null)
                {
                    Mesh = new ColladaMesh(collada, xElement);
                }
            }
 public void Read(XmlNode root)
 {
     id   = (string)root.Attributes["id"].Value;
     name = (string)root.Attributes["name"].Value;
     mesh = new ColladaMesh();
     foreach (XmlNode node in root.ChildNodes)
     {
         if (node.Name.Equals("mesh"))
         {
             mesh.Read(node);
         }
     }
 }
示例#6
0
        public void LoadMeshes()
        {
            //Dictionary<ColladaMaterial, EditorMaterial> materials = new Dictionary<ColladaMaterial, EditorMaterial>();

            // Load all models from the scene. Each meshPart/primitivelist will become a seperate model
            //TODO: this does not work, now simply load every mesh found
            //LoadFromColladaSceneNode( colladaModel.Scene );
            for (int i = 0; i < colladaModel.Meshes.Count; i++)
            {
                ColladaMesh colladaMesh = colladaModel.Meshes[i];
                for (int j = 0; j < colladaMesh.Parts.Count; j++)
                {
                    SkinnedMesh mesh = new SkinnedMesh(skinnedModel);
                    skinnedModel.Meshes.Add(mesh);
                    LoadMesh(mesh, colladaMesh, colladaMesh.Parts[j], Matrix.CreateRotationX(-MathHelper.PiOver2));
                }
            }
        }
示例#7
0
        private static void HandleNode(Dictionary <string, ColladaMesh> geometryMeshes, ref ColladaMesh resultMesh, ColladaDocument.Node node, Matrix world)
        {
            if (node.transforms != null)
            {
                world = ConcatTransforms(node.transforms, world);
            }

            if (node.instances != null)
            {
                if (node.instances.Count != 1)
                {
                    throw new Exception("Nodes need to have exactly one instance right now");
                }

                if (!(node.instances[0] is ColladaDocument.InstanceGeometry))
                {
                    return;     // SILENT FAIL
                }
                ColladaDocument.Instance i = node.instances[0];
                ColladaMesh mesh           = geometryMeshes[i.url.Fragment];
                resultMesh.AppendMesh(mesh, world);
                if (node.children != null && node.children.Count > 0)
                {
                    throw new Exception("Tell Joakim.");
                }
            }
            else if (node.children != null && node.children.Count > 0)
            {
                foreach (ColladaDocument.Node n in node.children)
                {
                    HandleNode(geometryMeshes, ref resultMesh, n, world);
                }
            }
            else
            {
                //throw new Exception("Node has no instance and no child. Keh?");
            }
        }
        public static Software.Mesh ParseCollada(String filename)
        {
            ColladaDocument doc = new ColladaDocument(filename);
            ColladaMesh resultMesh = new ColladaMesh();
            Dictionary<String, ColladaMesh> geometryMeshes = new Dictionary<string, ColladaMesh>();

            foreach (ColladaDocument.Geometry g in doc.geometries)
            {
                if (geometryMeshes.ContainsKey(g.id))
                    throw new Exception("Duplicate geometry entries");
                geometryMeshes[g.id] = ExtractColladaGeometry(g);
            }

            if (doc.visualScenes.Count != 1)
                throw new NotImplementedException("There has to be exactly one Visual Scene");

            foreach (ColladaDocument.Node n in doc.visualScenes[0].nodes)
                HandleNode(geometryMeshes, ref resultMesh, n, Matrix.Identity);

            resultMesh.BuildVertexList();

            return IndexedCollada(resultMesh.Vertices, resultMesh.Indices);
        }
示例#9
0
        private static ColladaMesh ExtractColladaGeometry(ColladaDocument.Geometry g)
        {
            ColladaMesh mesh = new ColladaMesh();
            var         m    = g.mesh;

            Vector3[] vertexData   = null;
            Vector3[] normalData   = null;
            Vector3[] texcoordData = null;

            if (m.primitives.Count != 1)
            {
                throw new NotImplementedException("m.primitives.Count = " + m.primitives.Count);
            }
            var p = m.primitives[0];


            Dictionary <string, float[]> data = new Dictionary <string, float[]>();

            for (int i = 0; i < m.sources.Count; i++)
            {
                ColladaDocument.Array <float> inputArr = (ColladaDocument.Array <float>)m.sources[i].array;
                if (data.ContainsKey(m.sources[i].id))
                {
                    throw new Exception("A data entry called " + m.sources[i].id + " has already been parsed.");
                }
                data[m.sources[i].id] = inputArr.arr;
            }

            int indlen = p.p.Length / p.stride;

            int[] vertexIndices   = new int[indlen];
            int[] normalIndices   = new int[indlen];
            int[] texcoordIndices = new int[indlen];
            foreach (ColladaDocument.Input input in p.Inputs)
            {
                switch (input.semantic.ToLower())
                {
                case "vertex":
                    if (!(input.source is ColladaDocument.Vertices))
                    {
                        throw new Exception("VERTEX source should be of type ColladaDocument.Vertices");
                    }
                    ProcessVertex((ColladaDocument.Vertices)input.source, p.p, p.stride, input.offset, data,
                                  ref vertexData, ref vertexIndices, ref normalData, ref normalIndices, ref texcoordData, ref texcoordIndices);
                    break;

                case "normal":
                    if (!(input.source is ColladaDocument.Source))
                    {
                        throw new Exception("NORMAL source should be of type ColladaDocument.Vertices");
                    }
                    var nsource = (ColladaDocument.Source)input.source;
                    // set up indices
                    for (int i = 0; i < indlen; i++)
                    {
                        normalIndices[i] = p.p[i * p.stride + input.offset];
                    }
                    // load data
                    normalData = ParseNormalData(data[nsource.id]);
                    break;

                case "texcoord":
                    if (!(input.source is ColladaDocument.Source))
                    {
                        throw new Exception("TEXCOORD source should be of type ColladaDocument.Vertices");
                    }
                    var tsource = (ColladaDocument.Source)input.source;
                    // set up indices
                    for (int i = 0; i < indlen; i++)
                    {
                        texcoordIndices[i] = p.p[i * p.stride + input.offset];
                    }
                    // load data
                    texcoordData = ParseTexcoordData(data[tsource.id], tsource.accessor.stride);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }


            if (vertexIndices.Length != normalIndices.Length || normalIndices.Length != texcoordIndices.Length)
            {
                throw new NotImplementedException("all of them needs to be supplied and of the same amount right now");
            }

            mesh.VertexData    = new List <Vector3>(vertexData);
            mesh.VertexIndices = new List <int>(vertexIndices);

            if (normalData != null)
            {
                mesh.NormalData    = new List <Vector3>(normalData);
                mesh.NormalIndices = new List <int>(normalIndices);
            }

            if (texcoordData != null)
            {
                mesh.TexcoordData    = new List <Vector3>(texcoordData);
                mesh.TexcoordIndices = new List <int>(texcoordIndices);
            }

            return(mesh);
        }
示例#10
0
        private void LoadMesh(SkinnedMesh mesh, ColladaMesh colladaMesh, ColladaMesh.PrimitiveList primitives, Matrix objectMatrix)
        {
            //EDIT: the vertices now include the objectmatrix, so this is always identity
            objectMatrix      = colladaMesh.objectMatrix;
            mesh.Shader.World = Matrix.Identity;

            mesh.Primitives = new Primitives();

            mesh.Primitives.PrimitiveCount = primitives.PrimitiveCount;
            mesh.Primitives.VertexCount    = primitives.PrimitiveCount * 3;

            if (primitives.PrimitiveCount * 3 >= int.MaxValue)
            {
                throw new Exception("Too many vertices");
            }
            int numVertices = primitives.PrimitiveCount * 3;



            // TODO check if all inputs are available

            /*if ( meshPart.ContainsInput( ColladaMesh.Input.InputSemantics.Position ) ) positions = new Vector3[ numVertices ];
             * if ( meshPart.ContainsInput( ColladaMesh.Input.InputSemantics.Normal ) ) normals = new Vector3[ numVertices ];
             * if ( meshPart.ContainsInput( ColladaMesh.Input.InputSemantics.Texcoord, 1 ) ) texCoords = new Vector3[ numVertices ];
             * if ( meshPart.ContainsInput( ColladaMesh.Input.InputSemantics.TexTangent, 1 ) ) tangents = new Vector3[ numVertices ];*/


            SkinnedTangentVertex[] vertices = new SkinnedTangentVertex[numVertices];

            for (int i = 0; i < numVertices; i++)
            {
                SkinnedTangentVertex v = new SkinnedTangentVertex();
                v.pos    = primitives.GetVector3(ColladaMesh.Input.InputSemantics.Position, i); //GetPosition( i );
                v.normal = primitives.GetVector3(ColladaMesh.Input.InputSemantics.Normal, i);


                // Texture Coordinates
                Vector3 texcoord = Vector3.Zero;
                if (primitives.ContainsInput(ColladaMesh.Input.InputSemantics.Texcoord, 1))
                {
                    texcoord   = primitives.GetVector3(ColladaMesh.Input.InputSemantics.Texcoord, 1, i);
                    texcoord.Y = 1.0f - texcoord.Y; // V coordinate is inverted in max
                }
                v.uv = new Vector2(texcoord.X, texcoord.Y);

                // Tangent
                Vector3 tangent = Vector3.Zero;
                if (primitives.ContainsInput(ColladaMesh.Input.InputSemantics.TexTangent, 1))
                {
                    v.tangent = primitives.GetVector3(ColladaMesh.Input.InputSemantics.TexTangent, 1, i);
                }


                // Bone weights and joint indices

                int positionIndex = primitives.GetSourceIndex(
                    primitives.GetInput(ColladaMesh.Input.InputSemantics.Position), i);

                // WARNING: THIS IS EXTREMELY IMPORTANT AND COSTED MORE THAN 6 HOURS DEBUGGING
                //    Indexes are PREMULTIPLIED BY 3!!!
                v.blendIndices = colladaMesh.vertexSkinJoints[positionIndex];
                //v.blendIndices = Vector3.One;
                v.blendIndices = v.blendIndices * 3;
                v.blendWeights = colladaMesh.vertexSkinWeights[positionIndex];

                v.pos    = Vector3.Transform(v.pos, objectMatrix);
                v.normal = Vector3.Transform(v.normal, objectMatrix);

                vertices[i] = v;
            }

            //vertices[ 0 ].pos = Vector3.Transform( Vector3.Zero, Matrix.Invert( objectMatrix ) );
            //vertices[ 0 ].pos = Vector3.Zero;

            mesh.Primitives.InitializeFromVertices(skinnedModel.Game, vertices, SkinnedTangentVertex.SizeInBytes);

            //CalculateBoundingBox();
            //CalculateBoundingSphere();


            //TODO: Material, maybe not really a good way of doing this
            //LoadDataFromColladaMaterial( meshPart.Material );
        }
        private static ColladaMesh ExtractColladaGeometry(ColladaDocument.Geometry g)
        {
            ColladaMesh mesh = new ColladaMesh();
            var m = g.mesh;
            Vector3[] vertexData = null;
            Vector3[] normalData = null;
            Vector3[] texcoordData = null;

            if (m.primitives.Count != 1)
                throw new NotImplementedException("m.primitives.Count = " + m.primitives.Count);
            var p = m.primitives[0];

            Dictionary<string, float[]> data = new Dictionary<string, float[]>();
            for (int i = 0; i < m.sources.Count; i++)
            {
                ColladaDocument.Array<float> inputArr = (ColladaDocument.Array<float>)m.sources[i].array;
                if (data.ContainsKey(m.sources[i].id))
                    throw new Exception("A data entry called " + m.sources[i].id + " has already been parsed.");
                data[m.sources[i].id] = inputArr.arr;
            }

            int indlen = p.p.Length / p.stride;
            int[] vertexIndices = new int[indlen];
            int[] normalIndices = new int[indlen];
            int[] texcoordIndices = new int[indlen];
            foreach (ColladaDocument.Input input in p.Inputs)
            {
                switch (input.semantic.ToLower())
                {
                    case "vertex":
                        if (!(input.source is ColladaDocument.Vertices))
                            throw new Exception("VERTEX source should be of type ColladaDocument.Vertices");
                        ProcessVertex((ColladaDocument.Vertices)input.source, p.p, p.stride, input.offset, data,
                            ref vertexData, ref vertexIndices, ref normalData, ref normalIndices, ref texcoordData, ref texcoordIndices);
                        break;
                    case "normal":
                        if (!(input.source is ColladaDocument.Source))
                            throw new Exception("NORMAL source should be of type ColladaDocument.Vertices");
                        var nsource = (ColladaDocument.Source)input.source;
                        // set up indices
                        for (int i = 0; i < indlen; i++)
                            normalIndices[i] = p.p[i * p.stride + input.offset];
                        // load data
                        normalData = ParseNormalData(data[nsource.id]);
                        break;
                    case "texcoord":
                        if (!(input.source is ColladaDocument.Source))
                            throw new Exception("TEXCOORD source should be of type ColladaDocument.Vertices");
                        var tsource = (ColladaDocument.Source)input.source;
                        // set up indices
                        for (int i = 0; i < indlen; i++)
                            texcoordIndices[i] = p.p[i * p.stride + input.offset];
                        // load data
                        texcoordData = ParseTexcoordData(data[tsource.id], tsource.accessor.stride);
                        break;
                    default:
                        throw new NotImplementedException();
                }
            }

            if (vertexIndices.Length != normalIndices.Length || normalIndices.Length != texcoordIndices.Length)
                throw new NotImplementedException("all of them needs to be supplied and of the same amount right now");

            mesh.VertexData = new List<Vector3>(vertexData);
            mesh.VertexIndices = new List<int>(vertexIndices);

            if (normalData != null)
            {
                mesh.NormalData = new List<Vector3>(normalData);
                mesh.NormalIndices = new List<int>(normalIndices);
            }

            if (texcoordData != null)
            {
                mesh.TexcoordData = new List<Vector3>(texcoordData);
                mesh.TexcoordIndices = new List<int>(texcoordIndices);
            }

            return mesh;
        }
            public void AppendMesh(ColladaMesh mesh, Matrix worldMatrix)
            {
                Matrix normalMatrix = Matrix.Transpose(Matrix.Invert(worldMatrix));

                int vertexCount = VertexData.Count;
                int normalCount = NormalData.Count;
                int texcoordCount = TexcoordData.Count;

                foreach (Vector3 v in mesh.VertexData)
                    VertexData.Add(VectorTransform(v, worldMatrix));
                foreach (Vector3 v in mesh.NormalData)
                    NormalData.Add(Vector3.Normalize(VectorTransform(v, normalMatrix)));
                TexcoordData.AddRange(mesh.TexcoordData);

                foreach (int index in mesh.VertexIndices)
                    VertexIndices.Add(vertexCount + index);

                foreach (int index in mesh.NormalIndices)
                    NormalIndices.Add(normalCount + index);

                foreach (int index in mesh.TexcoordIndices)
                    TexcoordIndices.Add(texcoordCount + index);
            }
        private static void HandleNode(Dictionary<string, ColladaMesh> geometryMeshes, ref ColladaMesh resultMesh, ColladaDocument.Node node, Matrix world)
        {
            if(node.transforms != null)
                world = ConcatTransforms(node.transforms, world);

            if (node.instances != null)
            {
                if (node.instances.Count != 1)
                    throw new Exception("Nodes need to have exactly one instance right now");

                if (!(node.instances[0] is ColladaDocument.InstanceGeometry))
                    return;     // SILENT FAIL

                ColladaDocument.Instance i = node.instances[0];
                ColladaMesh mesh = geometryMeshes[i.url.Fragment];
                resultMesh.AppendMesh(mesh, world);
                if (node.children != null && node.children.Count > 0)
                    throw new Exception("Tell Joakim.");
            }
            else if (node.children != null && node.children.Count > 0)
            {
                foreach (ColladaDocument.Node n in node.children)
                    HandleNode(geometryMeshes, ref resultMesh, n, world);
            }
            else
            {
                //throw new Exception("Node has no instance and no child. Keh?");
            }
        }