Example #1
0
 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;
 }
Example #2
0
        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;
        }