[SOLVED][Ogre 2] MovableObject, IdType & ObjMemMgr help

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

[SOLVED][Ogre 2] MovableObject, IdType & ObjMemMgr help

Post by al2950 »

As I get round to porting more and more 3rd part Ogre libs I have noticed that they seem to instantiate objects which inherit from MovableObject without doing it from the SceneManager::create* methods. For example Gorilla uses SimpleRenderable and ParticleUniverse uses things like BillboardSet. In Ogre 1.x this was not an issue as the objects were quite basic to instantiate, and Ogre only cared about them if they were added to the sceneManager, however in Ogre 2.0 we have much tighter control over memory and therefore have memory managers, which needs to be provided as a input variable to the constructor.

I would like detail just details the two main points of question around this below (IdType & ObjectMemoryManager)

IdType
IdType is the unique Id of the object and effectively replaces string name. If you are creating an object which you dont tell Ogre about you can set this to whatever you want, however it is good practice to set it to a unique number. Luckily Ogre has a static function for that;

Code: Select all

Id::generateNewId<Type>()
Where 'Type' could be MovableObject, but keep in mind IdType is an unsigned int and so has a limited number of 'IDs'. So if you creating a LOT of these objects you probably want to use your own Type to prevent messing up MovableObjects IDs.

ObjectMemoryManager
Now this is were it gets a little more complicated, although not really that complicated! You must provided an ObjectMemoryManager when instantiating a MovableObject; this is because in the constructor of MovableObject it calls the ObjectMemoryManager to allocate the SoA data of MovableObject. If you are trying to create an object that inherits from MovableObject outside of the SceneManager::create* methods you have 3 options;
  • 1) You can supply it with one of the MemoryManagers from the SceneManager; Eg

    Code: Select all

    sceneMgr->_getEntityMemoryManager(Ogre::SCENE_DYNAMIC)
    This is potentially a bit dangerous, the reason is, for example, when culling Ogre 2.0 works very differently than 1.x. It actually iterates though the EntityMemoryManager and creates a list of 'visible' MovableObjects which are then rendered. So if you use SceneManager EntityMemoryManager, its likely that Ogre will try and render that object for you. This is probably not what you want when you are trying to instantiate MovablObject outside of the SceneManager.
  • 2) Just supply it with a new memory manager for each object;

    Code: Select all

    new MovableObject( 0, new ObjectMemoryManager(), 0)
    This is simple, albeit a bit lazy, but very wasteful and should not really be done!
  • 3) Create your own ObjectMemoryManager and use it for your 'special' objects. This is where I am heading towards for ParticleUniverse and seems to be the tidiest solution, but requires more work :(
I invite anyone to correct me on the points above. I will update them when corrected so others can use them as reference.
Last edited by al2950 on Mon Feb 02, 2015 1:30 pm, edited 1 time in total.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5298
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1279
Contact:

Re: [Ogre 2] MovableObject, IdType & ObjMemMgr HELP!

Post by dark_sylinc »

Everything is spot on.

Perhaps the first reaction is why you need to provide the ID through a call to generateNewId, in other words, why can't this be made automatically inside the MovableObject class?
The reason for this is to be multithreading friendly. Creating MOs from multiple threads would by calling the same static function is either prone to race condition or big lock contention. Therefore, implementations could in theory provide an ID from their own thread-specific pool of IDs. This is why the assignment is external.
2) Just supply it with a new memory manager for each object;

Code: Select all

    new MovableObject( 0, new ObjectMemoryManager(), 0)
This is simple, albeit a bit lazy, but very wasteful and should not really be done!
Be careful with that snippet. You're allocating an ObjectMemoryManager but you will need to delete it yourself at some point, otherwise you'll have a leak.
3) Create your own ObjectMemoryManager and use it for your 'special' objects. This is where I am heading towards for ParticleUniverse and seems to be the tidiest solution, but requires more work
This is the safest approach for special objects, and not as hard as it sounds.

Even Ogre uses dummy memory managers (TBH, I didn't fully think it through...) AutoParamDataSource class has a dummy one to hold the special object "Light mBlankLight".
Even the new Compositor system uses a dummy memory manager for its 2D quad for pass quad passes.

As al2950 said, if an MO lives in a real memory manager obtained from the SceneManager, the SceneManager will try to put this MO on screen after frustum culling, thus things may not go as you want if you need to manually render the MO, or the MO is just a dummy.
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

Re: [Ogre 2] MovableObject, IdType & ObjMemMgr HELP!

Post by al2950 »

dark_sylinc wrote:Everything is spot on.
Yay :D

However I dont think I am correct on this point, after reading some of your replies;
al2950 wrote:IdType is the unique Id of the object and effectively replaces string name
IdType does not necessarily have to be unique and is not necessarily used to look up an object? I am sort of basing this on the following comment in code;

Code: Select all

        /** Retrieves a SceneNode based on it's ID from the scene graph.
        @remarks
            @note Returns null if the ID does not exist
            @note It is a linear search O(N), retrieves the first node found
            with that name (it's not unique)
        */
        virtual_l1 SceneNode* getSceneNode( IdType id );
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5298
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1279
Contact:

Re: [Ogre 2] MovableObject, IdType & ObjMemMgr HELP!

Post by dark_sylinc »

That's a documentation bug. The getSceneNode had many overloads which were removed. Originally there was an overload that would look by name string and that documentation is obviously from that removed variation.
serkanergun
Kobold
Posts: 25
Joined: Thu Mar 29, 2007 6:50 pm

Re: [Ogre 2] MovableObject, IdType & ObjMemMgr HELP!

Post by serkanergun »

We are trying to port our project to Ogre 2.0 and the first thing we noticed is the introduction of Id's and ObjMemMgr's. We have custom classes derived from SimpleRenderables which will need frustum culling. However, We don't want to make them SceneManager specific, we want to be able to detach and attach to any SceneNode. If we go with the manual ObjectMemoryMgr approach, do we need to do anything else to have them frustum culled and rendered accordingly or would attaching to a SceneNode be sufficient?
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

Re: [Ogre 2] MovableObject, IdType & ObjMemMgr HELP!

Post by al2950 »

If you use your own memory manager you will have to do your own frustum culling and manually add them to the render queue. However, in your case, I am not sure why you would NOT use the scene manager memory managers. You can still attach your object to any scene node. Could you explain your problem in a bit more detail as I am slightly confused what you are trying to do. Do you have multiple scene managers?
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5298
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1279
Contact:

Re: [Ogre 2] MovableObject, IdType & ObjMemMgr HELP!

Post by dark_sylinc »

serkanergun wrote:However, We don't want to make them SceneManager specific, we want to be able to detach and attach to any SceneNode.
By attaching to a SceneNode, you're implicitly making the MovableObject SceneManager-specific; since the SceneNode is owned by a specific SceneManager.
If what you means is that you want a MovableObject to be detached then attached to multiple SceneNodes belonging to different SceneManagers, you can use ObjectMemoryManager::migrateTo to migrate all the data to a memory manager that belongs to a different SceneManager.

Mind you, such behavior (detaching then reattaching, migrating memory managers), if frequent, would be slow for rendering both in 2.0 and 1.x; you're probably better off creating multiple MovableObjects, one per SceneManager.

Ogre 2.0 in particular has been optimized under the assumption that scene hierarchy changes are not common (i.e. you don't perform lots of creation and destruction of nodes and objects per frame) as we bake as much information as possible outside of the render loop.
Constantly reattaching and migrating lots of objects could trigger worst case scenarios.
serkanergun wrote:If we go with the manual ObjectMemoryMgr approach, do we need to do anything else to have them frustum culled and rendered accordingly or would attaching to a SceneNode be sufficient?
Once a MovableObject belongs to a valid ObjectMemoryMgr (i.e. the returned value from SceneManager::_getEntityMemoryManager) and is attached to a SceneNode, it will render. (make sure mObjectData.mLocalAabb[mObjectData.mIndex] is populated with the correct local-space AABB; so should mObjectData.mLocalRadius[mObjectData.mIndex])

While not attached to a SceneNode, a MovableObject doesn't have a transform (pos, rotation, scale), thus there's not enough information to frustum cull or render.
Even if attached, if the MovableObject doesn't belong to a valid ObjectMemoryManager (i.e. you used a dummy you created yourself), the SceneManager will not "see" it; and thus cannot frustum cull or render.
Post Reply