////////////////////////////////////////////////////////// // // MeshSweeper implementation // =========== // TriangleMesh* MeshSweeper::makeCylinder( const Polyline& circle, const vec3& path, const mat4& m) //[]----------------------------------------------------[] //| Make cylinder | //[]----------------------------------------------------[] { int np = circle.getNumberOfVertices(); int nv = np * 2; // number of vertices int nb = np - 2; // number of triangles of the base int nt = nv + 2 * nb; // number of triangles TriangleMesh::Arrays data; data.vertices = new vec3[data.numberOfVertices = nv]; data.triangles = new TriangleMesh::Triangle[data.numberOfTriangles = nt]; vec3 c(0, 0, 0); if (true) { Polyline::VertexIterator vit(circle.getVertexIterator()); for (int i = 0; i < np; i++) { const vec3& p = vit++.position; c += p; data.vertices[i + np] = m.transform3x4(p); data.vertices[i] = m.transform3x4(p + path); } c *= Math::inverse(REAL(np)); } TriangleMesh::Triangle* triangle = data.triangles; for (int i = 0; i < np; i++) { int j = (i + np); int k = (i + 1) % np; triangle->setVertices(i, j, k); triangle[1].setVertices(j, k + np, k); triangle += 2; } int v0 = 0; int v1 = 1; int v2 = 2; for (int i = 0; i < nb; i++) { triangle->setVertices(v0, v1, v2); triangle[nb].setVertices(v0 + np, v2 + np, v1 + np); triangle++; v2 = ((v1 = (v0 = v2) + 1) + 1) % np; } TriangleMesh* mesh = new TriangleMesh(data); mesh->computeNormals(); return mesh; }
TriangleMeshShape* MeshSweeper::makeCone(const Polyline& circle, const Vec3& path, bool flat) //[]----------------------------------------------------[] //| Make cone | //[]----------------------------------------------------[] { int np = circle.getNumberOfVertices(); int nv = np *2; // number of vertices int nb = np - 2; // number of triangles of the base int nt = np + nb; // number of triangles TriangleMesh::Arrays data; data.vertices = new Vec3[data.numberOfVertices = nv]; data.normals = new Vec3[data.numberOfNormals = np + 2]; data.triangles = new TriangleMesh::Triangle[data.numberOfTriangles = nt]; Vec3 c(0, 0, 0); if (true) { Polyline::VertexIterator vit(circle.getVertexIterator()); for (int i = 0; i < np; i++) { const Vec3 p = vit++.position; data.vertices[i] = p; c+=p; } c *= Math::inverse<REAL>((REAL)np); // Adiciona vértice superior do cone data.vertices[np+1] = path + data.vertices[np].normalize(); } if (true) { Vec3 N = triangleNormal(data.vertices); data.normals[np] = N; data.normals[np+1] = -N; } TriangleMesh::Triangle* triangle = data.triangles; int npm = np + 1; for (int i = 0; i < np; i++) { int k = (i + 1) % np; triangle->setVertices(i, npm, k); if (flat) { data.normals[i] = triangleNormal(data.vertices, i, npm, k); triangle->setNormal(i); } else { data.normals[i] = (data.vertices[i + np] - c).versor(); triangle->setNormals(i, i, k); } triangle++; } int v0 = 0; int v1 = 1; int v2 = 2; int aux = np - 2; for (int i = 0; i < aux; i++) { triangle->setVertices(v0, v1, v2); triangle->setNormal(np); triangle++; v1 = (v1+1) % np; v2 = (v2+1) % np; } return new TriangleMeshShape(data); }
TriangleMesh* MeshSweeper::makeSphere(const vec3& center, REAL radius, int mers) //[]----------------------------------------------------[] //| Make sphere | //[]----------------------------------------------------[] { if (mers < 6) mers = 6; int sections = mers; int nv = sections * mers + 2; // number of vertices (and normals) int nt = 2 * mers * sections; // number of triangles TriangleMesh::Arrays data; data.vertices = new vec3[data.numberOfVertices = nv]; data.normals = new vec3[data.numberOfNormals = nv]; data.triangles = new TriangleMesh::Triangle[data.numberOfTriangles = nt]; { Polyline arc = makeArc(center, radius, vec3(0, 0, 1), 180, sections + 1); Polyline::VertexIterator vit = arc.getVertexIterator(); vec3* vertex = data.vertices; vec3* normal = data.normals; REAL invRadius = Math::inverse<REAL>(radius); *normal = ((*vertex = (vit++).position) - center) * invRadius; mat4 rot = mat4::rotation(*normal, REAL(360) / mers, center); vertex++; normal++; for (int s = 0; s < sections; s++) { vec3 p = *vertex = (vit++).position; *normal = (p - center) * invRadius; vertex++; normal++; for (int m = 1; m < mers; m++) { *vertex = p = rot.transform3x4(p); *normal = (p - center) * invRadius; vertex++; normal++; } } *normal = ((*vertex = (vit++).position) - center) * invRadius; } TriangleMesh::Triangle* triangle = data.triangles; for (int i = 1; i <= mers; i++) { int j = i % mers + 1; triangle->setVertices(0, i, j); triangle++; } for (int s = 1; s < sections; s++) for (int m = 0, b = (s - 1) * mers + 1; m < mers;) { int i = b + m; int k = b + ++m % mers; int j = i + mers; int l = k + mers; triangle->setVertices(i, j, k); triangle[1].setVertices(k, j, l); triangle += 2; } for (int m = 0, b = (sections - 1) * mers + 1, j = nv - 1; m < mers;) { int i = b + m; int k = b + ++m % mers; triangle->setVertices(i, j, k); triangle++; } return new TriangleMesh(data); }
TriangleMeshShape* MeshSweeper::makeCylinder(const Polyline& circle, const Vec3& path, bool flat) //[]----------------------------------------------------[] //| Make cylinder | //[]----------------------------------------------------[] { int np = circle.getNumberOfVertices(); int nv = np * 2; // number of vertices int nb = np - 2; // number of triangles of the base int nt = nv + 2 * nb; // number of triangles TriangleMesh::Arrays data; data.vertices = new Vec3[data.numberOfVertices = nv]; data.normals = new Vec3[data.numberOfNormals = np + 2]; data.triangles = new TriangleMesh::Triangle[data.numberOfTriangles = nt]; Vec3 c(0, 0, 0); if (true) { Polyline::VertexIterator vit(circle.getVertexIterator()); for (int i = 0; i < np; i++) { const Vec3 p = vit++.position; c += p; data.vertices[i + np] = p; data.vertices[i] = p + path; } c *= Math::inverse<REAL>((REAL)np); } if (true) { Vec3 N = triangleNormal(data.vertices); // base normal data.normals[np] = N; data.normals[np + 1] = -N; } TriangleMesh::Triangle* triangle = data.triangles; for (int i = 0; i < np; i++) { int j = (i + np); int k = (i + 1) % np; triangle->setVertices(i, j, k); triangle[1].setVertices(j, k + np, k); if (flat) { data.normals[i] = triangleNormal(data.vertices, i, j, k); triangle->setNormal(i); triangle[1].setNormal(i); } else { data.normals[i] = (data.vertices[i + np] - c).versor(); triangle->setNormals(i, i, k); triangle[1].setNormals(i, k, k); } triangle += 2; } int v0 = 0; int v1 = 1; int v2 = 2; for (int i = 0; i < nb; i++) { triangle->setVertices(v0, v1, v2); triangle[nb].setVertices(v0 + np, v2 + np, v1 + np); triangle->setNormal(np); triangle[nb].setNormal(np + 1); triangle++; //v2 = ((v1 = (v0 = v2) + 1) + 1) % np; v1 = (v1+1) % np; v2 = (v2+1) % np; } return new TriangleMeshShape(data); }