Hey all,
Playing around with JME using the SimpleGame as a basis for this and I'm noticing what appears to be incorrect behavior, probably something I'm doing wrong though. I just used the programmatic heightmap demo as a base and then loaded and placed a model on the terrain.
The problem is that the object will disappear then reappear depending on the camera angle and distance, in a counter intuitive way. By that I mean to say if you have it in view and turn a bit to the left, it may disappear, only to reappear if you keep turning left after a bit.
I'm running this off an M17X w/260M SLI - but noticed the same issue when I tried this on my old XPS w/ the 7950GTX+ iirc?
At this point I'm just working with the different features and learning JME, so its possibly I need to do some kind of lighting better or am missing a step (or 3) here. Thought I'd fire this one across the bow and see if theres an obvious answer, searching didn't yield any and I can provide source if necessary (at work right now).
** Edit: I should also mention I'm running 64bit Windows 7 under JDK 1.7.0.
Ok, I tried to start from scratch and only use the basics (cube and non-textured terrain), sadly I'm still getting the clipping problem. My laptop is about 3 months old so I'll check for newer drivers but i'm not holding my breath on that one. Currently I'm running in SLI, perhaps thats the problem? Will disable SLI and try with the internal card to see if that solves the problem.
What bothers me is that I'm planning on putting a lot of work into this project, even if it is just for "kicks", I'd like to know things are stable at the end. Is this a common problem? Has anyone else experienced the scene "disappearing" entirely at certain viewpoints where they should not?
sbook, could you paste a really simple example of a cube on terrain, no textures, including the frustrum setup you mentioned - If it works for you without clipping I can use that as a baseline to test my machine here.
Sounds like you're getting some clipping action… have you set up your camera frustum?
sbook said:
Sounds like you're getting some clipping action.. have you set up your camera frustum?
No I'm not doing that explicitly, just using whatever SimpleGame has setup already. Actually thats another question I have - how do I gain access to the camera? I see a lot of examples where Camera is passed, but I'm curious what I do to get a reference to the camera in the first place, I was looking for something like Camera.getActiveCamera().
Anyhow, back to the topic at hand, heres a snipet of code I'm using, I've removed preamble and network related code, etc... to make it a little more succinct (see below).
Thanks for taking the time to look!
---8<
public class MyGameClient
extends SimpleGame
{
private static final String BASE_URL = "C:/workspace/MyGame/data/";
private Text console;
private Client client;
private Node player;
public static void main(String[] args) {
MyGameClient app = new MyGameClient();
app.setConfigShowMode(ConfigShowMode.AlwaysShow);
app.start();
}
protected void simpleInitGame( )
{
initializeResources( );
generatedHeightMap( );
}
private void generatedHeightMap() {
// This will be the texture for the terrain.
URL grass = ResourceLocatorTool.locateResource( ResourceLocatorTool.TYPE_TEXTURE, "grassb.png" );
// Use the helper class to create a terrain for us. The terrain will be 64x64
MidPointHeightMap mph = new MidPointHeightMap(512,100.0f);
// Create a terrain block from the created terrain map.
TerrainBlock tb = new TerrainBlock("midpoint block",mph.getSize(), new Vector3f(1,.11f,1), mph.getHeightMap(), new Vector3f(0,-25,0));
// Add the texture
TextureState ts = display.getRenderer().createTextureState();
ts.setTexture(TextureManager.loadTexture(grass, Texture.MinificationFilter.BilinearNearestMipMap, Texture.MagnificationFilter.Bilinear));
tb.setRenderState(ts);
// Give the terrain a bounding box.
tb.setModelBound(new BoundingBox());
tb.updateModelBound();
// Toss up a house on the terrain
TriMesh house = ( TriMesh )loadModel( "house_obj" );
house.translatePoints( 1900.0f, -150.0f, 1600.0f );
// Toss up a soldier on the terrain
player = ( Node )loadModel( "robot" );
console = Text.createDefaultTextLabel("Text Label", "Press 0 and/or 1");
console.setLocalTranslation(new Vector3f(1, 60, 0));
Node scene = new Node("Scene graph node");
scene.attachChild( console );
KeyInput.get().addListener( new KeyInputListener() {
public void onKey( char character, int keyCode, boolean pressed ) {
// console.print( "key: '" + (character != 0 ? ""+character : "\0") + "' (code "+keyCode+") " + (pressed?"pressed":"released") );
// MyGameRequest request = new MyGameRequest( );
// request.message = String.valueOf( player.getLocalTranslation( ).getZ( ) );
// client.sendUDP( request );
}
} );
// Add a light source over the building
// Set camera position
// Attach the terrain TriMesh to rootNode
rootNode.attachChild( tb );
rootNode.attachChild( house );
rootNode.attachChild( player );
rootNode.attachChild( scene );
}
private URL getResourceUrl( String relativePath )
{
try {
return new URL( "file:///" + relativePath );
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
}
private Object loadModel( String modelName )
{
URL url = ResourceLocatorTool.locateResource( ResourceLocatorTool.TYPE_MODEL, modelName + ".obj" );
FormatConverter converter = new ObjToJme( );
converter.setProperty( "mtllib", url );
ByteArrayOutputStream BO = new ByteArrayOutputStream();
try {
// Use the format converter to convert .obj to .jme
converter.convert(url.openStream(), BO);
Object loadedObject = BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
if( loadedObject instanceof TriMesh )
{
TriMesh trimesh = ( TriMesh )loadedObject;
trimesh.setLocalScale(0.1f);
trimesh.setModelBound(new BoundingSphere());
trimesh.updateModelBound();
return trimesh;
}
else
{
Node node = ( Node )loadedObject;
node.setLocalScale(0.01f);
node.setModelBound(new BoundingSphere());
node.updateModelBound();
return node;
}
}
catch( IOException x )
{
x.printStackTrace( );
}
return null;
}
private void initializeResources( )
{
try
{
ResourceLocatorTool.addResourceLocator( ResourceLocatorTool.TYPE_TEXTURE, new SimpleResourceLocator( getResourceUrl( BASE_URL + "texture/" ) ) );
ResourceLocatorTool.addResourceLocator( ResourceLocatorTool.TYPE_MODEL, new SimpleResourceLocator( getResourceUrl( BASE_URL + "model/" ) ) );
}
catch( Exception x )
{
System.out.println( "Unable to initialize game, folders not found: " + x.getMessage( ) );
System.exit( 1 );
}
}
}
Lypheus said:
Actually thats another question I have - how do I gain access to the camera? I see a lot of examples where Camera is passed, but I'm curious what I do to get a reference to the camera in the first place, I was looking for something like Camera.getActiveCamera().
The easiest way is:
DisplaySystem.getDisplaySystem().getRenderer().getCamera();
I unfortunately can't look at the code at this second but I would definitely start by fiddling with the camera :)
Check this for some info on setting up the frustum.
Sounds good sbook, thanks for the quick response - i'll take a look tonight.
do your objects have a BoundingBox() / updateModelBound().
If not they might be culled too early.
Core-Dump said:
do your objects have a BoundingBox() / updateModelBound().
If not they might be culled too early.
Thank you, you are correct - my problem came from missing these two lines (below) while setting up my terrain:
terrain.setModelBound( new BoundingBox() );
terrain.updateModelBound();