cylinder.java
来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 460 行 · 第 1/2 页
JAVA
460 行
/**
* @deprecated use {@link #updateGeometry(int, int, float, float, float, boolean, boolean)}.
*/
public void recomputeGeometry(int axisSamples, int radialSamples,
float radius, float height, boolean closed, boolean inverted) {
updateGeometry(axisSamples, radialSamples, radius, radius, height,
closed, inverted);
}
/**
* Set the half angle of the cone.
*
* @param radians
*/
public void setHalfAngle(float radians) {
updateGeometry(getAxisSamples(), getRadialSamples(), FastMath.tan(radians), getRadius2(), getHeight(), isClosed(), isInverted());
}
/**
* Set the radius of this cylinder.
* <p>
* This will also reset any second radius value on the cylinder.
* <p>
* <strong>Note:</strong> this method causes the tri-mesh geometry data
* to be recalculated, see <a href="package-summary.html#mutator-methods">
* the package description</a> for more information about this.
*
* @param radius the new radius.
* @deprecated use {@link #recomputeGeometry(int, int, float, float, boolean, boolean)}.
*/
public void setRadius(float radius) {
updateGeometry(axisSamples, radialSamples, radius, radius, height, closed, inverted);
}
/**
* Set the top radius of the 'cylinder' to differ from the bottom radius.
* <p>
* <strong>Note:</strong> this method causes the tri-mesh geometry data
* to be recalculated, see <a href="package-summary.html#mutator-methods">
* the package description</a> for more information about this.
*
* @param radius the first radius to set.
* @see {@link Cone}
* @deprecated use {@link #recomputeGeometry(int, int, float, float, boolean, boolean)}.
*/
public void setRadius1(float radius) {
updateGeometry(axisSamples, radialSamples, radius, radius2, height, closed, inverted);
}
/**
* Set the bottom radius of the 'cylinder' to differ from the top radius.
* This makes the Geometry be a frustum of pyramid, or if set to 0, a cone.
* <p>
* <strong>Note:</strong> this method causes the tri-mesh geometry data
* to be recalculated, see <a href="package-summary.html#mutator-methods">
* the package description</a> for more information about this.
*
* @param radius the second radius to set.
* @see {@link Cone}
* @deprecated use {@link #recomputeGeometry(int, int, float, float, boolean, boolean)}.
*/
public void setRadius2(float radius2) {
updateGeometry(axisSamples, radialSamples, radius, radius2, height, closed, inverted);
}
/**
* Rebuilds the cylinder based on a new set of parameters.
*
* @param axisSamples the number of samples along the axis.
* @param radialSamples the number of samples around the radial.
* @param radius the radius of the bottom of the cylinder.
* @param radius2 the radius of the top of the cylinder.
* @param height the cylinder's height.
* @param closed should the cylinder have top and bottom surfaces.
* @param inverted is the cylinder is meant to be viewed from the inside.
*/
public void updateGeometry(int axisSamples, int radialSamples,
float radius, float radius2, float height, boolean closed, boolean inverted) {
this.axisSamples = axisSamples + (closed ? 2 : 0);
this.radialSamples = radialSamples;
this.radius = radius;
this.radius2 = radius2;
this.height = height;
this.closed = closed;
this.inverted = inverted;
// Vertices
setVertexCount(axisSamples * (radialSamples + 1) + (closed ? 2 : 0));
setVertexBuffer(createVector3Buffer(getVertexBuffer(), getVertexCount()));
// Normals
setNormalBuffer(createVector3Buffer(getNormalBuffer(), getVertexCount()));
// Texture co-ordinates
getTextureCoords().set(0, new TexCoords(createVector2Buffer(getVertexCount())));
setTriangleQuantity(((closed ? 2 : 0) + 2 * (axisSamples - 1)) * radialSamples);
setIndexBuffer(createIntBuffer(getIndexBuffer(), 3 * getTriangleCount()));
// generate geometry
float inverseRadial = 1.0f / radialSamples;
float inverseAxisLess = 1.0f / (closed ? axisSamples - 3 : axisSamples - 1);
float inverseAxisLessTexture = 1.0f / (axisSamples - 1);
float halfHeight = 0.5f * height;
// Generate points on the unit circle to be used in computing the mesh
// points on a cylinder slice.
float[] sin = new float[radialSamples + 1];
float[] cos = new float[radialSamples + 1];
for (int radialCount = 0; radialCount < radialSamples; radialCount++) {
float angle = FastMath.TWO_PI * inverseRadial * radialCount;
cos[radialCount] = FastMath.cos(angle);
sin[radialCount] = FastMath.sin(angle);
}
sin[radialSamples] = sin[0];
cos[radialSamples] = cos[0];
// generate the cylinder itself
Vector3f tempNormal = new Vector3f();
for (int axisCount = 0, i = 0; axisCount < axisSamples; axisCount++, i++) {
float axisFraction;
float 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;
}
}
float z = -halfHeight + height * axisFraction;
// compute center of slice
Vector3f sliceCenter = new Vector3f(0, 0, z);
// compute slice vertices with duplication at end point
int save = i;
for (int radialCount = 0; radialCount < radialSamples; radialCount++, i++) {
float radialFraction = radialCount * inverseRadial; // in [0,1)
tempNormal.set(cos[radialCount], sin[radialCount], 0);
if (topBottom == 0) {
if (!inverted)
getNormalBuffer().put(tempNormal.x).put(tempNormal.y).put(tempNormal.z);
else
getNormalBuffer().put(-tempNormal.x).put(-tempNormal.y).put(-tempNormal.z);
} else {
getNormalBuffer().put(0).put(0).put(topBottom * (inverted ? -1 : 1));
}
tempNormal.multLocal((radius - radius2) * axisFraction + radius2)
.addLocal(sliceCenter);
getVertexBuffer().put(tempNormal.x).put(tempNormal.y).put(tempNormal.z);
getTextureCoords().get(0).coords.put((inverted ? 1 - radialFraction : radialFraction))
.put(axisFractionTexture);
}
BufferUtils.copyInternalVector3(getVertexBuffer(), save, i);
BufferUtils.copyInternalVector3(getNormalBuffer(), save, i);
getTextureCoords().get(0).coords.put((inverted ? 0.0f : 1.0f))
.put(axisFractionTexture);
}
if (closed) {
getVertexBuffer().put(0).put(0).put(-halfHeight); // bottom center
getNormalBuffer().put(0).put(0).put(-1 * (inverted ? -1 : 1));
getTextureCoords().get(0).coords.put(0.5f).put(0);
getVertexBuffer().put(0).put(0).put(halfHeight); // top center
getNormalBuffer().put(0).put(0).put(1 * (inverted ? -1 : 1));
getTextureCoords().get(0).coords.put(0.5f).put(1);
}
// Connectivity
for (int axisCount = 0, axisStart = 0; axisCount < axisSamples - 1; axisCount++) {
int i0 = axisStart;
int i1 = i0 + 1;
axisStart += radialSamples + 1;
int i2 = axisStart;
int i3 = i2 + 1;
for (int i = 0; i < radialSamples; i++) {
if (closed && axisCount == 0) {
if (!inverted) {
getIndexBuffer().put(i0++);
getIndexBuffer().put(getVertexCount() - 2);
getIndexBuffer().put(i1++);
} else {
getIndexBuffer().put(i0++);
getIndexBuffer().put(i1++);
getIndexBuffer().put(getVertexCount() - 2);
}
} else if (closed && axisCount == axisSamples - 2) {
getIndexBuffer().put(i2++);
getIndexBuffer().put(inverted ? getVertexCount() - 1 : i3++);
getIndexBuffer().put(inverted ? i3++ : getVertexCount() - 1);
} else {
getIndexBuffer().put(i0++);
getIndexBuffer().put(inverted ? i2 : i1);
getIndexBuffer().put(inverted ? i1 : i2);
getIndexBuffer().put(i1++);
getIndexBuffer().put(inverted ? i2++ : i3++);
getIndexBuffer().put(inverted ? i3++ : i2++);
}
}
}
}
public void write(JMEExporter e) throws IOException {
super.write(e);
OutputCapsule capsule = e.getCapsule(this);
capsule.write(axisSamples, "axisSamples", 0);
capsule.write(radialSamples, "radialSamples", 0);
capsule.write(radius, "radius", 0);
capsule.write(radius2, "radius2", 0);
capsule.write(height, "height", 0);
capsule.write(closed, "closed", false);
capsule.write(inverted, "inverted", false);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?