Hi,
I am trying to change the code of LODGeomap as follows:
- I set a threshold value for y
- If in a generated triangle the y value of one point is below the threshold and the y value of another point is above the threshold, then remove this triangle from the mesh.
- The way a triangle is removed from the mesh is by changing the index of the one point that is on the other side of the threshold than the 2 other points to an index of one of the 2 other points. (Thus the triangle becomes a line).
The reason why I want to do this is that this way there can be discontinuities in the height of the terrain. 2 different terrains can be combined to form a cave as follows:
- There is one terrain with highs and lows and discontinuities between them
- There is another terrain with the height above the lows of the other terrain and below the highs of the other terrain.
I am testing my code changes with TerrainTestAdvanced.java (which allows to see a wireframe)
First I change the following in GeoMap.java (just to have a clear distinction between the lows and highs in the test file):
public FloatBuffer writeVertexArray(FloatBuffer store, Vector3f scale, boolean center) {if (store!=null){ if (store.remaining() < width*height*3) throw new BufferUnderflowException(); }else{ store = BufferUtils.createFloatBuffer(width*height*3); } assert hdata.length == height*width; Vector3f offset = new Vector3f(-getWidth() * scale.x * 0.5f, 0, -getWidth() * scale.z * 0.5f); if (!center) offset.zero(); int i = 0; for (int z = 0; z < height; z++){ for (int x = 0; x < width; x++){ store.put( (float)x*scale.x + offset.x );
float y = hdata[i];
if (y < 70f) {
store.put( (float)57.5fscale.y );
} else {
store.put( (float)yscale.y);
}
i++;
// store.put( (float)hdata[i++]scale.y );
// store.put( (float)57.5fscale.y );
store.put( (float)z*scale.z + offset.z );
}
}
Then I try to remove the triangles in the mesh where there are points on both side of the threshold as follows in LODGeomap:
public Mesh createMesh(Vector3f scale, Vector2f tcScale, Vector2f tcOffset, float offsetAmount, int totalSize, boolean center, int lod, boolean rightLod, boolean topLod, boolean leftLod, boolean bottomLod) {
FloatBuffer pb = writeVertexArray(null, scale, center);
FloatBuffer texb = writeTexCoordArray(null, tcOffset, tcScale, offsetAmount, totalSize);
FloatBuffer nb = writeNormalArray(null, scale);
Buffer ib;
IndexBuffer idxB = writeIndexArrayLodDiff(lod, rightLod, topLod, leftLod, bottomLod, totalSize);
//TODO patch idxB
pb.position(0);
float[] pbFloats = new float[pb.limit()];
pb.get(pbFloats);
boolean[] bottom = new boolean[pbFloats.length/3];
for (int i = 0; i < bottom.length; i++) {
int index = 3i + 1;
bottom[i] = (pbFloats[index] == 57.5fscale.y);
}
if (idxB.getBuffer() instanceof IntBuffer) {
IntBuffer temp = (IntBuffer)idxB.getBuffer();
int limit = temp.limit();
for (int i = 0; i < limit/3; i++) {
temp.position(3i);
int co1 = temp.get();
temp.position(3i + 1);
int co2 = temp.get();
temp.position(3i + 2);
int co3 = temp.get();
if (bottom[co1]) {
if (bottom[co2]) { //co1 & co2
if (!bottom[co3]) {
temp.position(3i + 2);
temp.put(co1);
}
} else { //co1 & !co2
if (bottom[co3]) {
temp.position(3i + 1);
temp.put(co1);
} else {
temp.position(3i);
temp.put(co2);
}
}
} else {
if (!bottom[co2]) { //!co1 & !co2
if (bottom[co3]) {
temp.position(3i + 2);
temp.put(co1);
}
} else { //!co1 & co2
if (!bottom[co3]) {
temp.position(3i + 1);
temp.put(co1);
} else {
temp.position(3i);
temp.put(co2);
}
}
}
}
} else {
ShortBuffer temp = (ShortBuffer)idxB.getBuffer();
int limit = temp.limit();
for (int i = 0; i < limit/3; i++) {
temp.position(3i);
short co1 = temp.get();
temp.position(3i + 1);
short co2 = temp.get();
temp.position(3i + 2);
short co3 = temp.get();
if (bottom[co1]) {
if (bottom[co2]) { //co1 & co2
if (!bottom[co3]) {
temp.position(3i + 2);
temp.put(co1);
}
} else { //co1 & !co2
if (bottom[co3]) {
temp.position(3i + 1);
temp.put(co1);
} else {
temp.position(3i);
temp.put(co2);
}
}
} else {
if (!bottom[co2]) { //!co1 & !co2
if (bottom[co3]) {
temp.position(3i + 2);
temp.put(co1);
}
} else { //!co1 & co2
if (!bottom[co3]) {
temp.position(3i + 1);
temp.put(co1);
} else {
temp.position(3i);
temp.put(co2);
}
}
}
}
}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); Mesh m = new Mesh(); m.setMode(Mode.TriangleStrip); m.setBuffer(Type.Position, 3, pb); m.setBuffer(Type.Normal, 3, nb); m.setBuffer(Type.Tangent, 3, tanb); m.setBuffer(Type.Binormal, 3, bb); m.setBuffer(Type.TexCoord, 2, texb); 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; }
However I see no difference when patching the method of LODGeomap. Does someone know why my changes to LODGeomap seem not to have the intended effect?
(The patch is temporarily, once I know how to remove the triangles from the mesh, I will refactor the code so it is cleaner.)
Regards,
Toon