Hi,
I'd like to add some functionality to Ogre::SceneNodes (namely to be "grabbable", i.e. the user can grab a node and place it somewhere else). My first idea was to simply inherit from Ogre::SceneNode, but then I get the problem of how to create and destroy new nodes, since they're usually created using the SceneManager, and I don't have a function Ogre::SceneManager::createNewGrabbableSceneNode().
Another way of course is two write a classe GrabbableSceneNode which, in its constructor, creates the scene node and in its destructor destroys it, and then gives access to it using a public getSceneNode() function. However, this means I have to handle GrabbableSceneNodes very differently from normal SceneNodes in my other classes, which I'd like to avoid.
Is there any design which would be a little cleaner? Without having me inherit from Ogre::SceneManager and add the function createNewGrabbableSceneNode to it, that is...
Cheers,
Micha
Inheriting from Ogre::SceneNode
-
- Halfling
- Posts: 87
- Joined: Mon Oct 11, 2010 6:39 pm
- x 12
-
- OGRE Expert User
- Posts: 1119
- Joined: Sat Jan 01, 2011 7:57 pm
- x 216
Re: Inheriting from Ogre::SceneNode
AFAIK you can create nodes without the scene manager.
That is pretty much what Ogre internally does anyway.
You'll just need to be careful to delete all custom nodes before destroying the parent SceneNode, or the SceneManager might try to delete them for you.
Code: Select all
Ogre::SceneNode* parentNode = ...;
MyNode* node = new MyNode;
parentNode->addChild(node);
// add node to some management facility so you can delete it later
// delete the node like this:
parentNode->removeChild(node);
delete node;
You'll just need to be careful to delete all custom nodes before destroying the parent SceneNode, or the SceneManager might try to delete them for you.
-
- Halfling
- Posts: 87
- Joined: Mon Oct 11, 2010 6:39 pm
- x 12
Re: Inheriting from Ogre::SceneNode
Hum, good idea, but no, that doesn't work.
This works:
But this doesn't (mesh won't show up in Scene):
Any other ideas?
This works:
Code: Select all
Ogre::SceneNode* testNode = mSceneMgr->createSceneNode();
mRoomNode->addChild( testNode );
testNode->setPosition( 0, 1, 0 );
Ogre::Entity* ent = testNode->getCreator()->createEntity( "GrabbableSceneNode.mesh" );
testNode->attachObject( ent );
Code: Select all
Ogre::SceneNode* testNode = new Ogre::SceneNode( mSceneMgr );
mRoomNode->addChild( testNode );
testNode->setPosition( 0, 1, 0 );
Ogre::Entity* ent = testNode->getCreator()->createEntity( "GrabbableSceneNode.mesh" );
testNode->attachObject( ent );
-
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 534
Re: Inheriting from Ogre::SceneNode
SceneNode can't be inherited from, unless you make your own scene manager.
The reason is because SceneNode almost never actually exists. When you ask a scene manager to create a node, it actually makes a private custom version. The octree manager makes an OctreeNode, BSP manager makes a BSPNode, Portal Connected Zone Manager makes PCZSceneNode, etc. (OctreeNode being the most common, since the OctreeManager has priority for most scenes)
If you derive a new class from SceneNode and inject it into the scene (so it can actually be rendered), the scene manager will try to treat it as one of the private classes, which will fail.
The reason is because SceneNode almost never actually exists. When you ask a scene manager to create a node, it actually makes a private custom version. The octree manager makes an OctreeNode, BSP manager makes a BSPNode, Portal Connected Zone Manager makes PCZSceneNode, etc. (OctreeNode being the most common, since the OctreeManager has priority for most scenes)
If you derive a new class from SceneNode and inject it into the scene (so it can actually be rendered), the scene manager will try to treat it as one of the private classes, which will fail.
-
- Halfling
- Posts: 87
- Joined: Mon Oct 11, 2010 6:39 pm
- x 12
Re: Inheriting from Ogre::SceneNode
All right, thanks for that answer.
In order to keep the effort required here to a minimum, I tried extending the OctreeSceneManager by inheriting from it (without writing my own plugin). However, this seems to be quite difficult, since the plugin is loaded at runtime only. This means I can't inherit from it...?
All I want to do is to add a "GrabbableSceneNode", i.e. a SceneNode with the extended functionality that it can be switched to "visible (will show a mesh at the position)" and can be moved around by mouse-interaction.
Doesn't sound like such a hard thing to do - does anyone have an idea of how to integrate this without writing a whole new plugin/SceneManager? That really sounds like overkill.
I realize I could write a class which internally stores a SceneNode and a mesh, and use that as my GrabbableSceneNode. But then I'd have to handle SceneNodes and GrabbableSceneNodes quite differently in my code, which is not what I want. I want to be able to replace a SceneNode with a GrabbableSceneNode without the other parts of the code worrying about which kind of SceneNode it is.
In order to keep the effort required here to a minimum, I tried extending the OctreeSceneManager by inheriting from it (without writing my own plugin). However, this seems to be quite difficult, since the plugin is loaded at runtime only. This means I can't inherit from it...?
All I want to do is to add a "GrabbableSceneNode", i.e. a SceneNode with the extended functionality that it can be switched to "visible (will show a mesh at the position)" and can be moved around by mouse-interaction.
Doesn't sound like such a hard thing to do - does anyone have an idea of how to integrate this without writing a whole new plugin/SceneManager? That really sounds like overkill.
I realize I could write a class which internally stores a SceneNode and a mesh, and use that as my GrabbableSceneNode. But then I'd have to handle SceneNodes and GrabbableSceneNodes quite differently in my code, which is not what I want. I want to be able to replace a SceneNode with a GrabbableSceneNode without the other parts of the code worrying about which kind of SceneNode it is.
-
- OGRE Team Member
- Posts: 5429
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1337
Re: Inheriting from Ogre::SceneNode
The OctreeSceneManager is loaded as a plugin. To do what you want, you can link your application against the DLL directly (to inherit from OctreeSceneManager) and replicate the plugin initialization routines so that your custom Derived class is registered without loading the plugin (basically replicate most of what happens inside dllStartPlugin & dllStopPlugin on your own).Germanunkol wrote: I tried extending the OctreeSceneManager by inheriting from it (without writing my own plugin). However, this seems to be quite difficult, since the plugin is loaded at runtime only. This means I can't inherit from it...?
Another even easier way is to create a dll linked to your application, and this DLL is the new plugin.