User data in ISceneNode?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
speculatius
Posts: 15
Joined: Wed Nov 28, 2007 12:49 pm

User data in ISceneNode?

Post by speculatius »

Hello,

in my program, I use encapsulation of ISceneNode for creating various entities. For example:

Code: Select all

class Car {

  ISceneNode* node;

  //...
};
Then I use CollisionManager for checking some collisions between entities. The problem is, that when collision happens, I know only ISceneNode, which was colliding in some way. But I dont know the entity, to which ISceneNode belongs. I am wondering, if there is a way to do something like this:

Code: Select all

class Car {

  ISceneNode* node;

public:

  Car() {
    node = smgr->addSceneNode(/*...*/);
    node->setUserData(this);
  }

  void fun() {
    // do something useful
  }
};

// and then for example...

ISceneNode* collNode = collisionManager->getSceneNodeAndCollisionPointFromRay(/*...*.);
collNode->getUserData()->fun();
How can I do it without inheriting custom SceneNode and then downcast to it every ISceneNode? How do you design your code?

Thanks...
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

Why not derive a class from ISceneNode?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

No, deriving from ISceneNode makes it quite hard to have e.g. animated meshes in the node of interest. But you can simply make a map of interesting scene nodes, and get the entitity from that map.
speculatius
Posts: 15
Joined: Wed Nov 28, 2007 12:49 pm

Post by speculatius »

First, my entities can live without their graphic representations. In other words, the encapsulated ISceneNode is not always initialized and can change (class Car was only example).

Second, I want to encapsulate more ISceneNodes in one entity, and create new very strict interface, which does not allow programmer to call for example setPosition, or setRotation. These "low-level" matters are hidden behind higher level abstraction of my new entity (for Car it would by method openDoor or setSpeed).

And finally, even if I inherited new CustomSceneNode, CollisionManager will still return to me ordinary ISceneNode. So I had to use static_cast and down-cast it to my CustomSceneNode, and this is not very safe.

...may be I am wrong and I can not see some details, that you are familiar with. Irrlicht tutorials are really useful and easy to learn from. But there are missing one-two tutorials to explain some design patterns, which are recommended to start with :(
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Well, this is the recommended practice. You don't have to expose the ISceneNode interface publicly, so no one needs to know how to setPosition on your node. If you want to avoid scene node pointers, you can use scene node names, IDs, or anything else which identifies the node uniquely. If you need to group things, you have to do this in your app as well. But the map approach would still work here.
speculatius
Posts: 15
Joined: Wed Nov 28, 2007 12:49 pm

Post by speculatius »

Thanks for your replies. Using map is really good idea. The only disadvantage is, that STL has only one map implementation, which can find element in logN (as well as irr::core::map). I hope this will not be problem for big scenes, when many collision occurs in short while. Do you have experience with his approach? Is it proven?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

STl also has hashmap, but logN is usually not something to fear.
Post Reply