CylinderGeometry function
Implementation
GeometryBuilder CylinderGeometry(double radTop, double radBot, double height,
int radialSubdivisions, bool computeNormals) {
assert (radialSubdivisions >2, "must have at least 3 divisions");
double halfHeight = height / 2;
List<VM.Vector3> vertices = [];
List<VM.Vector2> uvs = [];
List<VM.Vector3> normal = [];
// top center
vertices.add(VM.Vector3(0.0, halfHeight, 0.0));
uvs.add(VM.Vector2(0.0, 0.0));
if (computeNormals) normal.add(VM.Vector3(0.0, 1.0, 0.0));
// bottom center
vertices.add(VM.Vector3(0.0, -halfHeight, 0.0));
uvs.add(VM.Vector2(1.0, 1.0));
if (computeNormals) normal.add(VM.Vector3(0.0, -1.0, 0.0));
// First round for disks
for (int i = 0; i < radialSubdivisions; i++) {
double u = i / radialSubdivisions;
double x = Math.sin(u * Math.pi * 2);
double z = Math.cos(u * Math.pi * 2);
vertices.add(VM.Vector3(x * radTop, halfHeight, z * radTop));
uvs.add(VM.Vector2(u, 1.0));
if (computeNormals) normal.add(VM.Vector3(0.0, 1.0, 0.0));
vertices.add(VM.Vector3(x * radBot, -halfHeight, z * radBot));
uvs.add(VM.Vector2(u, 0.0));
if (computeNormals) normal.add(VM.Vector3(0.0, -1.0, 0.0));
}
if (computeNormals) {
assert(vertices.length == 2 + 2 * radialSubdivisions);
assert(uvs.length == 2 + 2 * radialSubdivisions);
// Second set of vertices for walls with different normals
for (int i = 0; i < 2 * radialSubdivisions; i += 2) {
vertices.add(vertices[i + 2]);
vertices.add(vertices[i + 3]);
uvs.add(uvs[i + 2]);
uvs.add(uvs[i + 3]);
// Now compute normals
VM.Vector3 a = vertices[i + 2];
VM.Vector3 b = vertices[i + 3];
// note: we added vertices so we will not access out of bounds
VM.Vector3 c = vertices[i + 4];
VM.Vector3 temp = VM.Vector3.zero();
VM.Vector3 norm = VM.Vector3.zero();
NormalFromPoints(a, b, c, temp, norm);
normal.add(norm);
normal.add(norm);
}
assert(vertices.length == 2 + 4 * radialSubdivisions);
} else {
assert(vertices.length == 2 + 2 * radialSubdivisions);
}
GeometryBuilder gb = GeometryBuilder();
gb.EnableAttribute(aTexUV);
gb.AddVertices(vertices);
gb.AddAttributesVector2(aTexUV, uvs);
if (computeNormals) {
gb.EnableAttribute(aNormal);
gb.AddAttributesVector3(aNormal, normal);
}
// triangles for top and bottom
for (int i = 0; i < radialSubdivisions; i++) {
final int t = (i * 2) + 2; // top node
final int b = t + 1; // bot node
int j = i + 1;
if (j == radialSubdivisions) j = 0;
final int tnext = (j * 2) + 2;
final int bnext = tnext + 1;
// triangle in top circle
gb.AddFace3(0, t, tnext);
// triangle in bottom circle
gb.AddFace3(1, bnext, b);
// Wall
int o = computeNormals ? radialSubdivisions * 2 : 0;
gb.AddFace4(o + tnext, o + t, o + b, o + bnext);
}
return gb;
}