159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.terrain.geomipmap.lodcalc.util;
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bounding.BoundingBox;
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.collision.CollisionResults;
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Matrix4f;
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Ray;
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f;
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh;
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer;
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer.Type;
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.BufferUtils;
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.FloatBuffer;
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.IntBuffer;
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Computes the entropy value δ (delta) for a given terrain block and
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LOD level.
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * See the geomipmapping paper section
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "2.3.1 Choosing the appropriate GeoMipMap level"
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Kirill Vainer
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class EntropyComputeUtil {
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float computeLodEntropy(Mesh terrainBlock, IntBuffer lodIndices){
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Bounding box for the terrain block
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        BoundingBox bbox = (BoundingBox) terrainBlock.getBound();
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Vertex positions for the block
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer positions = terrainBlock.getFloatBuffer(Type.Position);
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Prepare to cast rays
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f pos = new Vector3f();
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f dir = new Vector3f(0, -1, 0);
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Ray ray = new Ray(pos, dir);
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Prepare collision results
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        CollisionResults results = new CollisionResults();
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Set the LOD indices on the block
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        VertexBuffer originalIndices = terrainBlock.getBuffer(Type.Index);
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        terrainBlock.clearBuffer(Type.Index);
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        terrainBlock.setBuffer(Type.Index, 3, lodIndices);
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Recalculate collision mesh
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        terrainBlock.createCollisionData();
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float entropy = 0;
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 0; i < positions.capacity() / 3; i++){
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            BufferUtils.populateFromBuffer(pos, positions, i);
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            float realHeight = pos.y;
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            pos.addLocal(0, bbox.getYExtent(), 0);
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            ray.setOrigin(pos);
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            results.clear();
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            terrainBlock.collideWith(ray, Matrix4f.IDENTITY, bbox, results);
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (results.size() > 0){
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Vector3f contactPoint = results.getClosestCollision().getContactPoint();
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                float delta = Math.abs(realHeight - contactPoint.y);
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                entropy = Math.max(delta, entropy);
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Restore original indices
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        terrainBlock.clearBuffer(Type.Index);
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        terrainBlock.setBuffer(originalIndices);
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return entropy;
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
76