public void setNormals() { // first get normals for all faces int numFaces = F.size(); for (Face f : F) { Edge e = E.get(f.e); Vec3 v1 = V.get(e.v).coord; e = E.get(e.next); Vec3 v2 = V.get(e.v).coord; e = E.get(e.next); Vec3 v3 = V.get(e.v).coord; // set the normal for this face Vec3 U = Vec3.sub(v2, v1); Vec3 V = Vec3.sub(v3, v1); float nx = U.y * V.z - U.z * V.y; float ny = U.z * V.x - U.x * V.z; float nz = U.x * V.y - U.y * V.x; f.norm = new Vec3(nx, ny, nz); f.norm.normalize(); } // next set normals for all vertices for (Vert v : V) { Vector<Vec3> norms = new Vector<Vec3>(); Edge e = E.get(v.e); Edge eNext = e; // E.get(E.get(e.sym).next); do { // get eNext's Face's norm and store it for combining later norms.add(F.get(eNext.f).norm); eNext = E.get(E.get(eNext.sym).next); } while (e.i != eNext.i); // combine scaled norms here and set v.norm float scale = 1.0f / norms.size(); Vec3 vNorm = new Vec3(0, 0, 0); for (int i = 0; i < norms.size(); i++) vNorm = Vec3.add(vNorm, norms.get(i)); // .scale(scale)); v.norm = vNorm; v.norm.normalize(); } }
protected void splitEdge(int e, Vec3 newPos) { Edge edge = E.get(e); Edge sym = E.get(edge.sym); Edge e0 = new Edge(); Edge e1 = new Edge(); Vert v0 = new Vert(); // set indices of new edges + vert e0.i = E.size(); e1.i = e0.i + 1; // set up v0 v0.coord = newPos; v0.i = V.size(); v0.e = e0.i; V.add(v0); // set up e0 e0.v = v0.i; e0.f = edge.f; e0.next = edge.next; e0.prev = edge.i; e0.sym = edge.sym; // set up e1 e1.v = v0.i; e1.f = sym.f; e1.next = sym.next; e1.prev = edge.sym; e1.sym = edge.i; E.add(e0); E.add(e1); // clean up connections with e and e.sym E.get(edge.next).prev = e0.i; E.get(sym.next).prev = e1.i; edge.next = e0.i; sym.next = e1.i; sym.sym = e0.i; edge.sym = e1.i; }
public Mesh(Vec3 verts[], int faces[][]) { V = new Vector<Vert>(verts.length); for (int i = 0; i < verts.length; i++) V.addElement(null); F = new Vector<Face>(faces.length); for (int i = 0; i < faces.length; i++) F.addElement(null); int numEdges = 0; for (int f = 0; f < faces.length; f++) numEdges += faces[f].length; E = new Vector<Edge>(numEdges); for (int i = 0; i < numEdges; i++) E.addElement(null); originalFaceVerts = new Vector<Integer>(faces.length); originalFaceEdges = new Vector<Integer>(faces.length); Hashtable<IntPair, Edge> edgeTable = new Hashtable<IntPair, Edge>(); int ei = 0; // base index for group of edges for next face for (int f = 0; f < faces.length; f++) { int[] face = faces[f]; // current face final int N = face.length; // number of edges in face for (int i = 0; i < N; i++) { Edge edge = new Edge(); edge.i = ei + i; final int v = face[i]; final int vnext = face[(i + 1) % N]; IntPair key = new IntPair(vnext, v); Edge sym = edgeTable.get(key); if (sym == null) { key = new IntPair(v, vnext); edgeTable.put(key, edge); } else { edge.sym = sym.i; sym.sym = ei + i; } edge.v = v; if (V.get(v) == null) { Vert wvert = new Vert(); wvert.i = v; wvert.e = edge.i; wvert.coord = new Vec3(verts[v]); V.set(v, wvert); } edge.f = f; edge.next = ei + (i + 1) % N; edge.prev = ei + (i + N - 1) % N; E.set(edge.i, edge); } Face wface = new Face(); wface.i = f; wface.e = ei; F.set(f, wface); ei += N; } // ensure mesh is triangular triangulate(); // get number of original faces originalFaceCount = F.size(); // get one of each original face's vertices for (int i = 0; i < originalFaceCount; i++) originalFaceVerts.add(E.get(F.get(i).e).v); for (int i = 0; i < originalFaceCount; i++) originalFaceEdges.add(F.get(i).e); // set the normals for the mesh setNormals(); }
protected void adjustEvenVerts(Hashtable<Integer, Vec3> evenVerts) { for (int i = 0; i < V.size(); i++) { Vert v = V.get(i); v.coord = evenVerts.get(v.i); } }