changed terrain to use a ShortBuffer if the index count is less than 65535 so it can work on more android devices

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10065 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
bre..om 12 years ago
parent 4f02b407cf
commit 4bbbf7dbe8
  1. 76
      engine/src/terrain/com/jme3/terrain/geomipmap/LODGeomap.java
  2. 26
      engine/src/terrain/com/jme3/terrain/geomipmap/TerrainPatch.java
  3. 11
      engine/src/terrain/com/jme3/terrain/geomipmap/UpdatedTerrainPatch.java
  4. 10
      engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/util/EntropyComputeUtil.java

@ -40,14 +40,18 @@ import com.jme3.math.Vector3f;
import com.jme3.scene.Mesh;
import com.jme3.scene.Mesh.Mode;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.scene.mesh.IndexBuffer;
import com.jme3.terrain.GeoMap;
import com.jme3.util.BufferUtils;
import com.jme3.util.TempVars;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import org.bushe.swing.event.Logger;
/**
* Produces the mesh for the TerrainPatch.
@ -84,7 +88,12 @@ public class LODGeomap extends GeoMap {
FloatBuffer pb = writeVertexArray(null, scale, center);
FloatBuffer texb = writeTexCoordArray(null, tcOffset, tcScale, offsetAmount, totalSize);
FloatBuffer nb = writeNormalArray(null, scale);
IntBuffer ib = writeIndexArrayLodDiff(null, lod, rightLod, topLod, leftLod, bottomLod);
Buffer ib;
IndexBuffer idxB = writeIndexArrayLodDiff(lod, rightLod, topLod, leftLod, bottomLod, totalSize);
if (idxB.getBuffer() instanceof IntBuffer)
ib = (IntBuffer)idxB.getBuffer();
else
ib = (ShortBuffer)idxB.getBuffer();
FloatBuffer bb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3);
FloatBuffer tanb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3);
writeTangentArray(nb, tanb, bb, texb, scale);
@ -95,7 +104,10 @@ public class LODGeomap extends GeoMap {
m.setBuffer(Type.Tangent, 3, tanb);
m.setBuffer(Type.Binormal, 3, bb);
m.setBuffer(Type.TexCoord, 2, texb);
m.setBuffer(Type.Index, 3, ib);
if (ib instanceof IntBuffer)
m.setBuffer(Type.Index, 3, (IntBuffer)ib);
else if (ib instanceof ShortBuffer)
m.setBuffer(Type.Index, 3, (ShortBuffer)ib);
m.setStatic();
m.updateBound();
return m;
@ -151,17 +163,13 @@ public class LODGeomap extends GeoMap {
* @param bottomLod LOD of the bottom neighbour
* @return the LOD-ified index buffer
*/
public IntBuffer writeIndexArrayLodDiff(IntBuffer store, int lod, boolean rightLod, boolean topLod, boolean leftLod, boolean bottomLod) {
public IndexBuffer writeIndexArrayLodDiff(int lod, boolean rightLod, boolean topLod, boolean leftLod, boolean bottomLod, int totalSize) {
//if (true)
//return writeIndexArrayLodVariable(store, lod, height, lod, lod, lod);
IntBuffer buffer2 = store;
int numIndexes = calculateNumIndexesLodDiff(lod);
if (store == null) {
buffer2 = BufferUtils.createIntBuffer(numIndexes);
}
VerboseIntBuffer buffer = new VerboseIntBuffer(buffer2);
IndexBuffer ib = IndexBuffer.createIndexBuffer(numIndexes, numIndexes);
VerboseBuffer buffer = new VerboseBuffer(ib);
// generate center squares minus the edges
@ -357,14 +365,12 @@ public class LODGeomap extends GeoMap {
return buffer.delegate;
}
public IntBuffer writeIndexArrayLodVariable(IntBuffer store, int lod, int rightLod, int topLod, int leftLod, int bottomLod) {
public IndexBuffer writeIndexArrayLodVariable(int lod, int rightLod, int topLod, int leftLod, int bottomLod, int totalSize) {
IntBuffer buffer2 = store;
int numIndexes = calculateNumIndexesLodDiff(lod);
if (store == null) {
buffer2 = BufferUtils.createIntBuffer(numIndexes);
}
VerboseIntBuffer buffer = new VerboseIntBuffer(buffer2);
IndexBuffer ib = IndexBuffer.createIndexBuffer(numIndexes, numIndexes);
VerboseBuffer buffer = new VerboseBuffer(ib);
// generate center squares minus the edges
@ -908,25 +914,47 @@ public class LODGeomap extends GeoMap {
/**
* Keeps a count of the number of indexes, good for debugging
*/
public class VerboseIntBuffer {
public class VerboseBuffer {
private IntBuffer delegate;
private IndexBuffer delegate;
//private IntBuffer delegateInt;
//private ShortBuffer delegateShort;
int count = 0;
//private boolean intb = true;
public VerboseIntBuffer(IntBuffer d) {
delegate = d;
public VerboseBuffer(IndexBuffer d) {
this.delegate = d;
}
/*public VerboseBuffer(Buffer d) {
if (d instanceof IntBuffer)
delegateInt = (IntBuffer)d;
else if (d instanceof ShortBuffer) {
delegateShort = (ShortBuffer)d;
intb = false;
}
}*/
public void put(int value) {
delegate.put(count, value);
count++;
}
/*public void put(int value) {
try {
count++;
if (count > delegate.limit())
int limit = intb? delegateInt.limit() : delegateShort.limit();
if (count > limit)
throw new BufferOverflowException();
delegate.put(value);
if (intb)
delegateInt.put(value);
else {
System.out.println(Integer.toString(value)+" "+Short.toString((short)value));
delegateShort.put((short)value);
}
} catch (BufferOverflowException e) {
System.out.println("err buffer size: "+delegate.capacity());
Logger.getLogger(this.getClass().getName()).log(Logger.Level.ERROR, "err buffer size: "+delegateInt.capacity());
}
}
}*/
public int getCount() {
return count;

@ -46,12 +46,15 @@ import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.scene.mesh.IndexBuffer;
import com.jme3.terrain.geomipmap.TerrainQuad.LocationHeight;
import com.jme3.terrain.geomipmap.lodcalc.util.EntropyComputeUtil;
import com.jme3.util.BufferUtils;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.util.HashMap;
import java.util.List;
@ -195,8 +198,13 @@ public class TerrainPatch extends Geometry {
float[] entropies = new float[getMaxLod()+1];
for (int i = 0; i <= getMaxLod(); i++){
int curLod = (int) Math.pow(2, i);
IntBuffer buf = geomap.writeIndexArrayLodDiff(null, curLod, false, false, false, false);
entropies[i] = EntropyComputeUtil.computeLodEntropy(mesh, buf);
IndexBuffer idxB = geomap.writeIndexArrayLodDiff(curLod, false, false, false, false, totalSize);
Buffer ib;
if (idxB.getBuffer() instanceof IntBuffer)
ib = (IntBuffer)idxB.getBuffer();
else
ib = (ShortBuffer)idxB.getBuffer();
entropies[i] = EntropyComputeUtil.computeLodEntropy(mesh, ib);
}
lodEntropy = entropies;
@ -243,12 +251,18 @@ public class TerrainPatch extends Geometry {
boolean right = utp.getRightLod() > utp.getNewLod();
boolean bottom = utp.getBottomLod() > utp.getNewLod();
IntBuffer ib = null;
IndexBuffer idxB;
if (useVariableLod)
ib = geomap.writeIndexArrayLodVariable(null, pow, (int) Math.pow(2, utp.getRightLod()), (int) Math.pow(2, utp.getTopLod()), (int) Math.pow(2, utp.getLeftLod()), (int) Math.pow(2, utp.getBottomLod()));
idxB = geomap.writeIndexArrayLodVariable(pow, (int) Math.pow(2, utp.getRightLod()), (int) Math.pow(2, utp.getTopLod()), (int) Math.pow(2, utp.getLeftLod()), (int) Math.pow(2, utp.getBottomLod()), totalSize);
else
idxB = geomap.writeIndexArrayLodDiff(pow, right, top, left, bottom, totalSize);
Buffer b;
if (idxB.getBuffer() instanceof IntBuffer)
b = (IntBuffer)idxB.getBuffer();
else
ib = geomap.writeIndexArrayLodDiff(null, pow, right, top, left, bottom);
utp.setNewIndexBuffer(ib);
b = (ShortBuffer)idxB.getBuffer();
utp.setNewIndexBuffer(b);
}
}

@ -32,7 +32,9 @@
package com.jme3.terrain.geomipmap;
import com.jme3.scene.VertexBuffer.Type;
import java.nio.Buffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
/**
* Stores a terrain patch's details so the LOD background thread can update
@ -47,7 +49,7 @@ public class UpdatedTerrainPatch {
private int newLod;
private int previousLod;
private int rightLod,topLod,leftLod,bottomLod;
private IntBuffer newIndexBuffer;
private Buffer newIndexBuffer;
//private boolean reIndexNeeded = false;
private boolean fixEdges = false;
@ -93,7 +95,7 @@ public class UpdatedTerrainPatch {
return newIndexBuffer;
}*/
protected void setNewIndexBuffer(IntBuffer newIndexBuffer) {
protected void setNewIndexBuffer(Buffer newIndexBuffer) {
this.newIndexBuffer = newIndexBuffer;
}
@ -174,7 +176,10 @@ public class UpdatedTerrainPatch {
if (newIndexBuffer != null && isReIndexNeeded()) {
updatedPatch.setPreviousLod(previousLod);
updatedPatch.getMesh().clearBuffer(Type.Index);
updatedPatch.getMesh().setBuffer(Type.Index, 3, newIndexBuffer);
if (newIndexBuffer instanceof IntBuffer)
updatedPatch.getMesh().setBuffer(Type.Index, 3, (IntBuffer)newIndexBuffer);
else if (newIndexBuffer instanceof ShortBuffer)
updatedPatch.getMesh().setBuffer(Type.Index, 3, (ShortBuffer)newIndexBuffer);
}
}

@ -40,8 +40,10 @@ import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.util.BufferUtils;
import java.nio.Buffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
/**
* Computes the entropy value δ (delta) for a given terrain block and
@ -53,7 +55,7 @@ import java.nio.IntBuffer;
*/
public class EntropyComputeUtil {
public static float computeLodEntropy(Mesh terrainBlock, IntBuffer lodIndices){
public static float computeLodEntropy(Mesh terrainBlock, Buffer lodIndices){
// Bounding box for the terrain block
BoundingBox bbox = (BoundingBox) terrainBlock.getBound();
@ -72,7 +74,11 @@ public class EntropyComputeUtil {
VertexBuffer originalIndices = terrainBlock.getBuffer(Type.Index);
terrainBlock.clearBuffer(Type.Index);
terrainBlock.setBuffer(Type.Index, 3, lodIndices);
if (lodIndices instanceof IntBuffer)
terrainBlock.setBuffer(Type.Index, 3, (IntBuffer)lodIndices);
else if (lodIndices instanceof ShortBuffer) {
terrainBlock.setBuffer(Type.Index, 3, (ShortBuffer) lodIndices);
}
// Recalculate collision mesh
terrainBlock.createCollisionData();

Loading…
Cancel
Save