Number of instances of a geometry/mesh

Hi all,



Before digging into the code too much, is there an easy way to get all geometries with the same mesh?



For instance, I load an ogre scene with a lot of bushes. They’re all the same mesh, just in a whole bunch of different locations. Does jme make a new mesh for each bush? If not, is there a way to find out how many objects reference a certain mesh and what those objects are?

Are you talking about getting geometries from scene graphs / nodes? The Node.java class has a method that does such stuff, getChild(String name). It goes down the scene graph hierarchy and find the spatial with the given name, the spatial may be a geometry or a particle emitter or a node itself etc etc.

Kind of, but not exactly…



Imagine an artist gave you a scene in Ogre and it contained a bunch of car models. The car models are not named but they all use the exact same mesh.



I want to know how many objects use that same car mesh (in other words, how many cars there are).



Ideally I want to do this in a more general fashion; so I can find all geometry instances that reference the same mesh. I am writing an exporter for SunFlow (which supports mesh instancing) and have it working without mesh instancing, but the files are getting rather large so I was hoping to minimize it a bit

What are you talking about “mesh instancing”? It’s not possible to have Geometries without meshes in jME. It throws an error. Are you talking about the Mesh.java class?

Yea by meshes I mean the Mesh class.



The way Ogre scenes are set up, you have a bunch of XML files that define all the unique meshes in the scene. So if you had a 20 boxes and 30 cars, you would get two XML files (one for car and one for box). Then you have the scene file which says there are 20 boxes and 30 cars, what their transformations are, and contain pointers to the XML files for the mesh. So in the end, the mesh for the car and box is only ever defined once.



Translating this into JME, the XML files in Ogre would be the Mesh class and the 20 or 30 instances would be Geometry classes.



What I don’t know is if JME creates a new Mesh instance for all 30 cars as well as 30 Geometry instances, or if it creates a single Mesh instance and all 30 Geometries point to that 1 Mesh instance. If it does only create 1 Mesh instance, I am wondering how I can get all the Geometry instances which reference that Mesh instance

No. I’m quite sure the ogre xml importer instance a new mesh for each geometry. But it’s so very easy to prove, just print in console all mesh objects so you can see if they are the same or no. Just do it:



[java]

//This recursive method goes down the hierarchy and prints all mesh in console

public void printMeshNames(Spatial root) {

for(Spatial spatial:rootNode.getChildren()) {

if(spatial instanceof Geometry) {

System.out.println(((Geometry)spatial).getMesh());

}

if(spatial instanceof Node) {

printMeshNames((Node)spatial);

}

}

}

[/java]



It will print something ugly for each mesh like @Mesh234324324324 :), then you will know if they are the same or not.

Yep, the importer creates a new mesh for each imported object.



Bummer, I will come up with another solution

@bigstink:



Hey, interesting question you got there!



In the past, I 've also really wanted to know what Geometry belonged to what OgreMesh in XML… In JME, we properly create a new JMEMesh Object and wrap in a new Geometry Object already. So, we don’t know (and care) about which OgreMesh instance the created JMEMesh made by.



Ok, so the idea is you really want to control a bunch of Geometry that has the same instance back in OgreXML…



The only sollution I’ve found is modifying the OrgeLoader (a little bit) !



You know, all JMESpatial , include Geometry and Node come with an ID which in our case generated by OrgeLoader. So, what we do is a little tweak by making a list of which instance’s ID belong to which “primitive object”.



One step further is to create a J3O file, which only save the “primitive object”. Why we want to do that?

The J3O format can save that infos too, but I don’t want to mess with that extra info in the working file, so the good way to do it is produce another version of that J3O file which only contain the instance infos.



How can we do it…



Well, somehow can be a simple work if you have a good look at OrgeLoader code… ( :stuck_out_tongue: I did, but can’t show you the code _ forgive me! )



Later, you want to change (or backup) all the bush in the field which you “did” bring to our main imported J3O and even modified. Look up in the list which “now in the instance J3O file” and the “orginal mesh too”. Then you can change them to default or what ever you want with a replace command ! …



Keep in mind that if you want to make an instance to be “unique” - not related and not connect to other “instance”. You have to change the the list… Can also copy that “uniqued” mesh info to “instance saved” J3O too…!



Maybe other members can point us another good way to do it, :stuck_out_tongue: really don’t know!

blender importer and ogre scene importer do not share the same meshes. It’s really bad. Possibly we can ask for core devs to add this feature.



I decided to load every object separately and clone it.



[java]Geometry geo1 = new Geometry();

Geometry geo2 = geo1.clone(false); //shares the same mesh[/java]





Also, you can have a look at my blenderSceneComposer example:

Test example - http://code.google.com/p/jme-simple-examples/source/browse/JMESimpleExamples/src/Intermediate/BlenderSceneComposer.java

Test scene (works only with this file) - http://jme-simple-examples.googlecode.com/hg/JMESimpleExamples/assets/Models/blender_test_scene/blender_test_scene.blend

I don’t think it’s bad. It probably would cause collision problems and it might be a problem for the SceneExplorer’s scene graph tree.

i think it’s bad. because all meshes are stored in memory and video memory.

There is a caching system in the assetManager, and mesh are shared between geometries.

This means that when you load 10 times the same j3o (or mesh.xml or blend) file, you’ll have 10 geoms but they’ll share the same Mesh instance.

Also when you clone a geometry as @mifth stated the cloned geom will share the same mesh with the original geom.



For identical meshes in the same file this does not work, there is no easy way to know that 2 meshes are identical and should be shared. (maybe comparing each vertex but that would be crazy…).



also sharing meshes has a big drawback though, we have an issue with objects that have skeletal animations. Skeletal animation deforms the mesh on each update, So if 2 geom share the same skeletal animated mesh, they won’t be able to have separated animations.

We are looking into this, one solution would be to implement hardware skinning (skinning is done by the GPU at render time so the mesh is never changed in memory).



@bigstink If you have a scene with lots of identical objects, i recommend batching them instead of cloning them. cloning is good for memory, but it’s not better for performance.

However if objects are spread over a wide area, you might have to partition them (group some nearby object and batch them) to allow them to be culled when they are not in the camera frustum.

Look into the GeometryBatchFactory.

Soon you’ll be even able to move batched geometries with the BatchNode system, that I added some time ago. It’s not finish though but it’s already quite functional.

1 Like

when .blend file has 20 same objects (box01, box01.000, box01.001, box01.002, box01.003…) do they share the same mesh when are loaded?

@mifth said:
when .blend file has 20 same objects (box01, box01.000, box01.001, box01.002, box01.003...) do they share the same mesh when are loaded?

nope.Technically they are separated objects with different meshes in blender too. There is no way to know they are identical except by comparing the vertices.

Blender has two ways of sharing objects, one is Alt-D and another is Shift-D. One of those ways shares the mesh and the other duplicates it. I don’t know how the blender importer handles that case though. If using Ogre3D .scene, then the meshes are properly shared

Is it possible to share meshes and materials by their names? Or use some kind of hash map/code?



In blender, when you press “alt-D” a name of meshes is the same.



Possibly this image will be helpful:

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