Merging objects

Dear All,



I have to implement a scene (a labyrinth).  I have the basic building blocks ready (in obj and mtl format and some pictures), like lines, korners etc… the concept is very much ilke a LEGO world: you put something large from basic blocks together.



I've got this all mess from an Ogre based application inherited, were the developers had the poblem of running out of memory, when building very large scenes. The goal is to move from Ogre to JME and this is one of the questions left to solve… beside of coding.  :lol:



Is there a support in JMonkey, for situations like this? and I do not mean just culling, but preventing a memory overflow too… I do not wish to implement a custom pre-parser, if I don't have to (for pre merging scene blocks offline)



Thanks in advance, D

Look into using shared nodes. Load each type of shape one time, then use it over and over in your scene. The whole purpose is to save memory for repeated instances of the same object.

Thanks for the tip, I've looked into it.



One last question: how does the shared node/mesh concept support collision detection?

Is it possible, to use shared nodes for instances like "food" in a Pacman game?

In this case one would have a line of shared nodes from the same instance if I understand correctly.

Lets say we have 1000 spheres in a line and the PacMan should "eat" them one - by -one as it walks on the line. The displayed shared nodes should be removed after eating.



I've read the SharedMesh code and took a look into the examples, but an example would be welcome for proper "hiding" of a node as mentioned in the description of SharedMesh.

Fixbits said:

Thanks for the tip, I've looked into it.

One last question: how does the shared node/mesh concept support collision detection?
Is it possible, to use shared nodes for instances like "food" in a Pacman game?
In this case one would have a line of shared nodes from the same instance if I understand correctly.
Lets say we have 1000 spheres in a line and the PacMan should "eat" them one - by -one as it walks on the line. The displayed shared nodes should be removed after eating.

I've read the SharedMesh code and took a look into the examples, but an example would be welcome for proper "hiding" of a node as mentioned in the description of SharedMesh.



Sharing mesh information saves memory, because if you have two Trimesh's that are exactly the same, you'd be sending the vertex information of both to the gpu. If you use two shared meshes using one trimesh, you're only sending one set of vertex information. However, the shared meshes keep the bounding info, world matrix info, etc and essentially are two distinct objects. It's just that you're sending less data to the card (or using the same vertex buffers that exist on the card).

So stuff like collision detection is the same as if you had two distinct trimeshes. If you look at SharedMesh for example, the findTriangleCollision method actually transforms the source trimesh appropiately before searching for the collision.

This is why it's not recommended to actually use the trimesh that is shared, since each SharedMesh object is transforming the mesh data before operating it. It may be a bit of an overhead, but the memory saving may be quite a bit. You still have the thousand sphere SharedMesh objects, but you may only have to store a thousand triangles vs 1 million triangles.

Fyi, SharedNode does essentially the same thing as SharedMesh, but in the case when you may have an object composed of several nodes/trimeshes, it copies the node information, and creates SharedMeshes using the trimeshes used from the target object.

Thanks for the explanation. For some reasone I can run only the SharedMesh example, for SharedNode I've got, the following exception:





org.lwjgl.LWJGLException: No support for WGL_ARB_multisample

at org.lwjgl.opengl.WindowsPeerInfo.nChoosePixelFormat(Native Method)

at org.lwjgl.opengl.WindowsPeerInfo.choosePixelFormat(WindowsPeerInfo.java:52)

at org.lwjgl.opengl.WindowsDisplay.createWindow(WindowsDisplay.java:174)

at org.lwjgl.opengl.Display.createWindow(Display.java:308)

at org.lwjgl.opengl.Display.create(Display.java:839)

at org.lwjgl.opengl.Display.create(Display.java:767)

at com.jme.system.lwjgl.LWJGLDisplaySystem.initDisplay(LWJGLDisplaySystem.java:426)

at com.jme.system.lwjgl.LWJGLDisplaySystem.createWindow(LWJGLDisplaySystem.java:143)

at com.jme.app.BaseSimpleGame.initSystem(BaseSimpleGame.java:381)

at com.jme.app.BaseGame.start(BaseGame.java:70)

at jmetest.renderer.TestSharedNode.main(TestSharedNode.java:76)

26-Jan-2010 21:43:11 com.jme.app.BaseSimpleGame initSystem

SEVERE: Could not create displaySystem

com.jme.system.JmeException: Cannot create window: No support for WGL_ARB_multisample

at com.jme.system.lwjgl.LWJGLDisplaySystem.initDisplay(LWJGLDisplaySystem.java:444)

at com.jme.system.lwjgl.LWJGLDisplaySystem.createWindow(LWJGLDisplaySystem.java:143)

at com.jme.app.BaseSimpleGame.initSystem(BaseSimpleGame.java:381)

at com.jme.app.BaseGame.start(BaseGame.java:70)

at jmetest.renderer.TestSharedNode.main(TestSharedNode.java:76)



I haven't had the time to look further in it (forum archives etc.) and doesen't seemed that important, since TestSharedMesh does pretty much the same thing that I would like to use anyway.



Thanks again.

A little explanation to the previous post.



I can run the TestSharedMesh,TestSharedNodeOffset examples, but can't run the TestSharedNode example and I've got the exception from above.

Well your graficcard does not support multitexturing, i suppose its an intel onboard?

Probably that test will run if you just the minsamples to 0 in the line that creates the display.

Thanks, that solved the issue :slight_smile:

it is on intell onboard indeed…

based on your help and on the tutorials I've came up with this code fragment for setting up walls in my scene:





private void setupWalls() {

// Point to a URL of my model



URL model = MyModelLoadingTest.class.getClassLoader().getResource(

"jmetest/data/model/wall1.obj");



// Create something to convert .obj format to .jme

FormatConverter converter = new ObjToJme();

// Point the converter to where it will find the .mtl file from

converter.setProperty("mtllib", model);



// This byte array will hold my .jme file

ByteArrayOutputStream BO = new ByteArrayOutputStream();

try {

// Use the format converter to convert .obj to .jme

converter.convert(model.openStream(), BO);

rootWall = new Node("rootWall");

rootWall.setModelBound(new BoundingBox());

rootWall.updateModelBound();

Node wall = (Node) BinaryImporter.getInstance().load(

new ByteArrayInputStream(BO.toByteArray()));



rootWall.setLocalScale(6.1f);

wall.setLocalRotation(new Quaternion().fromAngleAxis(

FastMath.PI / 2, new Vector3f(0, 1, 0)));

rootWall.setLocalTranslation(8, 0, 0);

rootWall.attachChild(wall);



for (int i = 0; i < 500; i++) {

SharedNode sn = new SharedNode("Share" + i, wall);

sn.setLocalTranslation(new Vector3f((float) 0, (float) 0,

(float) i));

rootWall.attachChild(sn);

}

rootWall.updateWorldBound();

rootNode.attachChild(rootWall);



} catch (IOException e) { // Just in case anything happens

logger.logp(Level.SEVERE, this.getClass().toString(),

"simpleInitGame()", "Exception", e);

System.exit(0);

}

}







Is this the right way to treat bounding boxes? I don't wana end up without the max performance I can get after getting this far :slight_smile: