[osg-users] Referencing loaded models
Hi, This might be a total beginners question, but I didn't find any sufficient information in the forum nor in the documentation. Let's assume I have a scene composed of some models, let's say a trees/houses which are the same model. If I want to load the model once and use it multiple times (with different transform/state) what is the best way to handle this. The naive way would be to load the model for each instance and add it to the scene graph. But there must be some way to share the node. What I had in mind is to load the model exactly once and sort of clone it in a way that the geometry/textures are still shared and only referenced multiple times. As I understand DRAW_INSTANCED, it performs something like this on GPU side. But what I want is more like a logical structure. I'm sort of lost. If I naively take a loaded model and just add it to the scene-graph with different transform nodes as parent it is still displayed only once :-( something like: osg::Node* loadedModel = osgDB::load(); osg::Node* rootNode = new osg::Group; // create some transforms for different instances osg::Transform* instance_1 = new osg::PositudeAttitudeTransfrom ... set some position to instance_1 osg::Transform* instance_2 = new osg::PositudeAttitudeTransfrom ... set some position to instance_2 osg::Transform* instance_3 = new osg::PositudeAttitudeTransfrom ... set some position to instance_3 //now attach the instances to the graph rootNode.addChild(instance_1); rootNode.addChild(instance_2); rootNode.addChild(instance_3); Shouldn't that work? cheers Sebastian ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
I does this: const static osg::ref_ptr osg::Node staticNode = osgDB::readNodeFile(Shapes/Shape.osg); then for each required instance: const static osg::ref_ptr osg::Node nodeCopy = (osg::Node*)staticNode-clone(osg::CopyOp::DEEP_COPY_NODES); -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=12808#12808 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Hi Paul, but isn't this just cloning? With other words: is there something that is shared between the nodes? Plus, i would favour something not involving static data ;-) cheers Sebastian I does this: const static osg::ref_ptr osg::Node staticNode = osgDB::readNodeFile(Shapes/Shape.osg); then for each required instance: const static osg::ref_ptr osg::Node nodeCopy = (osg::Node*)staticNode-clone(osg::CopyOp::DEEP_COPY_NODES); -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=12808#12808 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Is the only way i worked out that works, though i belive there is a tutorial in the turorial section. Got to ask though, whats wrong with using static? -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=12812#12812 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Hi Sebastian, Unless you explicitly ask the osg to clone your model's geometry it will share the geometry by default. It simply stores a pointer to the loaded model's vertices etc. So the below code should work for you. You can also set osgDB to cache the model in memory so that if you ever call osgDB::load() with the same path and filename it will just return a pointer to the cached model rather than reloading it. osg::Group* rootNode = new osg::Group; osg::Node* loadedModel = osgDB::load(); osg::PositudeAttitudeTransfrom* instance_1 = new osg::PositudeAttitudeTransfrom instance_1-setPosition( 10.f, 0.0, 0.0); instance_1-addChild(loadedModel); osg::PositudeAttitudeTransfrom* instance_2 = new osg::PositudeAttitudeTransfrom instance_2-setPosition( 20.f, 0.0, 0.0); instance_2-addChild(loadedModel); osg::PositudeAttitudeTransfrom* instance_3 = new osg::PositudeAttitudeTransfrom instance_3-setPosition( 30.f, 0.0, 0.0); instance_3-addChild(loadedModel); //now attach the instances to the graph rootNode-addChild(instance_1); rootNode-addChild(instance_2); rootNode-addChild(instance_3); viewer.setSceneData(rootNode); Regards, Kim. From: osg-users-boun...@lists.openscenegraph.org on behalf of Sebastian Messerschmidt Sent: Sat 23/05/2009 14:42 To: OpenSceneGraph Users Subject: [osg-users] Referencing loaded models Hi, This might be a total beginners question, but I didn't find any sufficient information in the forum nor in the documentation. Let's assume I have a scene composed of some models, let's say a trees/houses which are the same model. If I want to load the model once and use it multiple times (with different transform/state) what is the best way to handle this. The naive way would be to load the model for each instance and add it to the scene graph. But there must be some way to share the node. What I had in mind is to load the model exactly once and sort of clone it in a way that the geometry/textures are still shared and only referenced multiple times. As I understand DRAW_INSTANCED, it performs something like this on GPU side. But what I want is more like a logical structure. I'm sort of lost. If I naively take a loaded model and just add it to the scene-graph with different transform nodes as parent it is still displayed only once :-( something like: osg::Node* loadedModel = osgDB::load(); osg::Node* rootNode = new osg::Group; // create some transforms for different instances osg::Transform* instance_1 = new osg::PositudeAttitudeTransfrom ... set some position to instance_1 osg::Transform* instance_2 = new osg::PositudeAttitudeTransfrom ... set some position to instance_2 osg::Transform* instance_3 = new osg::PositudeAttitudeTransfrom ... set some position to instance_3 //now attach the instances to the graph rootNode.addChild(instance_1); rootNode.addChild(instance_2); rootNode.addChild(instance_3); Shouldn't that work? cheers Sebastian ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org winmail.dat* To view the terms under which this email is distributed, please go to http://www.hull.ac.uk/legal/email_disclaimer.html *___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
The reason i chose static is so the model is loaded only once when the first class instance is created. You could however create this node non-static but you must make sure you load it only once, like put it in another class and referance to it or something. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=12813#12813 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Kim C Bale wrote: Hi Sebastian, Unless you explicitly ask the osg to clone your model's geometry it will share the geometry by default. It simply stores a pointer to the loaded model's vertices etc. So the below code should work for you. You can also set osgDB to cache the model in memory so that if you ever call osgDB::load() with the same path and filename it will just return a pointer to the cached model rather than reloading it. osg::Group* rootNode = new osg::Group; osg::Node* loadedModel = osgDB::load(); osg::PositudeAttitudeTransfrom* instance_1 = new osg::PositudeAttitudeTransfrom instance_1-setPosition( 10.f, 0.0, 0.0); instance_1-addChild(loadedModel); osg::PositudeAttitudeTransfrom* instance_2 = new osg::PositudeAttitudeTransfrom instance_2-setPosition( 20.f, 0.0, 0.0); instance_2-addChild(loadedModel); osg::PositudeAttitudeTransfrom* instance_3 = new osg::PositudeAttitudeTransfrom instance_3-setPosition( 30.f, 0.0, 0.0); instance_3-addChild(loadedModel); //now attach the instances to the graph rootNode-addChild(instance_1); rootNode-addChild(instance_2); rootNode-addChild(instance_3); viewer.setSceneData(rootNode); Regards, Kim. That works fine unless your pickick with the mouse. Is you select any of the nodes it always selects the first node :( So i had to make a clone for each instance. Guess it depense if your picking... -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=12815#12815 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Could you not check the name of parent node to identify the instance of the child? I might be wrong I haven't used the picking functionality for a while. K. From: osg-users-boun...@lists.openscenegraph.org on behalf of Paul Griffiths Sent: Sat 23/05/2009 15:39 To: osg-users@lists.openscenegraph.org Subject: Re: [osg-users] Referencing loaded models Kim C Bale wrote: Hi Sebastian, Unless you explicitly ask the osg to clone your model's geometry it will share the geometry by default. It simply stores a pointer to the loaded model's vertices etc. So the below code should work for you. You can also set osgDB to cache the model in memory so that if you ever call osgDB::load() with the same path and filename it will just return a pointer to the cached model rather than reloading it. osg::Group* rootNode = new osg::Group; osg::Node* loadedModel = osgDB::load(); osg::PositudeAttitudeTransfrom* instance_1 = new osg::PositudeAttitudeTransfrom instance_1-setPosition( 10.f, 0.0, 0.0); instance_1-addChild(loadedModel); osg::PositudeAttitudeTransfrom* instance_2 = new osg::PositudeAttitudeTransfrom instance_2-setPosition( 20.f, 0.0, 0.0); instance_2-addChild(loadedModel); osg::PositudeAttitudeTransfrom* instance_3 = new osg::PositudeAttitudeTransfrom instance_3-setPosition( 30.f, 0.0, 0.0); instance_3-addChild(loadedModel); //now attach the instances to the graph rootNode-addChild(instance_1); rootNode-addChild(instance_2); rootNode-addChild(instance_3); viewer.setSceneData(rootNode); Regards, Kim. That works fine unless your pickick with the mouse. Is you select any of the nodes it always selects the first node :( So i had to make a clone for each instance. Guess it depense if your picking... -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=12815#12815 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org winmail.dat* To view the terms under which this email is distributed, please go to http://www.hull.ac.uk/legal/email_disclaimer.html *___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Kim C Bale wrote: Could you not check the name of parent node to identify the instance of the child? I might be wrong I haven't used the picking functionality for a while. K. Tried that but it always gives the parent node of the first instance. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=12818#12818 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Thanks Kim and Paul, My problem seems to be elsewhere. Me stupid hasn't tried his own minimal example. In my application I sort of wrap certain scene elements (like models) for an more abstract interface to loaded entities (as the models geometrical/graphical representation is only one aspect). So I reckon, there must be something wrong with my logic, rather than with the sharing principle. And yes, as far as picking is a concern, one could always put some top node (like the transform is in my case) above the reference. At least there are two lessons learned for me: 1. double check you stupid questions on behalf on a simple example, as I didn't ;-) 2. ask questions to assure yourself ;-) cheers thanks Sebastian Could you not check the name of parent node to identify the instance of the child? I might be wrong I haven't used the picking functionality for a while. K. From: osg-users-boun...@lists.openscenegraph.org on behalf of Paul Griffiths Sent: Sat 23/05/2009 15:39 To: osg-users@lists.openscenegraph.org Subject: Re: [osg-users] Referencing loaded models Kim C Bale wrote: Hi Sebastian, Unless you explicitly ask the osg to clone your model's geometry it will share the geometry by default. It simply stores a pointer to the loaded model's vertices etc. So the below code should work for you. You can also set osgDB to cache the model in memory so that if you ever call osgDB::load() with the same path and filename it will just return a pointer to the cached model rather than reloading it. osg::Group* rootNode = new osg::Group; osg::Node* loadedModel = osgDB::load(); osg::PositudeAttitudeTransfrom* instance_1 = new osg::PositudeAttitudeTransfrom instance_1-setPosition( 10.f, 0.0, 0.0); instance_1-addChild(loadedModel); osg::PositudeAttitudeTransfrom* instance_2 = new osg::PositudeAttitudeTransfrom instance_2-setPosition( 20.f, 0.0, 0.0); instance_2-addChild(loadedModel); osg::PositudeAttitudeTransfrom* instance_3 = new osg::PositudeAttitudeTransfrom instance_3-setPosition( 30.f, 0.0, 0.0); instance_3-addChild(loadedModel); //now attach the instances to the graph rootNode-addChild(instance_1); rootNode-addChild(instance_2); rootNode-addChild(instance_3); viewer.setSceneData(rootNode); Regards, Kim. That works fine unless your pickick with the mouse. Is you select any of the nodes it always selects the first node :( So i had to make a clone for each instance. Guess it depense if your picking... -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=12815#12815 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org * To view the terms under which this email is distributed, please go to http://www.hull.ac.uk/legal/email_disclaimer.html * ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Then something else is wrong. The nodePath of your hits should be accurate to the specific node that was picked. This is pretty routine stuff as anyone using a scene graph is likely to have nodes scattered in at least dozens of places around their scene graphs. -Paul Paul Griffiths wrote: Kim C Bale wrote: Could you not check the name of parent node to identify the instance of the child? I might be wrong I haven't used the picking functionality for a while. K. Tried that but it always gives the parent node of the first instance. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=12818#12818 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Hi Paul, Tried that but it always gives the parent node of the first instance. If that's the case, then you're probably using getParent(0) to go up in the graph, instead of using the intersection's node path. Remember, the model can have a whole hierarchy inside too, and the intersection will give you the Geode that was intersected. So you might have to go up a few levels in the node path before getting to the root of the model, and at that point the parent of that (still in the node path) should be the unique transform for the instance that was intersected. You can identify the root of your model in different ways, either with a name, a description, a piece of user data, ... Hope this helps, J-S -- __ Jean-Sebastien Guayjean-sebastien.g...@cm-labs.com http://www.cm-labs.com/ http://whitestar02.webhop.org/ ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Skylark wrote: If that's the case, then you're probably using getParent(0) to go up in the graph, instead of using the intersection's node path. Yes, i am going osg::Node* node = hitr-nodePath.back(); if (node node-getNumParents() 0) { node = node-getParent(0); ... } now im trying this but its crashing: osg::Node* node; while (!hitr-nodePath.empty() (node = hitr-nodePath.back()) != NULL) { // check the node ... } -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=12822#12822 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Found the fault, forgot to add hitr-nodePath.pop_back() at the end of each itteration -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=12825#12825 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Referencing loaded models
Hi Paul, Yes, i am going osg::Node* node = hitr-nodePath.back(); if (node node-getNumParents() 0) { node = node-getParent(0); ... } Yes, well no wonder you're always getting the same parent... :-) now im trying this but its crashing: What you want to do is walk the path up from the last node in the node path. for (unsigned int i = nodePath.size() - 1; i = 0; --i) { // check the node } or use iterators (you can use rbegin(), rend(), ... - check the STL documentation). And as I said, it might not be the first node up from the one you got in the intersection that will be different, if your model has a multi-level hierarchy you'll need to go up more than that. Know your graph... And you can use osgDB::writeNodeFile(*root, saved_scene.osg); to write the whole scene graph to a file and examine it. It's very useful to know what to expect and how the graph is laid out. Hope this helps, J-S -- __ Jean-Sebastien Guayjean-sebastien.g...@cm-labs.com http://www.cm-labs.com/ http://whitestar02.webhop.org/ ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org