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); }
/// <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; }
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); }
/// <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; }
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; }
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; }
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; }
/// <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; }
/// <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; }
/// <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; }
/// <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); }
/// <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); }
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; }