private TriangleMesh generate(int[] tris, float[] verts, bool smoothNormals) { ParameterList pl = new ParameterList(); pl.addIntegerArray("triangles", tris); pl.addPoints("points", ParameterList.InterpolationType.VERTEX, verts); if (smoothNormals) { float[] normals = new float[verts.Length]; // filled with 0's Point3 p0 = new Point3(); Point3 p1 = new Point3(); Point3 p2 = new Point3(); Vector3 n = new Vector3(); for (int i3 = 0; i3 < tris.Length; i3 += 3) { int v0 = tris[i3 + 0]; int v1 = tris[i3 + 1]; int v2 = tris[i3 + 2]; p0.set(verts[3 * v0 + 0], verts[3 * v0 + 1], verts[3 * v0 + 2]); p1.set(verts[3 * v1 + 0], verts[3 * v1 + 1], verts[3 * v1 + 2]); p2.set(verts[3 * v2 + 0], verts[3 * v2 + 1], verts[3 * v2 + 2]); Point3.normal(p0, p1, p2, n); // compute normal // add face normal to each vertex // note that these are not normalized so this in fact weights // each normal by the area of the triangle normals[3 * v0 + 0] += n.x; normals[3 * v0 + 1] += n.y; normals[3 * v0 + 2] += n.z; normals[3 * v1 + 0] += n.x; normals[3 * v1 + 1] += n.y; normals[3 * v1 + 2] += n.z; normals[3 * v2 + 0] += n.x; normals[3 * v2 + 1] += n.y; normals[3 * v2 + 2] += n.z; } // normalize all the vectors for (int i3 = 0; i3 < normals.Length; i3 += 3) { n.set(normals[i3 + 0], normals[i3 + 1], normals[i3 + 2]); n.normalize(); normals[i3 + 0] = n.x; normals[i3 + 1] = n.y; normals[i3 + 2] = n.z; } pl.addVectors("normals", ParameterList.InterpolationType.VERTEX, normals); } TriangleMesh m = new TriangleMesh(); if (m.update(pl, null)) return m; // something failed in creating the mesh, the error message will be // printed by the mesh itself - no need to repeat it here return null; }
public PrimitiveList tesselate() { float[] vertices = new float[patches.Length * (subdivs + 1) * (subdivs + 1) * 3]; float[] normals = smooth ? new float[patches.Length * (subdivs + 1) * (subdivs + 1) * 3] : null; float[] uvs = new float[patches.Length * (subdivs + 1) * (subdivs + 1) * 2]; int[] indices = new int[patches.Length * subdivs * subdivs * (quads ? 4 : (2 * 3))]; int vidx = 0, pidx = 0; float step = 1.0f / subdivs; int vstride = subdivs + 1; Point3 p = new Point3(); Vector3 n = smooth ? new Vector3() : null; foreach (float[] patch in patches) { // create patch vertices for (int i = 0, voff = 0; i <= subdivs; i++) { float u = i * step; float[] bu = bernstein(u); float[] bdu = bernsteinDeriv(u); for (int j = 0; j <= subdivs; j++, voff += 3) { float v = j * step; float[] bv = bernstein(v); float[] bdv = bernsteinDeriv(v); getPatchPoint(u, v, patch, bu, bv, bdu, bdv, p, n); vertices[vidx + voff + 0] = p.x; vertices[vidx + voff + 1] = p.y; vertices[vidx + voff + 2] = p.z; if (smooth) { normals[vidx + voff + 0] = n.x; normals[vidx + voff + 1] = n.y; normals[vidx + voff + 2] = n.z; } uvs[(vidx + voff) / 3 * 2 + 0] = u; uvs[(vidx + voff) / 3 * 2 + 1] = v; } } // generate patch triangles for (int i = 0, vbase = vidx / 3; i < subdivs; i++) { for (int j = 0; j < subdivs; j++) { int v00 = (i + 0) * vstride + (j + 0); int v10 = (i + 1) * vstride + (j + 0); int v01 = (i + 0) * vstride + (j + 1); int v11 = (i + 1) * vstride + (j + 1); if (quads) { indices[pidx + 0] = vbase + v01; indices[pidx + 1] = vbase + v00; indices[pidx + 2] = vbase + v10; indices[pidx + 3] = vbase + v11; pidx += 4; } else { // add 2 triangles indices[pidx + 0] = vbase + v00; indices[pidx + 1] = vbase + v10; indices[pidx + 2] = vbase + v01; indices[pidx + 3] = vbase + v10; indices[pidx + 4] = vbase + v11; indices[pidx + 5] = vbase + v01; pidx += 6; } } } vidx += vstride * vstride * 3; } ParameterList pl = new ParameterList(); pl.addPoints("points", ParameterList.InterpolationType.VERTEX, vertices); if (quads) pl.addIntegerArray("quads", indices); else pl.addIntegerArray("triangles", indices); pl.addTexCoords("uvs", ParameterList.InterpolationType.VERTEX, uvs); if (smooth) pl.addVectors("normals", ParameterList.InterpolationType.VERTEX, normals); PrimitiveList m = quads ? (PrimitiveList)new QuadMesh() : (PrimitiveList)new TriangleMesh(); m.update(pl, null); pl.clear(true); return m; }