public override void Draw(OpenGL gl) { // Drawing metagons is fairly easy, we save the vertex data, make a copy of // it, apply gravity, then draw the polygon. Afterwards, we restore it. VertexCollection oldVertices = vertices; VertexCollection newVertices = new VertexCollection(); foreach (Vertex v in vertices) { // Apply gravity, this means we need to know what other metagons there // are. // Find the closest vertex from the other metagon. double finddistance = -1; Vertex gravPoint = null; foreach (Vertex mV in other.Vertices) { Vertex temp = (mV /* + other.Translate*/) - (v + Translate); double tempdist = temp.Magnitude(); if (finddistance == -1 || tempdist < finddistance) { gravPoint = mV; finddistance = tempdist; } } Vertex toGrav = gravPoint - v; double distance = toGrav.Magnitude(); // The 'force' of gravity is the square root of this value, so it // only works well up cloes. double force = System.Math.Sqrt(distance); double growForce = System.Math.Sqrt(force); toGrav.UnitLength(); // Now we push this vector along by the required amount. Vertex newV = v + (toGrav * (float)force); newVertices.Add(newV); } vertices = newVertices; // Draw it. base.Draw(gl); }
/// <summary> /// This function generates normals for every vertex. /// </summary> /// <param name="parent">The parent polygon.</param> public void GenerateNormals(Polygon parent) { if (Indices.Count >= 3) { foreach (Index index in Indices) { // Do we have enough vertices for a normal? if (Indices.Count >= 3) { // Create a normal. Vertex vNormal = GetSurfaceNormal(parent); vNormal.UnitLength(); // Add it to the normals, setting the index for next time. if (index.Normal != -1) { parent.Normals.RemoveAt(index.Normal); } index.Normal = parent.Normals.Count; parent.Normals.Add(vNormal); } } } }
/// <summary> /// This function draws the polygon. /// </summary> /// <param name="gl">OpenGL.</param> public override void Draw(OpenGL gl) { if (DoPreDraw(gl)) { polyAttributes.Set(gl); foreach (Face face in faces) { // Begin drawing a polygon. if (face.Indices.Count == 2) { gl.Begin(OpenGL.LINES); } else { gl.Begin(OpenGL.POLYGON); } foreach (Index index in face.Indices) { // Set a texture coord (if any). if (index.UV != -1) { gl.TexCoord(uvs[index.UV]); } // Set a normal, or generate one. if (index.Normal != -1) { gl.Normal(normals[index.Normal]); } else { // Do we have enough vertices for a normal? if (face.Indices.Count >= 3) { // Create a normal. Vertex vNormal = face.GetSurfaceNormal(this); vNormal.UnitLength(); // Add it to the normals, setting the index for next time. index.Normal = normals.Add(new Normal(vNormal)); gl.Normal(vNormal); } } // Set the vertex. gl.Vertex(vertices[index.Vertex]); } gl.End(); } // If the current context is edit vertices, draw the vertices. if (currentContext == Context.EditVertices) { // Push all the attributes. gl.PushAttrib(OpenGL.ALL_ATTRIB_BITS); // Set the colour to red, large points, no lighting. gl.Color(1, 0, 0, 1); gl.PointSize(5); gl.Disable(OpenGL.LIGHTING); // Draw the control points. for (int point = 0; point < vertices.Count; point++) { // Name the point, then draw it. gl.PushName((uint)point); gl.Begin(OpenGL.POINTS); gl.Vertex(vertices[point]); gl.End(); gl.PopName(); } // Restore the attributes. gl.PopAttrib(); } // If the current context is edit normals, draw the normals. if (currentContext == Context.EditNormals) { // We're going to disable lighting. Attributes.Lighting lighting = new Attributes.Lighting(); lighting.Enable = false; lighting.Set(gl); gl.Color(1, 0, 0); gl.Begin(OpenGL.LINES); // Draw the normals points. foreach (Face face in faces) { foreach (Index index in face.Indices) { if (index.Normal == -1) { continue; } // Translate to that vertex. Vertex v = vertices[index.Vertex]; gl.PushName((uint)index.Normal); gl.Vertex(v); gl.Vertex(v + normals[index.Normal]); gl.PopName(); } } gl.End(); lighting.Restore(gl); } if (currentContext == Context.EditFaces) { for (int i = 0; i < Faces.Count; i++) { // Push the face name. gl.PushName((uint)i); // Set the parent poly. faces[i].parentpoly = this; // Draw it. ((IInteractable)faces[i]).DrawPick(gl); // Pop the name. gl.PopName(); } } // Draw normals if we have to. if (drawNormals) { // Set the colour to red. gl.PushAttrib(OpenGL.ALL_ATTRIB_BITS); gl.Color(1, 0, 0, 1); gl.Disable(OpenGL.LIGHTING); // Go through each face. foreach (Face face in faces) { // Go though each index. foreach (Index index in face.Indices) { // Make sure it's got a normal, and a vertex. if (index.Normal != -1 && index.Vertex != -1) { // Get the vertex. Vertex vertex = vertices[index.Vertex]; // Get the normal vertex. Normal normal = normals[index.Normal]; Vertex vertex2 = vertex + normal; gl.Begin(OpenGL.LINES); gl.Vertex(vertex); gl.Vertex(vertex2); gl.End(); } } } // Restore the attributes. gl.PopAttrib(); } polyAttributes.Restore(gl); DoPostDraw(gl); } }