final double b = 0.2764 * _radius;
final double c = 0.7236 * _radius;
final double d = 0.8507 * _radius;
final double e = 0.5257 * _radius;
pos++;
put(new Vector3(0, _radius, 0));
pos++;
put(new Vector3(a, y, 0));
pos++;
put(new Vector3(b, y, -d));
pos++;
put(new Vector3(-c, y, -e));
pos++;
put(new Vector3(-c, y, e));
pos++;
put(new Vector3(b, y, d));
pos++;
put(new Vector3(c, -y, -e));
pos++;
put(new Vector3(-b, -y, -d));
pos++;
put(new Vector3(-a, -y, 0));
pos++;
put(new Vector3(-b, -y, d));
pos++;
put(new Vector3(c, -y, e));
pos++;
put(new Vector3(0, -_radius, 0));
final Triangle[] ikosaedron = new Triangle[indices.length / 3];
for (int i = 0; i < ikosaedron.length; i++) {
final Triangle triangle = ikosaedron[i] = new Triangle();
triangle.pt[0] = indices[i * 3];
triangle.pt[1] = indices[i * 3 + 1];
triangle.pt[2] = indices[i * 3 + 2];
}
old = ikosaedron;
} else {
/* Six equidistant points lying on the unit sphere */
final Vector3 XPLUS = new Vector3(_radius, 0, 0); /* X */
final Vector3 XMIN = new Vector3(-_radius, 0, 0); /* -X */
final Vector3 YPLUS = new Vector3(0, _radius, 0); /* Y */
final Vector3 YMIN = new Vector3(0, -_radius, 0); /* -Y */
final Vector3 ZPLUS = new Vector3(0, 0, _radius); /* Z */
final Vector3 ZMIN = new Vector3(0, 0, -_radius); /* -Z */
final int xplus = pos++;
put(XPLUS);
final int xmin = pos++;
put(XMIN);
final int yplus = pos++;
put(YPLUS);
final int ymin = pos++;
put(YMIN);
final int zplus = pos++;
put(ZPLUS);
final int zmin = pos++;
put(ZMIN);
final Triangle[] octahedron = new Triangle[] { new Triangle(yplus, zplus, xplus),
new Triangle(xmin, zplus, yplus), new Triangle(ymin, zplus, xmin),
new Triangle(xplus, zplus, ymin), new Triangle(zmin, yplus, xplus),
new Triangle(zmin, xmin, yplus), new Triangle(zmin, ymin, xmin), new Triangle(zmin, xplus, ymin) };
old = octahedron;
}
final Vector3 pt0 = new Vector3();
final Vector3 pt1 = new Vector3();
final Vector3 pt2 = new Vector3();
/* Subdivide each starting triangle (maxlevels - 1) times */
for (int level = 1; level < _maxlevels; level++) {
/* Allocate a next triangle[] */
final Triangle[] next = new Triangle[old.length * 4];
for (int i = 0; i < next.length; i++) {
next[i] = new Triangle();
}
/**
* Subdivide each polygon in the old approximation and normalize the next points thus generated to lie on
* the surface of the unit sphere. Each input triangle with vertBuf labeled [0,1,2] as shown below will be
* turned into four next triangles:
*
* <pre>
* Make next points
* a = (0+2)/2
* b = (0+1)/2
* c = (1+2)/2
*
* 1 /\ Normalize a, b, c
* / \
* b /____\ c
*
* Construct next triangles
*
* /\ /\ [0,b,a]
* / \ / \ [b,1,c]
* /____\/____\ [a,b,c]
* 0 a 2 [a,c,2]
* </pre>
*/
for (int i = 0; i < old.length; i++) {
int newi = i * 4;
final Triangle oldt = old[i];
Triangle newt = next[newi];
BufferUtils.populateFromBuffer(pt0, vertBuf, oldt.pt[0]);
BufferUtils.populateFromBuffer(pt1, vertBuf, oldt.pt[1]);
BufferUtils.populateFromBuffer(pt2, vertBuf, oldt.pt[2]);
final Vector3 av = createMidpoint(pt0, pt2).normalizeLocal().multiplyLocal(_radius);
final Vector3 bv = createMidpoint(pt0, pt1).normalizeLocal().multiplyLocal(_radius);
final Vector3 cv = createMidpoint(pt1, pt2).normalizeLocal().multiplyLocal(_radius);
final int a = pos++;
put(av);
final int b = pos++;
put(bv);
final int c = pos++;
put(cv);
newt.pt[0] = oldt.pt[0];
newt.pt[1] = b;
newt.pt[2] = a;
newt = next[++newi];
newt.pt[0] = b;
newt.pt[1] = oldt.pt[1];
newt.pt[2] = c;
newt = next[++newi];
newt.pt[0] = a;
newt.pt[1] = b;
newt.pt[2] = c;
newt = next[++newi];
newt.pt[0] = a;
newt.pt[1] = c;
newt.pt[2] = oldt.pt[2];
}
/* Continue subdividing next triangles */
old = next;
}
final IndexBufferData<?> indexBuffer = BufferUtils.createIndexBufferData(tris * 3, verts - 1);
_meshData.setIndices(indexBuffer);
int carryIntIndex = _meshData.getVertexBuffer().position() / 3;
for (final Triangle triangle : old) {
for (final int aPt : triangle.pt) {
final Vector3 point = new Vector3();
BufferUtils.populateFromBuffer(point, _meshData.getVertexBuffer(), aPt);
if (point.getX() > 0 && point.getY() == 0) {
// Find out which 'y' side the triangle is on
final double yCenter = (_meshData.getVertexBuffer().get(triangle.pt[0] * 3 + 1)
+ _meshData.getVertexBuffer().get(triangle.pt[1] * 3 + 1) + _meshData.getVertexBuffer()
.get(triangle.pt[2] * 3 + 1)) / 3.0;
if (yCenter > 0.0) {