private void setGeometryData() { final FloatBuffer verts = _meshData.getVertexBuffer(); final FloatBuffer norms = _meshData.getNormalBuffer(); final FloatBuffer texs = _meshData.getTextureBuffer(0); verts.rewind(); norms.rewind(); texs.rewind(); // generate geometry final double inverseRadial = 1.0 / radialSamples; final double inverseSphere = 1.0 / sphereSamples; final double halfHeight = 0.5 * height; // Generate points on the unit circle to be used in computing the mesh // points on a cylinder slice. final double[] sin = new double[radialSamples + 1]; final double[] cos = new double[radialSamples + 1]; for (int radialCount = 0; radialCount < radialSamples; radialCount++) { final double angle = MathUtils.TWO_PI * inverseRadial * radialCount; cos[radialCount] = MathUtils.cos(angle); sin[radialCount] = MathUtils.sin(angle); } sin[radialSamples] = sin[0]; cos[radialSamples] = cos[0]; final Vector3 tempA = new Vector3(); // top point. verts.put(0).put((float) (radius + halfHeight)).put(0); norms.put(0).put(1).put(0); texs.put(1).put(1); // generating the top dome. for (int i = 0; i < sphereSamples; i++) { final double center = radius * (1 - (i + 1) * (inverseSphere)); final double lengthFraction = (center + height + radius) / (height + 2 * radius); // compute radius of slice final double fSliceRadius = Math.sqrt(Math.abs(radius * radius - center * center)); for (int j = 0; j <= radialSamples; j++) { final Vector3 kRadial = tempA.set(cos[j], 0, sin[j]); kRadial.multiplyLocal(fSliceRadius); verts.put(kRadial.getXf()).put((float) (center + halfHeight)).put(kRadial.getZf()); kRadial.setY(center); kRadial.normalizeLocal(); norms.put(kRadial.getXf()).put(kRadial.getYf()).put(kRadial.getZf()); final double radialFraction = 1 - (j * inverseRadial); // in [0,1) texs.put((float) radialFraction).put((float) lengthFraction); } } // generate cylinder... but no need to add points for first and last // samples as they are already part of domes. for (int i = 1; i < axisSamples; i++) { final double center = halfHeight - (i * height / axisSamples); final double lengthFraction = (center + halfHeight + radius) / (height + 2 * radius); for (int j = 0; j <= radialSamples; j++) { final Vector3 kRadial = tempA.set(cos[j], 0, sin[j]); kRadial.multiplyLocal(radius); verts.put(kRadial.getXf()).put((float) center).put(kRadial.getZf()); kRadial.normalizeLocal(); norms.put(kRadial.getXf()).put(kRadial.getYf()).put(kRadial.getZf()); final double radialFraction = 1 - (j * inverseRadial); // in [0,1) texs.put((float) radialFraction).put((float) lengthFraction); } } // generating the bottom dome. for (int i = 0; i < sphereSamples; i++) { final double center = i * (radius / sphereSamples); final double lengthFraction = (radius - center) / (height + 2 * radius); // compute radius of slice final double fSliceRadius = Math.sqrt(Math.abs(radius * radius - center * center)); for (int j = 0; j <= radialSamples; j++) { final Vector3 kRadial = tempA.set(cos[j], 0, sin[j]); kRadial.multiplyLocal(fSliceRadius); verts.put(kRadial.getXf()).put((float) (-center - halfHeight)).put(kRadial.getZf()); kRadial.setY(-center); kRadial.normalizeLocal(); norms.put(kRadial.getXf()).put(kRadial.getYf()).put(kRadial.getZf()); final double radialFraction = 1 - (j * inverseRadial); // in [0,1) texs.put((float) radialFraction).put((float) lengthFraction); } } // bottom point. verts.put(0).put((float) (-radius - halfHeight)).put(0); norms.put(0).put(-1).put(0); texs.put(0).put(0); }
private void setGeometryData() { // generate geometry final double inverseRadial = 1.0 / _radialSamples; final double inverseAxisLess = 1.0 / (_closed ? _axisSamples - 3 : _axisSamples - 1); final double inverseAxisLessTexture = 1.0 / (_axisSamples - 1); final double halfHeight = 0.5 * _height; // Generate points on the unit circle to be used in computing the mesh // points on a cylinder slice. final double[] sin = new double[_radialSamples + 1]; final double[] cos = new double[_radialSamples + 1]; for (int radialCount = 0; radialCount < _radialSamples; radialCount++) { final double angle = MathUtils.TWO_PI * inverseRadial * radialCount; cos[radialCount] = MathUtils.cos(angle); sin[radialCount] = MathUtils.sin(angle); } sin[_radialSamples] = sin[0]; cos[_radialSamples] = cos[0]; // generate the cylinder itself final Vector3 tempNormal = new Vector3(); for (int axisCount = 0, i = 0; axisCount < _axisSamples; axisCount++) { double axisFraction; double axisFractionTexture; int topBottom = 0; if (!_closed) { axisFraction = axisCount * inverseAxisLess; // in [0,1] axisFractionTexture = axisFraction; } else { if (axisCount == 0) { topBottom = -1; // bottom axisFraction = 0; axisFractionTexture = inverseAxisLessTexture; } else if (axisCount == _axisSamples - 1) { topBottom = 1; // top axisFraction = 1; axisFractionTexture = 1 - inverseAxisLessTexture; } else { axisFraction = (axisCount - 1) * inverseAxisLess; axisFractionTexture = axisCount * inverseAxisLessTexture; } } final double z = -halfHeight + _height * axisFraction; // compute center of slice final Vector3 sliceCenter = new Vector3(0, 0, z); // compute slice vertices with duplication at end point final int save = i; for (int radialCount = 0; radialCount < _radialSamples; radialCount++) { final double radialFraction = radialCount * inverseRadial; // in [0,1) tempNormal.set(cos[radialCount], sin[radialCount], 0); if (topBottom == 0) { if (!_inverted) { _meshData .getNormalBuffer() .put(tempNormal.getXf()) .put(tempNormal.getYf()) .put(tempNormal.getZf()); } else { _meshData .getNormalBuffer() .put(-tempNormal.getXf()) .put(-tempNormal.getYf()) .put(-tempNormal.getZf()); } } else { _meshData.getNormalBuffer().put(0).put(0).put(topBottom * (_inverted ? -1 : 1)); } tempNormal .multiplyLocal((_radius - _radius2) * axisFraction + _radius2) .addLocal(sliceCenter); _meshData .getVertexBuffer() .put(tempNormal.getXf()) .put(tempNormal.getYf()) .put(tempNormal.getZf()); _meshData .getTextureCoords(0) .getBuffer() .put((float) (_inverted ? 1 - radialFraction : radialFraction)) .put((float) axisFractionTexture); i++; } BufferUtils.copyInternalVector3(_meshData.getVertexBuffer(), save, i); BufferUtils.copyInternalVector3(_meshData.getNormalBuffer(), save, i); _meshData .getTextureCoords(0) .getBuffer() .put((_inverted ? 0.0f : 1.0f)) .put((float) axisFractionTexture); i++; } if (_closed) { _meshData.getVertexBuffer().put(0).put(0).put((float) -halfHeight); // bottom center _meshData.getNormalBuffer().put(0).put(0).put(-1 * (_inverted ? -1 : 1)); _meshData.getTextureCoords(0).getBuffer().put(0.5f).put(0); _meshData.getVertexBuffer().put(0).put(0).put((float) halfHeight); // top center _meshData.getNormalBuffer().put(0).put(0).put(1 * (_inverted ? -1 : 1)); _meshData.getTextureCoords(0).getBuffer().put(0.5f).put(1); } }