public Vertex(Vertex vertex) { this.position = vertex.position; this.color = vertex.color; this.texture = vertex.texture; this.normal = vertex.normal; }
public Triangle(Vertex[] vertices) { this.vertices = new Vertex[3]; for (int i = 0; i < vertices.Length; i++) this.vertices[i] = vertices[i]; }
public HalfEdge(Vertex origin, Vertex dest) { this.origin = origin; /* twin = new HalfEdge(); twin.origin = dest; twin.twin = this;*/ }
public Cylinder(float radius, float height, int faces, Vector4 color, ProgramObject program) : base(1, program) { float step = 2 * (float)Math.PI / faces; float theta = (float) Math.PI / 4; Vertex[] base_vertices = new Vertex[faces]; for (int i = 0; i < faces; i++, theta += step) { float x = radius * (float)Math.Cos(theta); float y = radius * (float)Math.Sin(theta); base_vertices[i] = new Vertex(x, y, 0, 1f); base_vertices[i].color = color; // Bottom normal pointing down and its texture base_vertices[i].normal = new Vector4(x, y, -100f, 0f); base_vertices[i].texture = new Vector4(new Vector2((184 + 128 * (float)Math.Cos(theta)) / 500, (188 + 128 * (float)Math.Sin(theta)) / 375)); //Console.WriteLine(base_vertices[i].texture.ToString()); } Vector2[][] textures = new Vector2[faces][]; float mapping_step = (float) 1 / faces; Console.WriteLine("Start"); for (int i = 0; i < faces; i++) { textures[i] = new Vector2[4]; textures[i][0] = new Vector2(mapping_step * i, 0); textures[i][1] = new Vector2(mapping_step * (i + 1), 0); textures[i][2] = new Vector2(mapping_step * i, 1f); textures[i][3] = new Vector2(mapping_step * (i + 1), 1f); Console.WriteLine(textures[i].ToString()); } Console.WriteLine("Finish"); createSweep( base_vertices, color, new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.CreateTranslation(new Vector3(0f, 0f, height)); } ), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.Identity; } ), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.Identity; } ), textures ); }
public Foot(float height, int num_steps, ProgramObject program) : base(num_steps, program) { Vertex[] vertices = new Vertex[]{ new Vertex(new Vector4(1f, -1f, 0, 1f)), new Vertex(new Vector4(1f, 1f, 0, 1f)), new Vertex(new Vector4(-1f, 1f, 0, 1f)), new Vertex(new Vector4(-1f, -1f, 0, 1f)), }; Vector2[][] textures = new Vector2[vertices.Length][]; for (int i = 0; i < vertices.Length; i+=2) { textures[i] = new Vector2[4]; textures[i][0] = new Vector2((i % 2) / 2, 0); textures[i][1] = new Vector2((i % 2) / 2 + 0.75f, 0); textures[i][2] = new Vector2((i % 2) / 2, 1f); textures[i][3] = new Vector2((i % 2) / 2 + 0.75f, 1f); } for (int i = 1; i < vertices.Length; i+= 2) { textures[i] = new Vector2[4]; textures[i][0] = new Vector2((i % 2) / 2 + 0.75f, 0); textures[i][1] = new Vector2(1f, 0); textures[i][2] = new Vector2((i % 2) / 2 + 0.75f, 1f); textures[i][3] = new Vector2(1f, 1f); } float height_step = height / num_steps; createSweep(vertices, new Vector4(0, 1f, 0, 1f), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.CreateTranslation(new Vector3(0, 0, (current + 1) * height_step)); } ), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.Identity; } ), new Func<int, int, Matrix4>( delegate(int current, int steps) { current++; float pend = 4 * 0.5f / (float)Math.Pow(steps * 0.1f, 2); float scale_factor = (float)(pend * Math.Pow(current * 0.1f - steps * 0.1f / 2f, 2) + 0.5f); return Matrix4.Scale(scale_factor, scale_factor, 1f); } ) , textures); }
public void createSweep(Vertex[] face_vertices, Vector4 color, Func<int, int, Matrix4> translation_step, Func<int, int, Matrix4> rotation_step, Func<int, int, Matrix4> scale_step,Vector2[][] textures) { this.translation_step = translation_step; this.textures = textures; polynet.addFace(face_vertices); Vertex[] backwards = new Vertex[face_vertices.Length]; backwards[0] = face_vertices[0]; for (int i = 1; i < backwards.Length; i++) { backwards[i] = face_vertices[backwards.Length - i]; } firstFace = backwards; Vertex[] currentFace = backwards; Vertex[] nextFace = new Vertex[backwards.Length]; // For each division for (int i = 0; i < steps; i++) { Matrix4 transform = translation_step(i, steps) * scale_step(i, steps); // Generate next section nextFace = new Vertex[backwards.Length]; for (int j = 0; j < backwards.Length; j++) { Vertex new_vertex = new Vertex(Vector4.Transform(backwards[j].position, transform), color, backwards[j].texture); nextFace[j] = new_vertex; } // Generate Faces for (int j = 0; j < backwards.Length; j++) { Vertex[] v = new Vertex[]{ currentFace[j], currentFace[(j + 1) % backwards.Length], nextFace[(j + 1) % backwards.Length], nextFace[j], }; polynet.addFace(v); } currentFace = nextFace; } tapa = currentFace; polynet.addFace(tapa); // Fill ArrayBuffer triangulate(); base.fillArrayBuffer(); }
public Cover(float height, float width, float lenght,float radius, int num_steps, ProgramObject program) : base(num_steps, program) { float x = width / 2; float y = lenght / 2; Vertex[] vertices = new Vertex[]{ new Vertex(-x, -y + radius, 0, 1.0f), new Vertex(-x + radius, -y, 0, 1.0f), new Vertex(x - radius, -y, 0, 1.0f), new Vertex(x, -y + radius, 0, 1.0f), new Vertex(x, y - radius, 0, 1.0f), new Vertex(x - radius, y, 0, 1), new Vertex(-x + radius, y, 0, 1.0f), new Vertex(-x, y - radius, 0, 1.0f) }; Vector2[][] textures = new Vector2[vertices.Length][]; for (int i = 0; i < vertices.Length; i++) { textures[i] = new Vector2[4]; textures[i][0] = new Vector2((i % 2) / 2, 0); textures[i][1] = new Vector2((i % 2) / 2 + 0.5f, 0); textures[i][2] = new Vector2((i % 2) / 2, 1f); textures[i][3] = new Vector2((i % 2) / 2 + 0.5f, 1f); } float height_step = height / num_steps; createSweep(vertices, new Vector4(0, 1f, 0, 1f), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.CreateTranslation(new Vector3(0, 0, height_step)); } ), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.Identity; } ), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.Identity; } ) , textures); }
public static Vector4[] singleVector4Array(Vertex[] array) { Vector4[] toRet = new Vector4[4 * array.Length]; int count = array.Length; for (int i = 0; i < array.Length; i++) { toRet[i] = array[i].position; toRet[i + count] = array[i].normal; toRet[i + count * 2] = array[i].color; toRet[i + count * 3] = array[i].texture; } return toRet; }
public void addFace(Vertex[] vertices) { HalfEdge[] currentHalfEdges = new HalfEdge[vertices.Length]; //add halfedges for (int curr = 0; curr < vertices.Length; curr++) { int next_he = (curr + 1) % vertices.Length; // look if half-edge already exists HalfEdge exist = existHalfEdge(vertices[curr], vertices[next_he]); // if it does, add it to the array, otherwise create it if (exist == null) { // create half edge from current to next vertex currentHalfEdges[curr] = new HalfEdge(vertices[curr], vertices[next_he]); HalfEdge twin = new HalfEdge(vertices[next_he],vertices[curr]); currentHalfEdges[curr].twin = twin; twin.twin = currentHalfEdges[curr]; // add halfedge to polynet halfedges dictionary this.halfEdges.Add(vertices[curr], vertices[next_he], currentHalfEdges[curr]); this.halfEdges.Add(vertices[next_he], vertices[curr], twin); } else { currentHalfEdges[curr] = exist; } } // create face with some halfedge Face face = new Face(currentHalfEdges[0]); // calculate face's normal face.normal = faceNormal(vertices); // add face to faces list faces.Add(face); // link halfedges with next and prev for(int i = 0; i < currentHalfEdges.Length; i++){ int next = (i + 1) % currentHalfEdges.Length; int prev = (currentHalfEdges.Length + i - 1) % currentHalfEdges.Length; currentHalfEdges[i].next = currentHalfEdges[next]; currentHalfEdges[i].prev = currentHalfEdges[prev]; // link face to halfedge currentHalfEdges[i].face = face; } }
// gets vertex normal as an average of faces normals public Vector4 normal(Vertex vertex) { Vector3 n = new Vector3(0, 0, 0); Dictionary<Vertex, HalfEdge> d = halfEdges[vertex]; foreach (KeyValuePair<Vertex, HalfEdge> kv in d) { Face f = kv.Value.face; n += f.normal; } return Vector4.Normalize(new Vector4(n)); }
public Foot(float height, int num_steps, ProgramObject program) : base(num_steps, program) { Vertex[] vertices = new Vertex[]{ new Vertex(new Vector4(1f, -1f, 0, 1f)), new Vertex(new Vector4(-1f, -1f, 0, 1f)), new Vertex(new Vector4(-1f, 1f, 0, 1f)), new Vertex(new Vector4(1f, 1f, 0, 1f)), }; Vector2[][] textures = new Vector2[vertices.Length][]; for (int i = 0; i < vertices.Length; i++) { textures[i] = new Vector2[4]; textures[i][0] = new Vector2((i % 2) / 2, 0); textures[i][1] = new Vector2((i % 2) / 2 + 1f, 0); textures[i][2] = new Vector2((i % 2) / 2, 1f); textures[i][3] = new Vector2((i % 2) / 2 + 1f, 1f); } float height_step = height / num_steps; createSweep(vertices, new Vector4(0, 1f, 0, 1f), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.CreateTranslation(new Vector3(0, 0, (current + 1) * height_step)); } ), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.Identity; } ), new Func<int, int, Matrix4>( delegate(int current, int steps) { current++; float pend = 4 * 0.5f / (float)Math.Pow(steps * 0.1f, 2); float scale_factor = (float)(pend * Math.Pow(current * 0.1f - steps * 0.1f / 2f, 2) + 0.5f); return Matrix4.Scale(scale_factor, scale_factor, 1f); } ) , textures); /* Vertex[][] toDraw = new Vertex[firstFace.Length + 2][]; //indices = new int[firstFace.Length + 2]; //count = new int[firstFace.Length + 2]; // agregar caras extrudadas for (int i = 0; i < firstFace.Length; i++) { int messi = 0; toDraw[i] = new Vertex[(2 + 2 * steps)*4]; HalfEdge current = polynet.halfEdges[firstFace[i]][firstFace[(i + 1) % firstFace.Length]]; // first toDraw[i][messi++] = current.origin.position; for (int j = 0; j < steps; j++) { // right (all parameters) toDraw[i][messi++] = current.next.origin.position; // left toDraw[i][messi++] = current.prev.origin.position; current = polynet.halfEdges[current.prev.origin][current.next.next.origin]; } // latest toDraw[i][messi++] = current.next.next.origin.position; }*/ }
/* * 2 ---- 3 * | | * 0 ---- 1 */ private Vector4[] faceExtents(Vertex vertex, Vertex vertex_2) { Matrix4 tr = translation_step(steps, steps); return new Vector4[] { vertex.position, vertex_2.position, Vector4.Transform(vertex.position, tr), Vector4.Transform(vertex_2.position, tr) }; }
public Cover(float height, int num_steps, ProgramObject program) : base(num_steps, program) { float x = 2.0f; float y = 2.0f; float z = 2f; float aux = 0.15f; Vertex[] vertices = new Vertex[]{ new Vertex(-x, -y + aux, z, 1.0f), new Vertex(-x + aux, -y, z, 1.0f), new Vertex(x - aux, -y, z, 1.0f), new Vertex(x, -y + aux, z, 1.0f), new Vertex(x, y - aux, z, 1.0f), new Vertex(x - aux, y, z, 1.0f), new Vertex(-x + aux, y, z, 1.0f), new Vertex(-x, y - aux, z, 1.0f) }; float step = 2 * (float)Math.PI / vertices.Length; float theta = (float)Math.PI / 4; float radius = 2f; for (int i = 0; i < vertices.Length; i++, theta += step) { // Bottom normal pointing down and its texture vertices[i].texture = new Vector4(new Vector2((184 + 128 * (float)Math.Cos(theta)) / 500, (188 + 128 * (float)Math.Sin(theta)) / 375)); //Console.WriteLine(base_vertices[i].texture.ToString()); } Vector2[][] textures = new Vector2[vertices.Length][]; for (int i = 0; i < vertices.Length; i++) { textures[i] = new Vector2[4]; textures[i][0] = new Vector2((i % 2) / 2, 0); textures[i][1] = new Vector2((i % 2) / 2 + 0.5f, 0); textures[i][2] = new Vector2((i % 2) / 2, 1f); textures[i][3] = new Vector2((i % 2) / 2 + 0.5f, 1f); } float height_step = height / num_steps; createSweep(vertices, new Vector4(0, 1f, 0, 1f), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.CreateTranslation(new Vector3(0, 0, height_step)); } ), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.Identity; } ), new Func<int, int, Matrix4>( delegate(int current, int steps) { return Matrix4.Identity; } ) , textures); }
// gets all vertex normals public List<Vector4> normals(Vertex vertex) { Dictionary<Vertex, HalfEdge> d = halfEdges[vertex]; List<Vector4> normals = new List<Vector4>(); foreach (KeyValuePair<Vertex, HalfEdge> kv in d) { Face f = kv.Value.face; normals.Add(new Vector4(f.normal)); } return normals; }
public SharpObjLoader(string path, Material material) { string errors = ""; List<Vector4> positions = new List<Vector4>(); List<Vector4> textures = new List<Vector4>(); List<Vector4> normals = new List<Vector4>(); Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; char[] split = new char[] { ' ' }; string mtlName = null; if (material != null) { Materials.Singleton.AddMaterial(material); mtlName = material.Name; } // Create a stream reader. using (StreamReader reader = new StreamReader(path)) { // Read line by line. string line = null; while ((line = reader.ReadLine()) != null) { //line = line.Replace('.', ','); // 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)); textures.Add(new Vector4(u, 1-v, 0f, 1f)); 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)); normals.Add(new Vector4(x, y, z, 1f)); 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)); positions.Add(new Vector4(x, y, z, 1f)); 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); if (indices.Length == 4) Console.Write(""); // Add each index. for (int i = 0; i < indices.Length - 1; i+=2) { for (int j = 0; j < 3; j++) { // Split the parts. string[] parts = indices[(j + i) % indices.Length].Split(new char[] { '/' }, StringSplitOptions.None); // Add each part. int position_index = (parts.Length > 0 && parts[0].Length > 0) ? int.Parse(parts[0]) - 1 : -1; int texture_index = (parts.Length > 1 && parts[1].Length > 0) ? int.Parse(parts[1]) - 1 : -1; int normal_index = (parts.Length > 2 && parts[2].Length > 0) ? int.Parse(parts[2]) - 1 : -1; Vertex v = new Vertex(positions[position_index]); if (texture_index != -1) v.texture = textures[texture_index]; if (normal_index != -1) v.normal = normals[normal_index]; vertices.Add(v); } } // 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(Path.GetDirectoryName(path) + "\\" + mtlPath); continue; } if (line.StartsWith("usemtl")) { mtlName = ReadMaterialValue(line); ebos[ebos.Count -1 ].material = Materials.Singleton[mtlName]; continue; } if (line.StartsWith("g")) { // Group name is evth after the space after 'g' string group_name = line.Substring(line.IndexOf(' ') + 1); if (ebos.Count != 0) ebos[ebos.Count - 1].lastIndex = vertices.Count - 1; EBO ebo = new EBO(); ebo.Name = group_name; if (mtlName != null) ebo.material = Materials.Singleton[mtlName]; else ebo.material = new Material(); ebo.firstIndex = vertices.Count; ebos.Add(ebo); continue; } errors += "Unsupported keyword " + line + "\n"; } if (ebos.Count > 0) ebos[ebos.Count - 1].lastIndex = vertices.Count - 1; } // Print Errors in different thread Thread t = new Thread(new ThreadStart(delegate() { Console.WriteLine(errors); })); t.Start(); //scene.SceneContainer.AddChild(polygon); //return scene; }
private HalfEdge existHalfEdge(Vertex origin, Vertex dest) { // check if halfedge exists in if(halfEdges.ContainsKey(origin) && halfEdges[origin].ContainsKey(dest)) return halfEdges[origin][dest]; return null; }
public ObjLoader(string path) { FileStream fs = File.Open(path, FileMode.Open); StreamReader reader = new StreamReader(fs); string line = reader.ReadLine(); line = line.Trim(' ').Replace('.', ',').Replace(" ", " "); string[] values = line.Split(' '); List<Vector4> positions = new List<Vector4>(); List<Vector4> textures = new List<Vector4>(); List<Vector4> normals = new List<Vector4>(); // Read vertices while (values[0] == "v") { positions.Add( new Vector4(float.Parse(values[1]), float.Parse(values[2]), float.Parse(values[3]), 1f)); line = reader.ReadLine().Trim(' ').Replace('.', ',').Replace(" ", " "); values = line.Split(' '); } // Read texture while (values[0] == "vt") { textures.Add( new Vector4(float.Parse(values[1]), float.Parse(values[2]), 0f, 1f)); line = reader.ReadLine().Trim(' ').Replace('.', ',').Replace(" ", " "); values = line.Split(' '); } // Read normals while (values[0] == "vn") { normals.Add( new Vector4(float.Parse(values[1]), float.Parse(values[2]), float.Parse(values[3]), 1f)); line = reader.ReadLine().Trim(' ').Replace('.', ',').Replace(" ", " "); values = line.Split(' '); } // Read faces while (values[0] == "f") { for (int i = 0; i < 3; i++) { string[] v_3 = values[i + 1].Split('/'); Vertex v = new Vertex(positions[int.Parse(v_3[0]) - 1]); v.texture = textures[int.Parse(v_3[1]) - 1]; v.normal = normals[int.Parse(v_3[2]) - 1]; vertices.Add(v); } line = reader.ReadLine(); if (line == null) return; line = line.Trim(' ').Replace('.', ',').Replace(" ", " "); values = line.Split(' '); } }
private Vector3 faceNormal(Vertex[] vertices) { Vector3 edge1, edge2; edge1 = new Vector3(vertices[1].position - vertices[0].position); edge2 = new Vector3(vertices[2].position - vertices[1].position); // get face's normal vector with cross product Vector3 ret = Vector3.Cross(edge1, edge2); return ret; }