protected static void AddTriangleFace(Polygon polygon, Material material, int verticesCount, params int[] verticeOffsets)
 {
     var face = new Face();
     if (material != null)
         face.Material = material;
     foreach (var verticeOffset in verticeOffsets)
         face.Indices.Add(new Index(verticesCount - verticeOffset, 0));
     polygon.Faces.Add(face);
 }
Пример #2
0
 /// <summary>
 /// Build cubic <see cref="Polygon" />.
 /// </summary>
 /// <param name="height"></param>
 /// <returns>The <see cref="Polygon" /> with cubic geometry.</returns>
 public static Polygon Create(float height)
 {
     var hh = height/2;
     var polygon = new Polygon();
     polygon.UVs.AddRange(new[]
     {
         new UV(0, 0),
         new UV(0, 1),
         new UV(1, 1),
         new UV(1, 0)
     });
     polygon.Vertices.AddRange(new[]
     {
         new Vertex(-hh, -hh, -hh),
         new Vertex(hh, -hh, -hh),
         new Vertex(hh, -hh, hh),
         new Vertex(-hh, -hh, hh),
         new Vertex(-hh, hh, -hh),
         new Vertex(hh, hh, -hh),
         new Vertex(hh, hh, hh),
         new Vertex(-hh, hh, hh)
     });
     var face = new Face(); // The bottom face
     face.Indices.AddRange(CreateIndices(1, 2, 3, 0));
     polygon.Faces.Add(face);
     face = new Face(); // The top face
     face.Indices.AddRange(CreateIndices(7, 6, 5, 4));
     polygon.Faces.Add(face);
     face = new Face(); // The right face
     face.Indices.AddRange(CreateIndices(5, 6, 2, 1));
     polygon.Faces.Add(face);
     face = new Face(); // The left face
     face.Indices.AddRange(CreateIndices(7, 4, 0, 3));
     polygon.Faces.Add(face);
     face = new Face(); // The front face
     face.Indices.AddRange(CreateIndices(4, 5, 1, 0));
     polygon.Faces.Add(face);
     face = new Face(); // The back face
     face.Indices.AddRange(CreateIndices(6, 7, 3, 2));
     polygon.Faces.Add(face);
     return polygon;
 }
Пример #3
0
        public override void ReadData(Scene scene, BinaryReader stream)
        {
            //	Note: A max face is three indices and
            //	a flag short.

            //	Read number of faces.
            short faceCount = 0;
            faceCount = stream.ReadInt16();

            //	Read each face and add it.
            for(short i = 0; i < faceCount; i++)
            {
                Face f = new Face();
                Index index = new Index(stream.ReadInt16());
                f.Indices.Add(index);
                index = new Index(stream.ReadInt16());
                f.Indices.Add(index);
                index = new Index(stream.ReadInt16());
                f.Indices.Add(index);
                stream.ReadInt16();
                faces.Add(f);
            }
        }
 private static void AddIndexesToFace(IEnumerable<string> indices, Face face)
 {
     foreach (var parts in indices.Select(index => index.Split(new[] {'/'}, StringSplitOptions.None)))
     {
         //  Add each part.
         face.Indices.Add(new Index(
             (parts.Length > 0 && parts[0].Length > 0) ? int.Parse(parts[0]) - 1 : -1,
             (parts.Length > 1 && parts[1].Length > 0) ? int.Parse(parts[1]) - 1 : -1,
             (parts.Length > 2 && parts[2].Length > 0) ? int.Parse(parts[2]) - 1 : -1));
     }
 }
        private static void AddFace(ISceneEngine sceneEngine, Polygon polygon, string mtlName, string line, char[] split)
        {
            var face = new Face();

            if (!string.IsNullOrWhiteSpace(mtlName))
                face.Material = sceneEngine.GetAssets<Material>().FirstOrDefault(t => t.Name == mtlName);

            //  Get the face indices
            string[] indices = line.Substring(2).Split(split, StringSplitOptions.RemoveEmptyEntries);

            //  Add each index.
            AddIndexesToFace(indices, face);

            //  Add the face.
            polygon.Faces.Add(face);
        }
Пример #6
0
        /// <summary>
        /// This function reads a polygon.
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        protected override object ReadData(BinaryReader reader)
        {
            //	Create a polygon.
            Polygon poly = new Polygon();

            //	Read a name chunk.
            CaligariName name = new CaligariName();
            name.Read(reader);
            poly.Name = name.name;

            //	Read the local axies.
            CaligariAxies axies = new CaligariAxies();
            axies.Read(reader);
            poly.Translate = axies.centre;
            //	poly.Rotate = axies.rotate;

            //	Read the position matrix.
            CaligariPosition pos = new CaligariPosition();
            pos.Read(reader);

            //	Read number of verticies.
            int verticesCount = reader.ReadInt32();

            //	Get them all
            for(int i=0; i<verticesCount; i++)
            {
                //	Read a vertex.
                Vertex vertex = new Vertex(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                //	Multiply it by the position matrix.
                vertex = vertex * pos.matrix;

                //	Add it.
                poly.Vertices.Add(vertex);
            }

            //	Read UV count.
            int uvsCount = reader.ReadInt32();

            //	Read all of the UVs
            for(int i=0; i<uvsCount; i++)
                poly.UVs.Add(new UV(reader.ReadInt32(), reader.ReadInt32()));

            //	Read faces count.
            int faces = reader.ReadInt32();

            //	Read each face.
            for(int f= 0; f<faces; f++)
            {
                Face face = new Face();
                poly.Faces.Add(face);

                //	Read face type flags.
                byte flags = reader.ReadByte();

                //	Read vertex count
                short verticesInFace = reader.ReadInt16();

                //	Do we read a material number?
                if((flags&0x08) == 0)	//	is it a 'hole' face?
                    reader.ReadInt16();

                //	Now read the indices, a vertex index and a uv index.
                for(short j=0; j<verticesInFace; j++)
                    face.Indices.Add(new Index(reader.ReadInt32(), reader.ReadInt32()));
            }

            //	Any extra stuff?
            if(header.minorVersion > 4)
            {
                //	read flags.
                reader.ReadChars(4);

                if((header.minorVersion > 5) && (header.minorVersion < 8))
                    reader.ReadChars(2);
            }

            //	Now that we've loaded the polygon, we triangulate it.
            poly.Triangulate();

            //	Finally, we update normals.
            poly.Validate(true);

            return poly;
        }
Пример #7
0
        public Scene LoadData(string path)
        {
            char[] split = new char[] { ' ' };

            //  Create a scene and polygon.
            Scene scene = new Scene();
            Polygon polygon = new Polygon();

            string mtlName = null;

            //  Create a stream reader.
            using (StreamReader reader = new StreamReader(path))
            {
                //  Read line by line.
                string line = null;
                while ((line = reader.ReadLine()) != null)
                {
                    //  Skip any comments (lines that start with '#').
                    if (line.StartsWith("#"))
                        continue;

                    //  Do we have a texture coordinate?
                    if (line.StartsWith("vt"))
                    {
                        //  Get the texture coord strings.
                        string[] values = line.Substring(3).Split(split, StringSplitOptions.RemoveEmptyEntries);
                        float x = float.Parse(values[0]);
                        float y = float.Parse(values[1]);
                        
                        //  Parse texture coordinates.
                        float u = float.Parse(values[0]);
                        float v = float.Parse(values[1]);

                        //  Add the texture coordinate.
                        polygon.UVs.Add(new UV(u, v));

                        continue;
                    }

                    //  Do we have a normal coordinate?
                    if (line.StartsWith("vn"))
                    {
                        //  Get the normal coord strings.
                        string[] values = line.Substring(3).Split(split, StringSplitOptions.RemoveEmptyEntries);
                        values[0] = values[0].Replace(".", ",");
                        values[1] = values[1].Replace(".", ",");
                        values[2] = values[2].Replace(".", ",");

                        //  Parse normal coordinates.
                        float x = float.Parse(values[0]);
                        float y = float.Parse(values[1]);
                        float z = float.Parse(values[2]);

                        //  Add the normal.
                        polygon.Normals.Add(new Vertex(x, y, z));

                        continue;
                    }

                    //  Do we have a vertex?
                    if (line.StartsWith("v"))
                    {
                        //  Get the vertex coord strings.
                        string[] values = line.Substring(2).Split(split, StringSplitOptions.RemoveEmptyEntries);
                        values[0] = values[0].Replace(".", ",");
                        values[1] = values[1].Replace(".", ",");
                        values[2] = values[2].Replace(".", ",");

                        //  Parse vertex coordinates.
                        float x = float.Parse(values[0]);
                        float y = float.Parse(values[1]);
                        float z = float.Parse(values[2]);

                        //   Add the vertices.
                        polygon.Vertices.Add(new Vertex(x, y, z));

                        continue;
                    }

                    //  Do we have a face?
                    if (line.StartsWith("f"))
                    {
                        Face face = new Face();

                        if (!String.IsNullOrWhiteSpace(mtlName))
                            face.Material = scene.Assets.Where(t => t.Name == mtlName).FirstOrDefault() as Material;

                        //  Get the face indices
                        string[] indices = line.Substring(2).Split(split,
                            StringSplitOptions.RemoveEmptyEntries);

                        //  Add each index.
                        foreach (var index in indices)
                        {
                            //  Split the parts.
                            string[] parts = index.Split(new char[] { '/' }, StringSplitOptions.None);

                            //  Add each part.
                            face.Indices.Add(new Index(
                                (parts.Length > 0 && parts[0].Length > 0) ? int.Parse(parts[0]) - 1 : -1,
                                (parts.Length > 1 && parts[1].Length > 0) ? int.Parse(parts[1]) - 1 : -1,
                                (parts.Length > 2 && parts[2].Length > 0) ? int.Parse(parts[2]) - 1 : -1));
                        }



                        //  Add the face.
                        polygon.Faces.Add(face);

                        continue;
                    }

                    if (line.StartsWith("mtllib"))
                    {
                        // Set current directory in case a relative path to material file is used.
                        Environment.CurrentDirectory = Path.GetDirectoryName(path);

                        // Load materials file.
                        string mtlPath = ReadMaterialValue(line);
                        LoadMaterials(mtlPath, scene);
                    }

                    if (line.StartsWith("usemtl"))
                        mtlName = ReadMaterialValue(line);
                }
            }

            scene.SceneContainer.AddChild(polygon);

            return scene;
        }
Пример #8
0
        protected override object LoadData(Stream stream)
        {
            //	We use a binary reader for this data.
            BinaryReader reader = new BinaryReader(stream, System.Text.Encoding.ASCII);

            //	Create a polygon.
            Polygon poly = new Polygon();

            //	Read the translate, scale, rotate.
            poly.Translate.X = reader.ReadSingle();
            poly.Translate.Y = reader.ReadSingle();
            poly.Translate.Z = reader.ReadSingle();
            poly.Scale.X = reader.ReadSingle();
            poly.Scale.Y = reader.ReadSingle();
            poly.Scale.Z = reader.ReadSingle();
            poly.Rotate.X = reader.ReadSingle();
            poly.Rotate.Y = reader.ReadSingle();
            poly.Rotate.Z = reader.ReadSingle();

            //	Read number of verticies.
            int verticesCount = reader.ReadInt32();

            //	Get them all
            for(int i=0; i<verticesCount; i++)
            {
                //	Read a vertex.
                Vertex vertex = new Vertex(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                //	Add it.
                poly.Vertices.Add(vertex);
            }

            //	Read UV count.
            int uvsCount = reader.ReadInt32();

            //	Read all of the UVs
            for(int i=0; i<uvsCount; i++)
                poly.UVs.Add(new UV(reader.ReadInt32(), reader.ReadInt32()));

            //	Read faces count.
            int faces = reader.ReadInt32();

            //	Read each face.
            for(int f= 0; f<faces; f++)
            {
                Face face = new Face();
                poly.Faces.Add(face);

                //	Read index count
                int indices = reader.ReadInt32();

                //	Now read the indices, a vertex index and a uv index and a color index.
                for(int j=0; j<indices; j++)
                {
                    face.Indices.Add(new Index(reader.ReadInt32(), reader.ReadInt32()));
                    int colour = reader.ReadInt32(); //not used.
                }
            }

            //	Finally, we update normals.
            poly.Validate(true);

            return poly;
        }
Пример #9
0
        public Scene LoadData(string path)
        { 
            char[] split = new char[] { ' '};

            //  Create a scene and polygon.
            Scene scene = new Scene();
            Polygon polygon = new Polygon();

            //  Create a stream reader.
            using (StreamReader reader = new StreamReader(path))
            {
                //  Read line by line.
                string line = null;
                while( (line = reader.ReadLine()) != null)
                {
                    //  Skip any comments (lines that start with '#').
                    if (line.StartsWith("#"))
                      continue;

                    //  Do we have a texture coordinate?
                    if (line.StartsWith("vt"))
                    {
                      //  Get the texture coord strings.
                      string[] values = line.Substring(3).Split(split, StringSplitOptions.RemoveEmptyEntries);

                      //  Parse texture coordinates.
                      float u = float.Parse(values[0]);
                      float v = float.Parse(values[1]);

                        //  Add the texture coordinate.
                        polygon.UVs.Add(new UV(u, v));

                      continue;
                    }

                    //  Do we have a normal coordinate?
                    if (line.StartsWith("vn"))
                    {
                        //  Get the normal coord strings.
                        string[] values = line.Substring(3).Split(split, StringSplitOptions.RemoveEmptyEntries);

                        //  Parse normal coordinates.
                        float x = float.Parse(values[0]);
                        float y = float.Parse(values[1]);
                        float z = float.Parse(values[2]);

                        //  Add the normal.
                        polygon.Normals.Add(new Vertex(x, y, z));

                        continue;
                    }

                    //  Do we have a vertex?
                    if (line.StartsWith("v"))
                    {
                        //  Get the vertex coord strings.
                        string[] values = line.Substring(2).Split(split, StringSplitOptions.RemoveEmptyEntries);

                        //  Parse vertex coordinates.
                        float x = float.Parse(values[0]);
                        float y = float.Parse(values[1]);
                        float z = float.Parse(values[2]);

                        //   Add the vertices.
                        polygon.Vertices.Add(new Vertex(x, y, z));

                        continue;
                    }
                    
                    //  Do we have a face?
                    if (line.StartsWith("f"))
                    {
                        Face face = new Face();

                        //  Get the face indices
                        string[] indices = line.Substring(2).Split(split,
                            StringSplitOptions.RemoveEmptyEntries);

                        //  Add each index.
                        foreach (var index in indices)
                        {
                            //  Split the parts.
                            string[] parts = index.Split(new char[] {'/'}, StringSplitOptions.None);

                            //  Add each part.
                            face.Indices.Add(new Index(
                                (parts.Length > 0 && parts[0].Length > 0) ? int.Parse(parts[0]) - 1 : -1,
                                (parts.Length > 1 && parts[1].Length > 0) ? int.Parse(parts[1]) - 1 : -1,
                                (parts.Length > 2 && parts[2].Length > 0) ? int.Parse(parts[2]) - 1: -1));
                        }

                        //  Add the face.
                        polygon.Faces.Add(face);

                        continue;
                    }
       
                    if (line.StartsWith("mtllib"))
                        continue;

                    if (line.StartsWith("usemtl"))
                        continue;
                }
            }

            scene.SceneContainer.AddChild(polygon);

            return scene;
        }
Пример #10
0
        /// <summary>
        /// Triangulate this polygon.
        /// </summary>
        public void Triangulate()
        {
            FaceCollection newFaces = new FaceCollection();

            //	Go through each face...
            foreach(Face face in faces)
            {
                //	Number of triangles = vertices - 2.
                int triangles = face.Indices.Count - 2;

                //	Is it a triangle already?...
                if(triangles == 1)
                {
                    newFaces.Add(face);
                    continue;
                }

                //	Add a set of triangles.
                for(int i=0; i<triangles; i++)
                {
                    Face triangle = new Face();
                    triangle.Indices.Add(new Index(face.Indices[0]));
                    triangle.Indices.Add(new Index(face.Indices[i+1]));
                    triangle.Indices.Add(new Index(face.Indices[i+2]));
                    triangle.Indices.Add(new Index(face.Indices[i+2]));
                    triangle.Indices.Add(new Index(face.Indices[i+1]));
                    newFaces.Add(triangle);
                }
            }

            faces.Clear();
            faces = newFaces;
        }
Пример #11
0
        /// <summary>
        /// This function subdivides the faces of this polygon.
        /// </summary>
        /// <param name="smooth">If set to true the faces will be smoothed.</param>
        /// <returns>The number of faces in the new subdivided polygon.</returns>
        public int Subdivide()
        {
            FaceCollection newFaces = new FaceCollection();

            foreach(Face face in Faces)
            {
                //	Make sure the face is a triangle.
                if(face.Count != 3)
                    continue;

                //	Now get the vertices of the face.
                Vertex v1 = Vertices[face.Indices[0].Vertex];
                Vertex v2 = Vertices[face.Indices[1].Vertex];
                Vertex v3 = Vertices[face.Indices[2].Vertex];

                //	Add the vertices to get a the midpoint of the edge formed by those
                //	vectors.
                Vertex vMidpoint = (v1 + v2 + v3) / 3;
                Index iMidpoint = new Index(Vertices.Add(vMidpoint));

                //	Now make three new faces from the old vertices and the midpoint.
                Face newFace = new Face();
                newFace.Indices.Add(new Index(face.Indices[0]));
                newFace.Indices.Add(new Index(face.Indices[1]));
                newFace.Indices.Add(iMidpoint);
                newFaces.Add(newFace);

                newFace = new Face();
                newFace.Indices.Add(new Index(face.Indices[1]));
                newFace.Indices.Add(new Index(face.Indices[2]));
                newFace.Indices.Add(iMidpoint);
                newFaces.Add(newFace);

                newFace = new Face();
                newFace.Indices.Add(new Index(face.Indices[2]));
                newFace.Indices.Add(new Index(face.Indices[0]));
                newFace.Indices.Add(iMidpoint);
                newFaces.Add(newFace);
            }

            faces = newFaces;

            return faces.Count;
        }
Пример #12
0
        /// <summary>
        /// This creates a polygon from a height map (any picture). Black is low, 
        /// and the colors are high (the lighter the color, the higher the surface).
        /// </summary>
        /// <param name="filename">Path of the image file.</param>
        /// <param name="xPoints">Number of points along X.</param>
        /// <param name="yPoints">Number of points along Y.</param>
        /// <returns>True if sucessful, false otherwise.</returns>
        public virtual bool CreateFromMap(string filename, int xPoints, int yPoints)
        {
            //	Try and load the image file.
            System.Drawing.Bitmap map = new System.Drawing.Bitmap(filename);
            if(map.Size.IsEmpty)
                return false;

            //	Set the descriptive name.
            Name = "Map created from '" + filename + "'";

            //	Get points.
            for(int y=0; y < yPoints; y++)
            {
                int yValue = (map.Height / yPoints) * y;

                for(int x=0; x < xPoints; x++)
                {
                    int xValue = (map.Width / xPoints) * x;

                    //	Get the pixel.
                    System.Drawing.Color col = map.GetPixel(xValue, yValue);

                    float xPos = (float)x / (float)xPoints;
                    float yPos = (float)y / (float)yPoints;

                    //	Create a control point from it.
                    Vertex v = new Vertex(xPos, 0, yPos);

                    //	Add the 'height', based on color.
                    v.Y = (float)col.R / 255.0f + (float)col.G / 255.0f +
                        (float)col.B / 255.0f;

                    //	Add this vertex to the vertices array.
                    Vertices.Add(v);
                }
            }

            //	Create faces for the polygon.
            for(int y=0; y < (yPoints-1); y++)
            {
                for(int x=0; x < (xPoints-1); x++)
                {
                    //	Create the face.
                    Face face = new Face();

                    //	Create vertex indicies.
                    int nTopLeft = (y * xPoints) + x;
                    int nBottomLeft = ((y + 1) * xPoints) + x;

                    face.Indices.Add(new Index(nTopLeft));
                    face.Indices.Add(new Index(nTopLeft + 1));
                    face.Indices.Add(new Index(nBottomLeft + 1));
                    face.Indices.Add(new Index(nBottomLeft));

                    // Add the face.
                    Faces.Add(face);
                }
            }

            return true;
        }
Пример #13
0
        /// <summary>
        /// This function makes a simple cube shape.
        /// </summary>
        public void CreateCube()
        {
            uvs.Add(new UV(0, 0));
            uvs.Add(new UV(0, 1));
            uvs.Add(new UV(1, 1));
            uvs.Add(new UV(1, 0));

            //	Add the vertices.
            vertices.Add(new Vertex(-1, -1, -1));
            vertices.Add(new Vertex( 1, -1, -1));
            vertices.Add(new Vertex( 1, -1,  1));
            vertices.Add(new Vertex(-1, -1,  1));
            vertices.Add(new Vertex(-1,  1, -1));
            vertices.Add(new Vertex( 1,  1, -1));
            vertices.Add(new Vertex( 1,  1,  1));
            vertices.Add(new Vertex(-1,  1,  1));

            //	Add the faces.
            Face face = new Face();	//	bottom
            face.Indices.Add(new Index(1, 0));
            face.Indices.Add(new Index(2, 1));
            face.Indices.Add(new Index(3, 2));
            face.Indices.Add(new Index(0, 3));
            faces.Add(face);

            face = new Face();		//	top
            face.Indices.Add(new Index(7, 0));
            face.Indices.Add(new Index(6, 1));
            face.Indices.Add(new Index(5, 2));
            face.Indices.Add(new Index(4, 3));
            faces.Add(face);

            face = new Face();		//	right
            face.Indices.Add(new Index(5, 0));
            face.Indices.Add(new Index(6, 1));
            face.Indices.Add(new Index(2, 2));
            face.Indices.Add(new Index(1, 3));
            faces.Add(face);

            face = new Face();		//	left
            face.Indices.Add(new Index(7, 0));
            face.Indices.Add(new Index(4, 1));
            face.Indices.Add(new Index(0, 2));
            face.Indices.Add(new Index(3, 3));
            faces.Add(face);

            face = new Face();		// front
            face.Indices.Add(new Index(4, 0));
            face.Indices.Add(new Index(5, 1));
            face.Indices.Add(new Index(1, 2));
            face.Indices.Add(new Index(0, 3));
            faces.Add(face);

            face = new Face();		//	back
            face.Indices.Add(new Index(6, 0));
            face.Indices.Add(new Index(7, 1));
            face.Indices.Add(new Index(3, 2));
            face.Indices.Add(new Index(2, 3));
            faces.Add(face);
        }
Пример #14
0
        /// <summary>
        /// This function is cool, just stick in a set of points, it'll add them to the
        /// array, and create a face. It will take account of duplicate vertices too!
        /// </summary>
        /// <param name="vertexData">A set of vertices to make into a face.</param>
        public virtual void AddFaceFromVertexData(Vertex[] vertexData)
        {
            //	Create a face.
            Face newFace = new Face();

            //	Go through the vertices...
            foreach(Vertex v in vertexData)
            {
                //	Do we have this vertex already?
                int at = vertices.Find(0, v, 0.01f);

                //	Add the vertex, and index it.
                newFace.Indices.Add(new Index( (at == -1) ? vertices.Add(v) : at));
            }

            //	Add the face.
            faces.Add(newFace);
        }
Пример #15
0
        public PlaneBuilder()
        {
            Polygon plane = new Polygon();
            plane.Vertices.Add(new Vertex());
            plane.Vertices.Add(new Vertex());
            plane.Vertices.Add(new Vertex());
            plane.Vertices.Add(new Vertex());

            plane.UVs.Add(new UV(0, 0));
            plane.UVs.Add(new UV(0, 1));
            plane.UVs.Add(new UV(1, 1));
            plane.UVs.Add(new UV(1, 0));

            Face face = new Face();
            face.Indices.Add(new Index(2, 0));
            face.Indices.Add(new Index(3, 1));
            face.Indices.Add(new Index(1, 2));
            face.Indices.Add(new Index(0, 3));
            plane.Faces.Add(face);

            buildingObject = plane;
        }