Example #1
0
        private void ConvertMesh(XElement meshElement, XElement triangles, ref AMT_MODEL amtModel)
        {
            //pega o mesh atual
            uint meshID = (uint)amtModel.Meshes.Count - 1;
            AMT_MESH mesh = amtModel.Meshes[amtModel.Meshes.Count - 1];

            //ja armazena o numero de faces do mesh
            mesh.NumFaces = int.Parse(triangles.Attribute("count").Value);

            //pega os inputs vertex, normal, texcoord etc
            List<XElement> inputs = triangles.Elements(XName.Get("input", Namespace)).ToList();
            XElement vertex = inputs.Find(item => { return item.Attribute("semantic").Value == "VERTEX"; });
            XElement normal = inputs.Find(item => { return item.Attribute("semantic").Value == "NORMAL"; });
            XElement texcoord = inputs.Find(item => { return item.Attribute("semantic").Value == "TEXCOORD"; });

            //elementos que tem na tag vertices, procurar o id = vertex.source
            List<XElement> verticesElements = meshElement.Elements(XName.Get("vertices", Namespace)).ToList();
            XElement verticeElement = verticesElements.Find(item => { return item.Attribute("id").Value == vertex.Attribute("source").Value.Substring(1); });
            //agora com o vertice certo pega o position
            List<XElement> inputsVerticesElement = verticeElement.Elements(XName.Get("input", Namespace)).ToList();
            XElement position = inputsVerticesElement.Find(item => { return item.Attribute("semantic").Value == "POSITION"; });

            //agora é so carregar os dados dos sources conforme os id dos inputs position, normal, texcoord
            List<XElement> sources = meshElement.Elements(XName.Get("source", Namespace)).ToList();
            XElement sourcePosition = sources.Find(item => { return item.Attribute("id").Value == position.Attribute("source").Value.Substring(1); });
            XElement sourceNormal = sources.Find(item => { return item.Attribute("id").Value == normal.Attribute("source").Value.Substring(1); });
            XElement sourceTexcoord = sources.Find(item => { return item.Attribute("id").Value == texcoord.Attribute("source").Value.Substring(1); });

            //pega os indices e junta tudo em um unico string
            List<XElement> ps = triangles.Elements(XName.Get("p", Namespace)).ToList();
            string indices = null;
            foreach (var item in ps)
                indices += ' ' + item.Value;
            //separa todos os indices usando os offsets
            string[] strIndices = indices.Replace('\n', ' ').Trim().Split(' ');
            List<int> positionIndices = new List<int>();
            int positionOffset = int.Parse(vertex.Attribute("offset").Value);
            List<int> normalIndices = new List<int>();
            int normalOffset = int.Parse(normal.Attribute("offset").Value);
            List<int> texcoordIndices = new List<int>();
            int texcoordOffset = int.Parse(texcoord.Attribute("offset").Value);

            for (int i = 0; i < strIndices.Length; i += sources.Count)
            {
                positionIndices.Add(int.Parse(strIndices[i + positionOffset]));
                normalIndices.Add(int.Parse(strIndices[i + normalOffset]));
                texcoordIndices.Add(int.Parse(strIndices[i + texcoordOffset]));
            }
            //vertices reais
            List<Vector3> positions = GetPositions(sourcePosition);
            List<Vector3> normals = GetNormals(sourceNormal);
            List<Vector2> texcoords = GetTexCoords(sourceTexcoord);

            //agora é so pegar os indices e vincular com os arrays pra criar os vertices q vao para o amt
            for (int i = 0; i < positionIndices.Count; i++)
            {
                AMT_VERTEX v = new AMT_VERTEX();
                v.SID = positionIndices[i]; //utilizado para encontrar esses vertices depois quando for atualizar o peso dos bones
                v.Position = positions[positionIndices[i]];
                v.Normal = normals[normalIndices[i]];
                v.TexCoord1 = texcoords[texcoordIndices[i]];
                v.TexCoord1.Y = -v.TexCoord1.Y; //Inverto o Y pq o exportador do max usa as coordenadas do opengl

                amtModel.Vertices.Add(v);
            }

            //carrega as faces
            for (int i = 0; i < amtModel.Vertices.Count; i += 3)
            {
                AMT_FACE f = new AMT_FACE();
                f.MeshID = meshID;
                f.Indices = new List<int>();
                f.Indices.Add(i);
                f.Indices.Add(i + 1);
                f.Indices.Add(i + 2);
                f.Normal = Tools.GetNormal(amtModel.Vertices[i].Position, amtModel.Vertices[i + 1].Position, amtModel.Vertices[i + 2].Position);

                amtModel.Faces.Add(f);

                mesh.FaceIndices.Add(amtModel.Faces.Count - 1);
            }

            //finalmente seta o mesh atual
            amtModel.Meshes[amtModel.Meshes.Count - 1] = mesh;
        }
Example #2
0
        public static bool EqualsWithoutFlagTest(AMT_VERTEX v1, AMT_VERTEX v2)
        {
            if ((v1.BoneIndices == null && v2.BoneIndices != null ||
                 v1.BoneIndices != null && v2.BoneIndices == null) ||
                (v1.BoneWeights == null && v2.BoneWeights != null ||
                 v1.BoneWeights != null && v2.BoneWeights == null))
                return true;

            if (v1.BoneIndices != null && v1.BoneWeights != null)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (v1.BoneIndices[i] != v2.BoneIndices[i] ||
                        v1.BoneWeights[i] != v2.BoneWeights[i])
                        return false;
                }
            }

            if (v1.Position != v2.Position ||
                v1.TexCoord1 != v2.TexCoord1 ||
                v1.TexCoord2 != v2.TexCoord2 ||
                v1.Normal != v2.Normal)
                return false;

            return true;
        }