예제 #1
0
        /// <summary>
        /// Parses a vertex found in a polygon's vertex list. Parses texture and
        /// lightmap coordinates based on the polygon's material type.
        /// </summary>
        /// <param name="xmlNode">Xml Poly node</param>
        /// <param name="dxsPrim">Dxs Primitive this Poly belongs to</param>
        /// <param name="dxsPoly">Dxs Poly the vertex belongs to</param>
        private void ParseVertex(XmlNode xmlNode, DxsPrimitive dxsPrim, DxsPoly dxsPoly)
        {
            //Get the vertex ID so we can look up the position info
            int vid = int.Parse(xmlNode.Attributes["vid"].Value);

            //Copy the master vertex (position + vertex color)
            DxsVertex vertex = new DxsVertex(dxsPrim.MasterVertexList[vid]);

            //Get the material of the polygon
            DxsMaterial material = dxsPrim.Materials[dxsPoly.MaterialID];

            //If the first layer is a texture, parse texture coordinates
            if (material.Layers.Count > 0 && material.Layers[0].MaterialType == MaterialType.Texture)
            {
                float u0 = float.Parse(xmlNode.Attributes["u0"].Value);
                float v0 = float.Parse(xmlNode.Attributes["v0"].Value);
                vertex.TextureCoordinate = new Vector2(u0, v0);
            }
            //If one of the layers (last one) is a lightmap, parse its texture coordinates
            for (int i = 1; i < material.Layers.Count; i++)
            {
                if (material.Layers[i].MaterialType == MaterialType.Lightmap)
                {
                    float ui = float.Parse(xmlNode.Attributes["u" + i].Value);
                    float vi = float.Parse(xmlNode.Attributes["v" + i].Value);
                    vertex.LightMapCoordinate = new Vector2(ui, vi);
                    break;
                }
            }

            //Add vertex to the poly
            dxsPoly.Vertices.Add(vertex);
        }
예제 #2
0
        /// <summary>
        /// Parses a vertex listing in a primitive node, this pertains to the
        /// position data used by the primitive - hence it being the "master list".
        /// All other data such as texture coordinates are referenced by the vertex
        /// ID's to these vertices.
        ///
        /// Also, if a vertex color is supplied it will be caught here. By default
        /// vertex colors are white, and if a single vertex color is found the
        /// dxs primitive is enabled to use vertex colors.
        /// </summary>
        /// <param name="xmlNode">Xml primitive node</param>
        /// <param name="dxsPrim">Dxs primitive</param>
        private void ParseMasterVertex(XmlNode xmlNode, DxsPrimitive dxsPrim)
        {
            //Parse attributes
            int   vid     = int.Parse(xmlNode.Attributes["id"].Value);
            float x       = float.Parse(xmlNode.Attributes["x"].Value);
            float y       = float.Parse(xmlNode.Attributes["y"].Value);
            float z       = float.Parse(xmlNode.Attributes["z"].Value);
            int   jointID = -1;// int.Parse(xmlNode.Attributes["jointID"].Value);
            //create a new dxs vertex
            DxsVertex vertex = new DxsVertex(vid, new Vector3(x, y, z), jointID);

            //See if we have a vertex color
            if (xmlNode.HasChildNodes && xmlNode.LastChild.Name.Equals("color"))
            {
                XmlNode child = xmlNode.FirstChild;
                byte    r     = byte.Parse(child.Attributes["r"].Value);
                byte    g     = byte.Parse(child.Attributes["b"].Value);
                byte    b     = byte.Parse(child.Attributes["g"].Value);
                byte    a     = byte.Parse(child.Attributes["a"].Value);
                vertex.VertexColor         = new Color(r, g, b, a);
                dxsPrim.VertexColorEnabled = true;
            }

            //Add master vertex to primitive
            dxsPrim.MasterVertexList.Add(vertex);
        }
예제 #3
0
        private void CalculateNormals(List <DxsPoly> polyList, NormalGeneration normalOptions, double creaseAngle)
        {
            if (normalOptions == NormalGeneration.None)
            {
                return;
            }

            double cosAngle = System.Math.Cos(MathHelper.DegreesToRadians * creaseAngle);

            //Loop through each polygon
            for (int i = 0; i < polyList.Count; i++)
            {
                DxsPoly poly = polyList[i];
                //For each vertex
                for (int j = 0; j < 3; j++)
                {
                    DxsVertex vert = poly.Vertices[j];
                    int       vid  = vert.ID;

                    Vector3 smoothNormal = poly.FaceNormal;
                    if (normalOptions != NormalGeneration.Face)
                    {
                        //Find every poly that shares this vertex
                        for (int k = 0; k < polyList.Count; k++)
                        {
                            if (i != k)
                            {
                                DxsPoly otherPoly = polyList[k];
                                for (int m = 0; m < 3; m++)
                                {
                                    DxsVertex otherVertex = otherPoly.Vertices[m];
                                    int       otherVid    = otherVertex.ID;
                                    //Other poly uses this vertex position, then take their normal into account
                                    if (vid == otherVid)
                                    {
                                        if (normalOptions == NormalGeneration.Crease)
                                        {
                                            if (Vector3.Dot(poly.FaceNormal, otherPoly.FaceNormal) > cosAngle)
                                            {
                                                smoothNormal += otherPoly.FaceNormal;
                                            }
                                        }
                                        else
                                        {
                                            smoothNormal += otherPoly.FaceNormal;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    smoothNormal.Normalize();
                    vert.Normal      = smoothNormal;
                    poly.Vertices[j] = vert;
                }
            }
        }
예제 #4
0
 public DxsVertex(DxsVertex vertex)
 {
     ID                 = vertex.ID;
     Position           = vertex.Position;
     Normal             = vertex.Normal;
     TextureCoordinate  = vertex.TextureCoordinate;
     LightMapCoordinate = vertex.LightMapCoordinate;
     VertexColor        = vertex.VertexColor;
     JointID            = vertex.JointID;
 }
예제 #5
0
        private bool VertexEquals(ref DxsVertex a, ref DxsVertex b)
        {
            Vector2 aTex    = a.TextureCoordinate;
            Vector2 bTex    = b.TextureCoordinate;
            Vector2 aLight  = a.LightMapCoordinate;
            Vector2 bLight  = b.LightMapCoordinate;
            Vector3 aNormal = a.Normal;
            Vector3 bNormal = b.Normal;

            return(Vector2Equals(ref aTex, ref bTex) && Vector2Equals(ref aLight, ref bLight) && Vector3Equals(ref aNormal, ref bNormal));
        }
예제 #6
0
        /// <summary>
        /// Uses the first vertex in a polygon as a pivot to triangulate the polygon,
        /// which get added to the dxs primitive.
        /// </summary>
        /// <param name="dxsPrim">Dxs Primitive the poly belongs to</param>
        /// <param name="dxsPoly">Dxs Poly to be triangulated</param>
        private void TriangulatePolygon(DxsPrimitive dxsPrim, DxsPoly dxsPoly)
        {
            DxsVertex[] vertices = dxsPoly.Vertices.ToArray();
            DxsVertex   v0       = vertices[0];

            //Use the first vertex as a pivot and create triangles.
            for (int v = 1; v < vertices.Length - 1; v++)
            {
                DxsPoly poly = new DxsPoly(dxsPoly.MaterialID);
                poly.Vertices.Add(v0);
                poly.Vertices.Add(vertices[v]);
                poly.Vertices.Add(vertices[v + 1]);
                poly.ComputeFaceNormal();
                dxsPrim.AddPoly(poly);
            }
        }
예제 #7
0
        public DxsMesh(List <DxsPoly> polyList, NormalGeneration normalOptions, double creaseAngle, bool swapWinding)
        {
            _matID    = polyList[0].MaterialID;
            _indices  = new DataBuffer <int>(polyList.Count * 3);
            _vertList = new List <DxsVertex>();

            if (swapWinding)
            {
                foreach (DxsPoly poly in polyList)
                {
                    DxsVertex temp = poly.Vertices[0];
                    poly.Vertices[0] = poly.Vertices[2];
                    poly.Vertices[2] = temp;
                }
            }

            CalculateNormals(polyList, normalOptions, creaseAngle);


            //Get all the unique vertices and build the index list
            foreach (DxsPoly poly in polyList)
            {
                for (int i = 0; i < 3; i++)
                {
                    DxsVertex vertex = poly.Vertices[i];
                    int       index;
                    if (IsUniqueVertex(_vertList, vertex, out index))
                    {
                        _vertList.Add(vertex);
                        index = _vertList.Count - 1;
                    }
                    _indices.Set(index);
                }
            }

            Vector3 center = GetCenter();

            for (int i = 0; i < _vertList.Count; i++)
            {
                DxsVertex v = _vertList[i];
                v.Position   = v.Position - center;
                _vertList[i] = v;
            }
            _translation = center;
        }
예제 #8
0
        private bool IsUniqueVertex(List <DxsVertex> list, DxsVertex vertex, out int index)
        {
            bool isUnique = true;

            index = -1;
            for (int i = 0; i < list.Count; i++)
            {
                DxsVertex test = list[i];
                if (test.ID == vertex.ID)
                {
                    if (VertexEquals(ref vertex, ref test))
                    {
                        isUnique = false;
                        index    = i;
                        break;
                    }
                }
            }
            return(isUnique);
        }