Custom Scene Node from Mesh

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
maverickbu
Posts: 17
Joined: Tue Dec 05, 2006 5:07 pm

Custom Scene Node from Mesh

Post by maverickbu »

What's the best/easiest way to do this? Basically, I want to create a custom scene node (I know how to do this much) that would be loaded from a mesh. Clearly in the constructor I can't just say:

Code: Select all

this = mgr->addMeshSceneNode(.....);
So I was wondering the proper way to go about it. It seems I could create the scene node with addMeshSceneNode(), casted to my custom node type, and then run some kind of initialization function on it after, but I was wondering if there was a better way to do it in one shot.
maverickbu
Posts: 17
Joined: Tue Dec 05, 2006 5:07 pm

Post by maverickbu »

OK, after sifting through these forums for hours, I've changed my approach. I'll be creating a player-like class that will include a scene node to represent it. Now here's my new question, if I click my mouse on the scene node that is a member of my new player-like class, how do I get from the selected scene node to the class instance? So basically:

Code: Select all

class Player {
private:
    ISceneNode *sphere;
    int health;
    char *name;
};
If I get the "sphere" from a call like getSceneNodeFromScreenCoordinatesBB(), how do I reference back to the class (Player) that contains it without creating a custom scene node that would hols a pointer to the class in a circular fashion?
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

Why not deriving a player class from ISceneNode ???

Code: Select all

class cPlayerSceneNode : public ISceneNode{
private:
    int health;
    char *name;
}; 
this is just an idea and has not been tested !!! ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

What you could do is when you select the sphere you could test to see if the selected node is equal to the player.sphere, if so then you know it was the player that was selected.
Image Image Image
maverickbu
Posts: 17
Joined: Tue Dec 05, 2006 5:07 pm

Post by maverickbu »

JP wrote:What you could do is when you select the sphere you could test to see if the selected node is equal to the player.sphere, if so then you know it was the player that was selected.
That seems like a good idea, I just wish there was something cleaner. The main reason is that there will potentially be a lot of these nodes in the scene at once (100+, maybe more as i get further into my project), so I will have to iterate through a collection each time I want to make that comparison.
Acki wrote:Why not deriving a player class from ISceneNode ???


Thhats what I was going to do initially, but my "player" node is coming from a mesh file, not actual custom rendering. It seems like a hack to make a custom node for something that really isn't custom. It seems the most logical organization is a "player" class that has the scene noed that represents it graphically as one of its members. This leaves only the problem of the scene node not being aware of which "player" clas object it belongs. This would be resolved by JP's solution, but I worry that it wouldn't scale well should the number of "player" nodes increase.

Thank you for all your help so far though, its giving me a new direction to try. I'd appreciate any further ideas on my specific problem.
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

If you used Acki's suggestion you could then try and cast the selected node as a player node and then if that was successful you'd know it was a player node. I think you can somehow do that in C++!
Image Image Image
KG
Posts: 35
Joined: Wed Jun 07, 2006 12:00 am

Post by KG »

One of the arguments when you create a scene node is the ID of it, which defaults to -1 if you don't give it one. If your player class (or enemy class or whatever) has a pointer to a scene node in it, and you assign that node a unique ID, you can fairly easily find out what scene node is supposed to represent what.
maverickbu
Posts: 17
Joined: Tue Dec 05, 2006 5:07 pm

Post by maverickbu »

KG wrote:One of the arguments when you create a scene node is the ID of it, which defaults to -1 if you don't give it one. If your player class (or enemy class or whatever) has a pointer to a scene node in it, and you assign that node a unique ID, you can fairly easily find out what scene node is supposed to represent what.
That was my first thought, but won't this then conflict with the bit mask I'm using in getSceneNodeFromScreenCoordinatesBB()? If the nodes' ids are all different (in some predefined range I keep track of) I can't use an overall "player" mask or "enemy" mask when using the picking function.
KG
Posts: 35
Joined: Wed Jun 07, 2006 12:00 am

Post by KG »

I'm not certain how to use the bitmask functionality, but I'm reasonably sure that the ID is seperate from the bitmask.
maverickbu
Posts: 17
Joined: Tue Dec 05, 2006 5:07 pm

Post by maverickbu »

I don't think it is, but PLEASE correct me if I'm wrong. I found another thread that lists exactly my problem:

http://irrlicht.sourceforge.net/phpBB2/ ... tity+nodes

I am thinking of using the solution that Electron dubbed "unclean" (in addition to using predefined bitmasks for ids for identiying the "userdata" in the ISceneNode) , mainly because I didn't at all understand what he proposed as the alternative. If someone can explain that alternative to me, I might officially be out of your hair. :oops: :lol:
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

The bitmask that you pass to the scene collision manager is indeed related to the scene node ids. If you pass a mask of 1, then all scene nodes with odd ids will be used in the selection. I made a patch a while back that eliminates the bitmask from the scene collision manager, but it has not been integrated yet.

If you are able, you could maintain a mapping from scene node to user entity using a wrapper struct and an array. Something like this...

Code: Select all

struct SEntry
{
  scene::ISceneNode* Node;
  MyEntityType* Entity;

  bool operator<(const SEntity& other) const
  {  return Node < other.Node; }

  bool operator==(const SEntity& other) const
  { return Entity == other.Entity; }
};

// you would probably put this in a manager class somewhere
core::array<SEntry> Entries;

// every time you create a new entity with a node, you would do this...
SEntry s;
s.Node = node;
s.Entity = entity;

Entries.push_back(s);

// every time you want to find a entity given the scene node
SEntry s;
s.Node = nodeToFindEntityFor;

s32 f = Entires.binary_search(s);
if (f != -1)
{
  // Entries[f].Entity is the entity you were searching for
}

// when the entity is destroyed, you would remove it from the array
SEntry s;
s.Entity = entityToRemove;

s32 f = Entries.linear_reverse_search(s);
if (f != -1)
  Entries.erase(f);
Travis
Saturn
Posts: 418
Joined: Mon Sep 25, 2006 5:58 pm

Post by Saturn »

maverickbu, your proposed solution of not inheriting from scene node and using composition instead is right for the exact reasons you mentioned.

Hybrid is against adding a userdata field to ISceneNode, but the demand is there obviously. So I'd say, go ahead, add it to your irrlicht copy. Everything else is a hack. External maps/lists/whatever are a bad idea imho, because of the complexity they add to the program, since it is the only use such a list has, also custom userdata field is faster for the lookup.
Provide the patch for such field, and it probably gets applied, since community backing for this feature is definitely there.
maverickbu
Posts: 17
Joined: Tue Dec 05, 2006 5:07 pm

Post by maverickbu »

Well, I made the change to ISceneNode.h in my copy of Irrlicht (1.2) and its working like a charm. Its a VERY simple addition, but I'd be happy to post it if anyone is interested. Whats the proper way to create and submit a patch? Or should I just mention it in the code snippet section of the forum and be done with it?

BTW, I am EXTREMELY grateful to all those who took the time to help answer my non-stop questioning. Thank you very much!
monkeycracks
Posts: 1029
Joined: Thu Apr 06, 2006 12:45 am
Location: Tennesee, USA
Contact:

Post by monkeycracks »

I'd post it in the code snippets...but thats just so I can see what was done :D

Could you pm it to me or post it in the code snippets/here?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

In my opinion vitek's proposal is the correct way. Something like MVC architecture and things come into mind. You should not mix the presentation layer with the game logic. Anyway, code snippets or bug forum is for announcements of new features respectively bugs. In order to avoid your patch being lost in the large amount of posts you can also submit a report on the sourceforge trackers on the Irrlicht SF project page. Please make patches against the latest SVN revision (although right now it would be safe to use 1.2 code :wink: )
Post Reply