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

📄 terrainpage.java

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

    /**
     * <code>getSurfaceNormal</code> returns the normal of an arbitrary point
     * on the terrain. The normal is linearly interpreted from the normals of
     * the 4 nearest defined points. If the point provided is not within the
     * bounds of the height map, null is returned.
     * 
     * @param x
     *            the x coordinate to check.
     * @param z
     *            the z coordinate to check.
     * @param store
     *            the Vector3f object to store the result in. If null, a new one
     *            is created.
     * @return the normal vector at the provided location.
     */
    public Vector3f getSurfaceNormal(float x, float z, Vector3f store) {
        // determine which quadrant this is in.
        Spatial child = null;
        int split = (size - 1) >> 1;
        float halfmapx = split * stepScale.x, halfmapz = split * stepScale.z;
        float newX = 0, newZ = 0;
        if (x == 0)
            x += .001f;
        if (z == 0)
            z += .001f;
        if (x > 0) {
            if (z > 0) {
                // upper right
                child = getChild(3);
                newX = x;
                newZ = z;
            } else {
                // lower right
                child = getChild(2);
                newX = x;
                newZ = z + halfmapz;
            }
        } else {
            if (z > 0) {
                // upper left
                child = getChild(1);
                newX = x + halfmapx;
                newZ = z;
            } else {
                // lower left...
                child = getChild(0);
                if (x == 0)
                    x -= .1f;
                if (z == 0)
                    z -= .1f;
                newX = x + halfmapx;
                newZ = z + halfmapz;
            }
        }
        if (child instanceof TerrainBlock)
            return ((TerrainBlock) child).getSurfaceNormal(newX, newZ, store);
        else if (child instanceof TerrainPage)
            return ((TerrainPage) child).getSurfaceNormal(x
                    - ((TerrainPage) child).getLocalTranslation().x, z
                    - ((TerrainPage) child).getLocalTranslation().z, store);
        return null;
    }

    /**
     * <code>split</code> divides the heightmap data for four children. The
     * children are either pages or blocks. This is dependent on the size of the
     * children. If the child's size is less than or equal to the set block
     * size, then blocks are created, otherwise, pages are created.
     * 
     * @param blockSize
     *            the blocks size to test against.
     * @param heightMap
     *            the height data.
     */
    private void split(int blockSize, float[] heightMap) {
        if ((size >> 1) + 1 <= blockSize) {
            createQuadBlock(heightMap);
        } else {
            createQuadPage(blockSize, heightMap);
        }

    }

    /**
     * <code>createQuadPage</code> generates four new pages from this page.
     */
    private void createQuadPage(int blockSize, float[] heightMap) {
        // create 4 terrain pages
        int quarterSize = size >> 2;

        int split = (size + 1) >> 1;

        Vector2f tempOffset = new Vector2f();
        offsetAmount += quarterSize;

        // 1 upper left
        float[] heightBlock1 = createHeightSubBlock(heightMap, 0, 0, split);

        Vector3f origin1 = new Vector3f(-quarterSize * stepScale.x, 0,
                -quarterSize * stepScale.z);

        tempOffset.x = offset.x;
        tempOffset.y = offset.y;
        tempOffset.x += origin1.x;
        tempOffset.y += origin1.z;

        TerrainPage page1 = new TerrainPage(getName() + "Page1", blockSize,
                split, stepScale, heightBlock1, totalSize, tempOffset,
                offsetAmount);
        page1.setLocalTranslation(origin1);
        page1.quadrant = 1;
        this.attachChild(page1);

        // 2 lower left
        float[] heightBlock2 = createHeightSubBlock(heightMap, 0, split - 1,
                split);

        Vector3f origin2 = new Vector3f(-quarterSize * stepScale.x, 0,
                quarterSize * stepScale.z);

        tempOffset.x = offset.x;
        tempOffset.y = offset.y;
        tempOffset.x += origin2.x;
        tempOffset.y += origin2.z;

        TerrainPage page2 = new TerrainPage(getName() + "Page2", blockSize,
                split, stepScale, heightBlock2, totalSize, tempOffset,
                offsetAmount);
        page2.setLocalTranslation(origin2);
        page2.quadrant = 2;
        this.attachChild(page2);

        // 3 upper right
        float[] heightBlock3 = createHeightSubBlock(heightMap, split - 1, 0,
                split);

        Vector3f origin3 = new Vector3f(quarterSize * stepScale.x, 0,
                -quarterSize * stepScale.z);

        tempOffset.x = offset.x;
        tempOffset.y = offset.y;
        tempOffset.x += origin3.x;
        tempOffset.y += origin3.z;

        TerrainPage page3 = new TerrainPage(getName() + "Page3", blockSize,
                split, stepScale, heightBlock3, totalSize, tempOffset,
                offsetAmount);
        page3.setLocalTranslation(origin3);
        page3.quadrant = 3;
        this.attachChild(page3);
        // //
        // 4 lower right
        float[] heightBlock4 = createHeightSubBlock(heightMap, split - 1,
                split - 1, split);

        Vector3f origin4 = new Vector3f(quarterSize * stepScale.x, 0,
                quarterSize * stepScale.z);

        tempOffset.x = offset.x;
        tempOffset.y = offset.y;
        tempOffset.x += origin4.x;
        tempOffset.y += origin4.z;

        TerrainPage page4 = new TerrainPage(getName() + "Page4", blockSize,
                split, stepScale, heightBlock4, totalSize, tempOffset,
                offsetAmount);
        page4.setLocalTranslation(origin4);
        page4.quadrant = 4;
        this.attachChild(page4);

    }

    /**
     * <code>createQuadBlock</code> creates four child blocks from this page.
     */
    private void createQuadBlock(float[] heightMap) {
        // create 4 terrain blocks
        int quarterSize = size >> 2;
        int halfSize = size >> 1;
        int split = (size + 1) >> 1;

        Vector2f tempOffset = new Vector2f();
        offsetAmount += quarterSize;

        // 1 upper left
        float[] heightBlock1 = createHeightSubBlock(heightMap, 0, 0, split);

        Vector3f origin1 = new Vector3f(-halfSize * stepScale.x, 0, -halfSize
                * stepScale.z);

        tempOffset.x = offset.x;
        tempOffset.y = offset.y;
        tempOffset.x += origin1.x / 2;
        tempOffset.y += origin1.z / 2;

        TerrainBlock block1 = new TerrainBlock(getName() + "Block1", split,
                stepScale, heightBlock1, origin1, totalSize, tempOffset,
                offsetAmount);
        block1.setQuadrant((short) 1);
        this.attachChild(block1);
        block1.setModelBound(new BoundingBox());
        block1.updateModelBound();

        // 2 lower left
        float[] heightBlock2 = createHeightSubBlock(heightMap, 0, split - 1,
                split);

        Vector3f origin2 = new Vector3f(-halfSize * stepScale.x, 0, 0);

        tempOffset.x = offset.x;
        tempOffset.y = offset.y;
        tempOffset.x += origin1.x / 2;
        tempOffset.y += quarterSize * stepScale.z;

        TerrainBlock block2 = new TerrainBlock(getName() + "Block2", split,
                stepScale, heightBlock2, origin2, totalSize, tempOffset,
                offsetAmount);
        block2.setQuadrant((short) 2);
        this.attachChild(block2);
        block2.setModelBound(new BoundingBox());
        block2.updateModelBound();

        // 3 upper right
        float[] heightBlock3 = createHeightSubBlock(heightMap, split - 1, 0,
                split);

        Vector3f origin3 = new Vector3f(0, 0, -halfSize * stepScale.z);

        tempOffset.x = offset.x;
        tempOffset.y = offset.y;
        tempOffset.x += quarterSize * stepScale.x;
        tempOffset.y += origin3.z / 2;

        TerrainBlock block3 = new TerrainBlock(getName() + "Block3", split,
                stepScale, heightBlock3, origin3, totalSize, tempOffset,
                offsetAmount);
        block3.setQuadrant((short) 3);
        this.attachChild(block3);
        block3.setModelBound(new BoundingBox());
        block3.updateModelBound();

        // 4 lower right
        float[] heightBlock4 = createHeightSubBlock(heightMap, split - 1,
                split - 1, split);

        Vector3f origin4 = new Vector3f(0, 0, 0);

        tempOffset.x = offset.x;
        tempOffset.y = offset.y;
        tempOffset.x += quarterSize * stepScale.x;
        tempOffset.y += quarterSize * stepScale.z;

        TerrainBlock block4 = new TerrainBlock(getName() + "Block4", split,
                stepScale, heightBlock4, origin4, totalSize, tempOffset,
                offsetAmount);
        block4.setQuadrant((short) 4);
        this.attachChild(block4);
        block4.setModelBound(new BoundingBox());
        block4.updateModelBound();
    }

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

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

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

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

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

    /**
     * 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 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 size of this terrain page. 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 step scale of this terrain page'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;
    }

    /*
     * Deletes the VBO for this normal buffer, if any is present.
     */
    private void deleteNormalVBO(TerrainBlock block) {
        if (block.getVBOInfo() != null
                && block.getVBOInfo().getVBOIndexID() > 0) {
            DisplaySystem.getDisplaySystem().getRenderer().deleteVBO(
                    block.getNormalBuffer());
            block.getVBOInfo().setVBONormalID(-1);
        }
    }

⌨️ 快捷键说明

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