/** * Recalculate the vertex normal, by averagin the normals of the neighboring triangles. The * neighbor list holds only triangles that we want to average with this vertex. * * @see GL_Object.registerNeighbors() * @param neighbors neighboring triangles for this vert * @return vertex normal */ public GL_Vector recalcVertexNormal(ArrayList neighbors) { float nx = 0; float ny = 0; float nz = 0; GL_Triangle tri; GL_Vector wn = new GL_Vector(); // for each neighbor triangle, average the normals for (int i = 0; i < neighbors.size(); i++) { tri = (GL_Triangle) neighbors.get(i); wn = tri.getWeightedNormal(); nx += wn.x; ny += wn.y; nz += wn.z; } GL_Vector vertn = new GL_Vector(nx, ny, nz); vertn.normalize(); return vertn; }

// MJN: have to clone the vertices, otherwise the cloned triangle // points back to the same verts as the original triangle. // WARNING: this means that the triangle verts aren't references to the // verts in the vertex array. The triangle verts are copies, so if // changes are made to the verts (ie. rebuild() assigns ids to them), // these copies won't be affected. public GL_Triangle makeClone() { GL_Triangle clone = new GL_Triangle(p1.makeClone(), p2.makeClone(), p3.makeClone()); clone.norm1 = norm1.getClone(); clone.norm2 = norm2.getClone(); clone.norm3 = norm3.getClone(); clone.uvw1 = uvw1.getClone(); clone.uvw2 = uvw2.getClone(); clone.uvw3 = uvw3.getClone(); clone.neighborsP1 = (ArrayList) neighborsP1.clone(); clone.neighborsP2 = (ArrayList) neighborsP2.clone(); clone.neighborsP3 = (ArrayList) neighborsP3.clone(); return clone; }

public GL_Vector getWeightedNormal() { return GL_Vector.vectorProduct(p1.pos, p2.pos, p3.pos); }

/** Calculate the face normal for this triangle */ public void recalcFaceNormal() { n = GL_Vector.getNormal(p1.pos, p2.pos, p3.pos); }

/** * Return true if two triangles should be smoothed as one surface. cos_angle is the minumum angle * for smoothing. If the angle between the faces is > cos_angle, then the faces are considered to * be a continuous surface. Ie. 90 degrees is a sharp corner, 180 degrees is a flat surface. */ public static boolean onSameSurface(GL_Triangle t1, GL_Triangle t2, float cos_angle) { float dot = GL_Vector.dotProduct(t1.n, t2.n); // System.out.println("surface: compare dot=" +dot + " cos-angle=" + cos_angle + " return " + // (dot > cos_angle)); return (dot > cos_angle); }