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 + -
显示快捷键?