Using LOD

Hello guys, these questions might be a little stupid but I couldn’t find my answers in the tutorials nor the forums.



I am just starting to look into LOD and looked at TestLodStress.java. Pretty cool stuff.



Now I have Blender files that I need to convert to xml.mesh, and the question is “Do I have to create 3 separate files for 3 different LOD levels of the same object?” in Blender.



When I create my code in my project I say let’s say load(dummy.xml.mesh) how would I load 3 different LODs? I only see one file in the examples. Again I tried to look in the tutorials and forums - nothing. Is there a link that explains this as the question seem see silly to ask.

There is no mechanism except the automatic LOD generation of the ogre importer or maybe the blender exporter even supports LOD levels to be exported with ogre, but idk about the requirements. In jme, you basically have multiple meshes in one geometry (see setLodLevel()) so you could combine multiple models meshes via code. Better support for creating and handling LOD in the SDK is planned, if you have any good ideas (that go along the way stuff works in the SDK, not some “UDK does it like this, I think we should copy that 1:1 including UI”) while playing with LOD, then hit us :slight_smile:

I see, I will definitely keep you posted. Is there in the meantime any working examples using j3o objects with LOD?





thanks

Like I said, it depends on the import. j3o is just a scene graph in binary format, so it supports everything jme supports by default. On windows and mac you can use the advanced ogre importer on ogre models that you have in your assets folder, it can create lot elves automatically.

@normen said:
[...] it can create lot elves automatically.

"Lot elves"?
Is that a lot of elves or just elves who usually reside in lots? ;)

Man, OSX’s new auto-correction is killing me xD “lod levels”

Haha best comment ever :’)

normen don’t kill me yet, just to make sure I get it. LOD levels automatically? meaning I don’t have to create a file for each level?? cz in the following example the LOD code works with Teapot that I convert to j3o but with my imported file it does not work. I am assuming I don’t have children… sorry again for being so s-l-o-w-

[java]

public class LodTest extends SimpleApplication {



public static void main(String[] args){

LodTest app = new LodTest();

app.setShowSettings(false);

app.setPauseOnLostFocus(false);

app.start();

}



public void simpleInitApp() {

DirectionalLight dl = new DirectionalLight();

dl.setDirection(new Vector3f(-1,-1,-1).normalizeLocal());

rootNode.addLight(dl);





Node teapotNode = (Node) assetManager.loadModel(“Models/Teapot.j3o”); <<< works

// Node teapotNode = (Node) assetManager.loadModel(“Models/myObject.j3o”); <<< does not work

Geometry teapot = (Geometry) teapotNode.getChild(0);





Material mat = new Material(assetManager, “Common/MatDefs/Light/Lighting.j3md”);

mat.setFloat(“Shininess”, 16f);

mat.setBoolean(“VertexLighting”, true);

teapot.setMaterial(mat);



// show normals as material

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



for (int y = -10; y < 10; y++){

for (int x = -10; x < 10; x++){

Geometry clonePot = teapot.clone();



//clonePot.setMaterial(mat);

clonePot.setLocalTranslation(x * .5f, 0, y * .5f);

clonePot.setLocalScale(.15f);



LodControl control = new LodControl();

clonePot.addControl(control);

rootNode.attachChild(clonePot);

}

}



cam.setLocation(new Vector3f(8.378951f, 5.4324f, 8.795956f));

cam.setRotation(new Quaternion(-0.083419204f, 0.90370524f, -0.20599906f, -0.36595422f));

}



}[/java]

error:

[java]SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.ClassCastException: com.jme3.scene.Node cannot be cast to com.jme3.scene.Geometry

at mygame.LodTest.simpleInitApp(LodTest.java:29)

at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:228)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:129)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:205)

at java.lang.Thread.run(Thread.java:619)

Mar 20, 2012 5:15:36 PM com.jme3.renderer.lwjgl.LwjglRenderer cleanup

INFO: Deleting objects and invalidating state

Mar 20, 2012 5:15:36 PM com.jme3.input.lwjgl.LwjglMouseInput destroy

INFO: Mouse destroyed.

Mar 20, 2012 5:15:36 PM com.jme3.input.lwjgl.LwjglKeyInpu[/java]

[java]Geometry clonePot = teapot.clone();[/java]

to

[java]Spatial clonePot = teapot.clone();[/java]

Geometry is Spatial

Node is Spatial



Spatial is an interface for it.



It is basic Java:

com.jme3.scene.Node cannot be cast to com.jme3.scene.Geometry

you done somethin like this
Geometry a = b, where b is Node and Node is not superclass of Geometry

error is occuring on this line though:



[java]Geometry teapot = (Geometry) teapotNode.getChild(0);[/java]

then do the same:



[java]Spatial teapot = teapotNode.getChild(0);[/java]

no I already tried it



[java]public void simpleInitApp() {

DirectionalLight dl = new DirectionalLight();

dl.setDirection(new Vector3f(-1,-1,-1).normalizeLocal());

rootNode.addLight(dl);



//Node teapotNode = (Node) assetManager.loadModel("Models/Teapot.mesh.xml");

//Node teapotNode = (Node) assetManager.loadModel("Models/Teapot.j3o");

Node teapotNode = (Node) assetManager.loadModel("Models/pod/F_Pod.j3o");

Spatial teapot = teapotNode.getChild(0);



//teapot.setMaterial((Material) assetManager.loadMaterial( "Materials/LeakThrough.j3m"));



Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");

mat.setFloat("Shininess", 16f);

mat.setBoolean("VertexLighting", true);

teapot.setMaterial(mat);



// show normals as material

//Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");



for (int y = -10; y < 10; y++){

for (int x = -10; x < 10; x++){

Spatial clonePot = teapot.clone();



//clonePot.setMaterial(mat);

clonePot.setLocalTranslation(x * .5f, 0, y * .5f);

clonePot.setLocalScale(.15f);



LodControl control = new LodControl();

clonePot.addControl(control);

rootNode.attachChild(clonePot);

}

}



cam.setLocation(new Vector3f(8.378951f, 5.4324f, 8.795956f));

cam.setRotation(new Quaternion(-0.083419204f, 0.90370524f, -0.20599906f, -0.36595422f));

}



}[/java]





will get



[java]SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.IllegalArgumentException: LodControl can only be attached to Geometry!

at com.jme3.scene.control.LodControl.setSpatial(LodControl.java:123)

at com.jme3.scene.Spatial.addControl(Spatial.java:572)

at mygame.LodTest.simpleInitApp(LodTest.java:51)

at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:228)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:129)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:205)

at java.lang.Thread.run(Thread.java:619)

Mar 20, 2012 5:27:29 PM com.jme3.renderer.lwjgl.LwjglRenderer cleanup

INFO: Deleting objects and invalidating state

Mar 20, 2012 5:27:29 PM com.jme3.input.lwjgl.LwjglMouseInput destroy

INFO: Mouse destroyed.

Mar 20, 2012 5:27:29 PM com.jme3.input.lwjgl.LwjglKeyInput destroy

INFO: Keyboard destroyed.

Mar 20, 2012 5:27:29 PM com.jme3.system.lwjgl.LwjglAbstractDisplay deinitInThread[/java]

The advanced ogre importer creates the LOD levels, yes. Right-click the mesh file in the assets folder of the project and select “advanced j3o convert”.

ok then you need to seek Geometry. do like this:



[java] public Geometry findGeom(Spatial spatial, String name) {

if (spatial instanceof Node) {

Node findingnode = (Node) spatial;

for (int i = 0; i < findingnode.getQuantity(); i++) {

Spatial child = findingnode.getChild(i);

Geometry result = findGeom(child, name);

if (result != null) {

return result;

}

}

} else if (spatial instanceof Geometry) {

if (spatial.getName().startsWith(name)) {

return (Geometry) spatial;

}

}

return null;

}[/java]



where it find geometry with name.



but you can use somethin like this:



[java] public Geometry findGeom(Spatial spatial) {

if (spatial instanceof Node) {

Node findingnode = (Node) spatial;

for (int i = 0; i < findingnode.getQuantity(); i++) {

Spatial child = findingnode.getChild(i);

Geometry result = findGeom(child);

if (result != null) {

return result;

}

}

} else if (spatial instanceof Geometry) {

return (Geometry) spatial;

}

return null;

}[/java]



edit: or like normen said, do it via SDK

@normen but that’s what I am saying, that I am converting from .blend to binary .j3o so no OgreXml

So no automatic LOD for you.

then @oxplay2 I might not take your recommendation and use OgreXML instead :slight_smile: I definitely don’t feel like doing the tedious work of creating the LOD levels one by one.



Now the issue is how to convert the .blend to xml.mesh as for some reason my .blend is not converting to xml.mesh correctly.





Edit:



and how would I set the LODs for the j3o then?

@nightwolf911: i thinked you use ogre :stuck_out_tongue_winking_eye:



if you dont use it would just not work. i never used LOD, becouse i do rpg style, but i thinked lod control is needed too. so i think both is needed:


  • advanced export from ogre → j3o with LOD
  • add a control



    but i never used it so i cant be sure



    edit: while exporting from ogre → j3o you need to do advanced export and set there to add a LOD. yes @normen?

Ok ok I got it figured I think I’ll export from blender to Ogre and then convert to j3o after setting the LOD levels