Terrain quad diagonal

@oxplay2 said:
pseudocode:

if(objvector.y < terrain.getHeight(x,y)) {
under
} else {
over
}


terrain.getHeight(x,y) is protected.

its a pseudocode, not code.



[java]public float getHeight(Vector2f xz)



protected float getHeight(float x, float z)[/java]



then use this first… getHeight(Vector2f xz). like getHeight(new Vector2f(float x, float z)).





edit:

even just look at source:

http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java?r=9237

Well, I modified an example from jme. A HillHeightMap is generated and a grid of red boxes are places on the ground.



Everything is ok, when the boxes are places at integer coordinates:



http://i.imgur.com/sLRbC.png

http://i.imgur.com/p6Tkm.png



But when the boxes places in a finer grid, interpolation is needed, it don’t work anymore.



http://i.imgur.com/4ozWS.png

http://i.imgur.com/eDS5W.png



For box position I use: box.setLocalTranslation(x, hillHeightMap.getInterpolatedHeight(x, z) * mapHeightScale, z);



Another pic: http://i.imgur.com/dIMgp.png

@oxplay2 said:
its a pseudocode, not code.

[java]public float getHeight(Vector2f xz)

protected float getHeight(float x, float z)[/java]

then use this first... getHeight(Vector2f xz). like getHeight(new Vector2f(float x, float z)).


edit:
even just look at source:
http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java?r=9237


Saw your post to late. When I change to terrain.getHeight(Vector2f xz) interpolation seems to work good.

But I take a closer look to it.

terrain.getHeight(x,z) does the interpolation for you, and handles the corners of the terrain patches (a special case).

Look at TerrainTestModifyHeight

I took a closer look and think it has a bug. Look at this screenshot:



http://i.imgur.com/v1U1G.jpg



There is a hole in the grid. And the hole is exactly ther, where the mesh isn’t homogeneous.



http://i.imgur.com/42dFP.png



EDIT:



http://i.imgur.com/0wRCJ.jpg

That is a corner of a terrain patch, the mesh is meant to look like that.

But it is possible there could be a bug in the corner for getHeight, it is a special case.



If you create a test case I can look into it.

@Sploreg said:
That is a corner of a terrain patch, the mesh is meant to look like that.
But it is possible there could be a bug in the corner for getHeight, it is a special case.

If you create a test case I can look into it.


I will do this, but it can take some time. As I said, I am quite new and english is not my native language.

The Bug is this:

TerrainQuad.java: protected float getHeight(float x, float z) { ... } This method always needs a grid like painted here http://i.imgur.com/0wRCJ.jpg (blue lines).

usrr: it’s possible that you’re right :o the output is clear. why noone observed it.



i also missed your edit before:

EDIT: I see in the last codeblock the backslashes are missing. They connect V1 and V4.


thats was why i dont known what you mean.

ah yes I see I didn’t drill down to the LODGeomap for the height, which does take into account the corner polygons.

I will fix it this week.

2 Likes

Testcase: http://i.imgur.com/HSEPN.png



[java]

import com.jme3.app.SimpleApplication;

import com.jme3.font.BitmapText;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector2f;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;

import com.jme3.terrain.geomipmap.TerrainLodControl;

import com.jme3.terrain.geomipmap.TerrainQuad;

import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator;

import com.jme3.terrain.heightmap.AbstractHeightMap;

import com.jme3.terrain.heightmap.HillHeightMap;



public class TerrainHeightTest extends SimpleApplication {



private TerrainQuad terrain;

Material matWire;

Material matTerrain;

Material matBox;

boolean wireframe = false;

boolean triPlanar = false;

protected BitmapText hintText;



public static void main(String[] args) {

TerrainHeightTest app = new TerrainHeightTest();

app.start();

}



@Override

public void initialize() {

super.initialize();

loadHintText();

}



@Override

public void simpleInitApp() {



int mapSize = 16;

int patchSize = 4;

float mapHeightScale = 0.05f;

float boxScale = 0.02f;

float boxDistance = 0.2f;

boolean lodOn = true;



setupKeys();



matBox = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

matBox.setColor(“Color”, ColorRGBA.Red);



matTerrain = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

matTerrain.setColor(“Color”, ColorRGBA.Green);



matWire = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

matWire.getAdditionalRenderState().setWireframe(true);

matWire.setColor(“Color”, ColorRGBA.Green);



AbstractHeightMap heightmap = null;

try {

heightmap = new HillHeightMap(mapSize, 100, 5f, 10f, (byte) 3);



} catch (Exception e) {

e.printStackTrace();

}



terrain = new TerrainQuad(“terrain”, patchSize + 1, mapSize + 1, heightmap.getHeightMap());

TerrainLodControl control = new TerrainLodControl(terrain, getCamera());



if (lodOn) {

control.setLodCalculator(new DistanceLodCalculator(65, 2.7f));

}



terrain.addControl(control);

terrain.setMaterial(matTerrain);

terrain.setLocalTranslation(mapSize / 2, 0, mapSize / 2);

terrain.setLocalScale(1f, mapHeightScale, 1f);

rootNode.attachChild(terrain);



cam.setLocation(new Vector3f(0, 100, 0));

cam.lookAtDirection(new Vector3f(0, -1f, 0).normalizeLocal(), Vector3f.UNIT_Y);



Box box1 = new Box(new Vector3f(0f, 0f, 0f), boxScale, boxScale, boxScale);



for (float x = 0; x < mapSize; x += boxDistance) {

for (float z = 0; z < mapSize; z += boxDistance) {



Geometry blue = new Geometry(“Box”, box1);

blue.setMaterial(matBox);



blue.setLocalTranslation(x, terrain.getHeight(new Vector2f(x, z)), z);



rootNode.attachChild(blue);

}

}

}



public void loadHintText() {

hintText = new BitmapText(guiFont, false);

hintText.setSize(guiFont.getCharSet().getRenderedSize());

hintText.setLocalTranslation(0, getCamera().getHeight(), 0);

hintText.setText(“Hit T to switch to wireframe”);

guiNode.attachChild(hintText);

}



private void setupKeys() {

flyCam.setMoveSpeed(50);

inputManager.addMapping(“wireframe”, new KeyTrigger(KeyInput.KEY_T));

inputManager.addListener(actionListener, “wireframe”);

}



private ActionListener actionListener = new ActionListener() {



public void onAction(String name, boolean pressed, float tpf) {

if (name.equals(“wireframe”) && !pressed) {

wireframe = !wireframe;

if (!wireframe) {

terrain.setMaterial(matWire);

} else {

terrain.setMaterial(matTerrain);

}

}

}

};

}

[/java]

4 Likes

Thanks @usrr

***deleted

okay the fix has been committed, let me know how it goes.

I used jME3_2012-04-03.zip but nothing changed. I try it again with next nightly.

I committed it a few hours ago, it won’t make it into the nightly build until this evening.

Works now.