Inheriting from Ogre::SceneNode

Get answers to all your basic programming questions. No Ogre questions, please!
Germanunkol
Halfling
Posts: 87
Joined: Mon Oct 11, 2010 6:39 pm
x 12

Inheriting from Ogre::SceneNode

Post by Germanunkol »

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
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: Inheriting from Ogre::SceneNode

Post by scrawl »

AFAIK you can create nodes without the scene manager.

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;
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.
Germanunkol
Halfling
Posts: 87
Joined: Mon Oct 11, 2010 6:39 pm
x 12

Re: Inheriting from Ogre::SceneNode

Post by Germanunkol »

Hum, good idea, but no, that doesn't work.

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 );
But this doesn't (mesh won't show up in Scene):

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 );
Any other ideas?
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Inheriting from Ogre::SceneNode

Post by Kojack »

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.
Germanunkol
Halfling
Posts: 87
Joined: Mon Oct 11, 2010 6:39 pm
x 12

Re: Inheriting from Ogre::SceneNode

Post by Germanunkol »

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.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5429
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1337

Re: Inheriting from Ogre::SceneNode

Post by dark_sylinc »

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...?
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).

Another even easier way is to create a dll linked to your application, and this DLL is the new plugin.