⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 terrainblock.java

📁 java 3d game jme 工程开发源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                focalSpot + size + 1);

        // Use linear interpolation to find the height.
        topLeft.interpolate(topRight, intOnX);
        bottomLeft.interpolate(bottomRight, intOnX);
        topLeft.interpolate(bottomLeft, intOnZ);
        return topLeft.normalizeLocal();
    }

    /**
     * <code>buildVertices</code> sets up the vertex and index arrays of the
     * TriMesh.
     */
    private void buildVertices() {
        setVertexCount(heightMap.length);
        setVertexBuffer(BufferUtils.createVector3Buffer(getVertexBuffer(),
                getVertexCount()));
        Vector3f point = new Vector3f();
        for (int x = 0; x < size; x++) {
            for (int y = 0; y < size; y++) {
                point.set(x * stepScale.x, heightMap[x + (y * size)]
                        * stepScale.y, y * stepScale.z);
                BufferUtils.setInBuffer(point, getVertexBuffer(),
                        (x + (y * size)));
            }
        }

        // set up the indices
        setTriangleQuantity(((size - 1) * (size - 1)) * 2);
        setIndexBuffer(BufferUtils.createIntBuffer(getTriangleCount() * 3));

        // go through entire array up to the second to last column.
        for (int i = 0; i < (size * (size - 1)); i++) {
            // we want to skip the top row.
            if (i % ((size * (i / size + 1)) - 1) == 0 && i != 0) {
                continue;
            }
            // set the top left corner.
            getIndexBuffer().put(i);
            // set the bottom right corner.
            getIndexBuffer().put((1 + size) + i);
            // set the top right corner.
            getIndexBuffer().put(1 + i);
            // set the top left corner
            getIndexBuffer().put(i);
            // set the bottom left corner
            getIndexBuffer().put(size + i);
            // set the bottom right corner
            getIndexBuffer().put((1 + size) + i);

        }
    }

    /**
     * <code>buildTextureCoordinates</code> calculates the texture coordinates
     * of the terrain.
     */
    public void buildTextureCoordinates() {
        float offsetX = offset.x + (offsetAmount * stepScale.x);
        float offsetY = offset.y + (offsetAmount * stepScale.z);

        setTextureCoords(new TexCoords(BufferUtils.createVector2Buffer(getVertexCount())));
        FloatBuffer texs = getTextureCoords(0).coords;
        texs.clear();

        getVertexBuffer().rewind();
        for (int i = 0; i < getVertexCount(); i++) {
            texs.put((getVertexBuffer().get() + offsetX)
                    / (stepScale.x * (totalSize - 1)));
            getVertexBuffer().get(); // ignore vert y coord.
            texs.put((getVertexBuffer().get() + offsetY)
                    / (stepScale.z * (totalSize - 1)));
        }
    }

    /**
     * <code>buildNormals</code> calculates the normals of each vertex that
     * makes up the block of terrain.
     */
    private void buildNormals() {
        setNormalBuffer(BufferUtils.createVector3Buffer(getNormalBuffer(),
                getVertexCount()));
        Vector3f oppositePoint = new Vector3f();
        Vector3f adjacentPoint = new Vector3f();
        Vector3f rootPoint = new Vector3f();
        Vector3f tempNorm = new Vector3f();
        int adj = 0, opp = 0, normalIndex = 0;
        for (int row = 0; row < size; row++) {
            for (int col = 0; col < size; col++) {
                BufferUtils.populateFromBuffer(rootPoint, getVertexBuffer(),
                        normalIndex);
                if (row == size - 1) {
                    if (col == size - 1) { // last row, last col
                        // up cross left
                        adj = normalIndex - size;
                        opp = normalIndex - 1;
                    } else { // last row, except for last col
                        // right cross up
                        adj = normalIndex + 1;
                        opp = normalIndex - size;
                    }
                } else {
                    if (col == size - 1) { // last column except for last row
                        // left cross down
                        adj = normalIndex - 1;
                        opp = normalIndex + size;
                    } else { // most cases
                        // down cross right
                        adj = normalIndex + size;
                        opp = normalIndex + 1;
                    }
                }
                BufferUtils.populateFromBuffer(adjacentPoint,
                        getVertexBuffer(), adj);
                BufferUtils.populateFromBuffer(oppositePoint,
                        getVertexBuffer(), opp);
                tempNorm.set(adjacentPoint).subtractLocal(rootPoint)
                        .crossLocal(oppositePoint.subtractLocal(rootPoint))
                        .normalizeLocal();
                BufferUtils.setInBuffer(tempNorm, getNormalBuffer(),
                        normalIndex);
                normalIndex++;
            }
        }
    }

    /**
     * Returns the height map this terrain block is using.
     * 
     * @return This terrain block's height map.
     */
    public float[] getHeightMap() {
        return heightMap;
    }

    /**
     * Returns the offset amount this terrain block uses for textures.
     * 
     * @return The current offset amount.
     */
    public float getOffsetAmount() {
        return offsetAmount;
    }

    /**
     * Returns the step scale that stretches the height map.
     * 
     * @return The current step scale.
     */
    public Vector3f getStepScale() {
        return stepScale;
    }

    /**
     * Returns the total size of the terrain.
     * 
     * @return The terrain's total size.
     */
    public int getTotalSize() {
        return totalSize;
    }

    /**
     * Returns the size of this terrain block.
     * 
     * @return The current block size.
     */
    public int getSize() {
        return size;
    }

    /**
     * Returns the current offset amount. This is used when building texture
     * coordinates.
     * 
     * @return The current offset amount.
     */
    public Vector2f getOffset() {
        return offset;
    }

    /**
     * Sets the value for the current offset amount to use when building texture
     * coordinates. Note that this does <b>NOT </b> rebuild the terrain at all.
     * This is mostly used for outside constructors of terrain blocks.
     * 
     * @param offset
     *            The new texture offset.
     */
    public void setOffset(Vector2f offset) {
        this.offset = offset;
    }

    /**
     * Sets the size of this terrain block. Note that this does <b>NOT </b>
     * rebuild the terrain at all. This is mostly used for outside constructors
     * of terrain blocks.
     * 
     * @param size
     *            The new size.
     */
    public void setSize(int size) {
        this.size = size;
    }

    /**
     * Sets the total size of the terrain . Note that this does <b>NOT </b>
     * rebuild the terrain at all. This is mostly used for outside constructors
     * of terrain blocks.
     * 
     * @param totalSize
     *            The new total size.
     */
    public void setTotalSize(int totalSize) {
        this.totalSize = totalSize;
    }

    /**
     * Sets the step scale of this terrain block's height map. Note that this
     * does <b>NOT </b> rebuild the terrain at all. This is mostly used for
     * outside constructors of terrain blocks.
     * 
     * @param stepScale
     *            The new step scale.
     */
    public void setStepScale(Vector3f stepScale) {
        this.stepScale = stepScale;
    }

    /**
     * Sets the offset of this terrain texture map. Note that this does <b>NOT
     * </b> rebuild the terrain at all. This is mostly used for outside
     * constructors of terrain blocks.
     * 
     * @param offsetAmount
     *            The new texture offset.
     */
    public void setOffsetAmount(float offsetAmount) {
        this.offsetAmount = offsetAmount;
    }

    /**
     * Sets the terrain's height map. Note that this does <b>NOT </b> rebuild
     * the terrain at all. This is mostly used for outside constructors of
     * terrain blocks.
     * 
     * @param heightMap
     *            The new height map.
     */
    public void setHeightMap(float[] heightMap) {
        this.heightMap = heightMap;
    }

    /**
     * Updates the block's vertices and normals from the current height map
     * values.
     */
    public void updateFromHeightMap() {
        if (!hasChanged())
            return;
        Vector3f point = new Vector3f();
        for (int x = 0; x < size; x++) {
            for (int y = 0; y < size; y++) {
                point.set(x * stepScale.x, heightMap[x + (y * size)]
                        * stepScale.y, y * stepScale.z);
                BufferUtils.setInBuffer(point, getVertexBuffer(),
                        (x + (y * size)));
            }
        }
        buildNormals();

        if (getVBOInfo() != null) {
            getVBOInfo().setVBOVertexID(-1);
            getVBOInfo().setVBONormalID(-1);
            DisplaySystem.getDisplaySystem().getRenderer().deleteVBO(
                    getVertexBuffer());
            DisplaySystem.getDisplaySystem().getRenderer().deleteVBO(
                    getNormalBuffer());
        }
    }

    /**
     * <code>setHeightMapValue</code> sets the value of this block's height
     * map at the given coords
     * 
     * @param x
     * @param y
     * @param newVal
     */
    public void setHeightMapValue(int x, int y, float newVal) {
        heightMap[x + (y * size)] = newVal;
    }

    /**
     * <code>setHeightMapValue</code> adds to the value of this block's height
     * map at the given coords
     * 
     * @param x
     * @param y
     * @param toAdd
     */
    public void addHeightMapValue(int x, int y, float toAdd) {
        heightMap[x + (y * size)] += toAdd;
    }

    /**
     * <code>setHeightMapValue</code> multiplies the value of this block's
     * height map at the given coords by the value given.
     * 
     * @param x
     * @param y
     * @param toMult
     */
    public void multHeightMapValue(int x, int y, float toMult) {
        heightMap[x + (y * size)] *= toMult;
    }

    public boolean hasChanged() {
        boolean update = false;
        if (oldHeightMap == null) {
            oldHeightMap = new float[heightMap.length];
            update = true;
        }

        for (int x = 0; x < oldHeightMap.length; x++)
            if (oldHeightMap[x] != heightMap[x] || update) {
                update = true;
                oldHeightMap[x] = heightMap[x];
            }

        return update;
    }

    /**
     * @return Returns the quadrant.
     */
    public short getQuadrant() {
        return quadrant;
    }

    /**
     * @param quadrant
     *            The quadrant to set.
     */
    public void setQuadrant(short quadrant) {
        this.quadrant = quadrant;
    }

    public void write(JMEExporter e) throws IOException {
        super.write(e);
        OutputCapsule capsule = e.getCapsule(this);
        capsule.write(size, "size", 0);
        capsule.write(totalSize, "totalSize", 0);
        capsule.write(quadrant, "quadrant", (short) 1);
        capsule.write(stepScale, "stepScale", Vector3f.ZERO);
        capsule.write(offset, "offset", new Vector2f());
        capsule.write(offsetAmount, "offsetAmount", 0);
        capsule.write(heightMap, "heightMap", null);
        capsule.write(oldHeightMap, "oldHeightMap", null);
    }

    public void read(JMEImporter e) throws IOException {
        super.read(e);
        InputCapsule capsule = e.getCapsule(this);
        size = capsule.readInt("size", 0);
        totalSize = capsule.readInt("totalSize", 0);
        quadrant = capsule.readShort("quadrant", (short) 1);
        stepScale = (Vector3f) capsule.readSavable("stepScale", Vector3f.ZERO
                .clone());
        offset = (Vector2f) capsule.readSavable("offset", new Vector2f());
        offsetAmount = capsule.readFloat("offsetAmount", 0);
        heightMap = capsule.readFloatArray("heightMap", null);
        oldHeightMap = capsule.readFloatArray("oldHeightMap", null);
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -