/** builds the vertices based on the radius, center and radial and zSamples. */ private void setGeometryData(PApplet pa) { // allocate vertices // setVertexCount((zSamples - 2) * (radialSamples + 1) + 2); // setVertexBuffer(ToolsBuffers.createVector3Buffer(vertBuff, // getVertexCount())); int vertexCount = (zSamples - 2) * (radialSamples + 1) + 2; FloatBuffer vertexBuff = ToolsBuffers.createFloatBuffer(3 * vertexCount); // allocate normals if requested // setNormalBuffer(ToolsBuffers.createVector3Buffer(normBuff, // getVertexCount())); FloatBuffer normBuff = ToolsBuffers.createFloatBuffer(3 * vertexCount); // allocate texture coordinates // setTextureCoords(new TexCoords(ToolsBuffers.createVector2Buffer(getVertexCount()))); FloatBuffer texBuff = ToolsBuffers.createFloatBuffer(2 * vertexCount); // generate geometry float fInvRS = 1.0f / radialSamples; float fZFactor = 2.0f / (zSamples - 1); // Generate points on the unit circle to be used in computing the mesh // points on a sphere slice. float[] afSin = new float[(radialSamples + 1)]; float[] afCos = new float[(radialSamples + 1)]; for (int iR = 0; iR < radialSamples; iR++) { float fAngle = ToolsMath.TWO_PI * fInvRS * iR; afCos[iR] = ToolsMath.cos(fAngle); afSin[iR] = ToolsMath.sin(fAngle); } afSin[radialSamples] = afSin[0]; afCos[radialSamples] = afCos[0]; // generate the sphere itself int i = 0; for (int iZ = 1; iZ < (zSamples - 1); iZ++) { float fAFraction = ToolsMath.HALF_PI * (-1.0f + fZFactor * iZ); // in (-pi/2, pi/2) float fZFraction; if (useEvenSlices) fZFraction = -1.0f + fZFactor * iZ; // in (-1, 1) else fZFraction = ToolsMath.sin(fAFraction); // in (-1,1) float fZ = radius * fZFraction; // compute center of slice Vector3D kSliceCenter = tempVb.setValues(center); kSliceCenter.z += fZ; // compute radius of slice float fSliceRadius = ToolsMath.sqrt(ToolsMath.abs(radius * radius - fZ * fZ)); // compute slice vertices with duplication at end point Vector3D kNormal; int iSave = i; for (int iR = 0; iR < radialSamples; iR++) { float fRadialFraction = iR * fInvRS; // in [0,1) tempVc.setXYZ(afCos[iR], afSin[iR], 0); Vector3D kRadial = tempVc; tempVa = kRadial.getScaled(fSliceRadius); vertexBuff .put(kSliceCenter.x + tempVa.x) .put(kSliceCenter.y + tempVa.y) .put(kSliceCenter.z + tempVa.z); ToolsBuffers.populateFromBuffer(tempVa, vertexBuff, i); kNormal = tempVa.subtractLocal(center); kNormal.normalizeLocal(); if (true) // later we may allow interior texture vs. exterior normBuff.put(kNormal.x).put(kNormal.y).put(kNormal.z); else normBuff.put(-kNormal.x).put(-kNormal.y).put(-kNormal.z); if (textureMode == TextureMode.Original) texBuff.put(fRadialFraction).put(0.5f * (fZFraction + 1.0f)); else if (textureMode == TextureMode.Projected) texBuff .put(fRadialFraction) .put(ToolsMath.INV_PI * (ToolsMath.HALF_PI + ToolsMath.asin(fZFraction))); else if (textureMode == TextureMode.Polar) { float r = (ToolsMath.HALF_PI - ToolsMath.abs(fAFraction)) / ToolsMath.PI; float u = r * afCos[iR] + 0.5f; float v = r * afSin[iR] + 0.5f; texBuff.put(u).put(v); } i++; } copyInternalVector3(vertexBuff, iSave, i); copyInternalVector3(normBuff, iSave, i); if (textureMode == TextureMode.Original) texBuff.put(1.0f).put(0.5f * (fZFraction + 1.0f)); else if (textureMode == TextureMode.Projected) texBuff.put(1.0f).put(ToolsMath.INV_PI * (ToolsMath.HALF_PI + ToolsMath.asin(fZFraction))); else if (textureMode == TextureMode.Polar) { float r = (ToolsMath.HALF_PI - ToolsMath.abs(fAFraction)) / ToolsMath.PI; texBuff.put(r + 0.5f).put(0.5f); } i++; } // south pole vertexBuff.position(i * 3); vertexBuff.put(center.x).put(center.y).put(center.z - radius); normBuff.position(i * 3); if (true) normBuff.put(0).put(0).put(-1); // allow for inner // texture orientation // later. else normBuff.put(0).put(0).put(1); texBuff.position(i * 2); if (textureMode == TextureMode.Polar) { texBuff.put(0.5f).put(0.5f); } else { texBuff.put(0.5f).put(0.0f); } i++; // north pole vertexBuff.put(center.x).put(center.y).put(center.z + radius); if (true) normBuff.put(0).put(0).put(1); else normBuff.put(0).put(0).put(-1); if (textureMode == TextureMode.Polar) { texBuff.put(0.5f).put(0.5f); } else { texBuff.put(0.5f).put(1.0f); } Vertex[] verts = ToolsBuffers.getVertexArray(vertexBuff); Vector3D[] norms = ToolsBuffers.getVector3DArray(normBuff); // Set texcoords to vertices float[] tex = ToolsBuffers.getFloatArray(texBuff); for (int j = 0; j < tex.length / 2; j++) { float u = tex[j * 2]; float v = tex[j * 2 + 1]; verts[j].setTexCoordU(u); verts[j].setTexCoordV(v); } // get indices short[] indices = this.getIndexData(); GeometryInfo geomInfo = new GeometryInfo(pa, verts, norms, indices); this.setGeometryInfo(geomInfo); }