node deletion

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.
kennypu666
Posts: 26
Joined: Thu Apr 26, 2007 6:57 am

node deletion

Post by kennypu666 »

hi, i need help deleting a node. when i use delete node, or node->remove(), my game crashes. can anybody help me? a different way of deletion or advise will help. I will post the code if needed. thanks
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

You should _never_ call delete node, assuming node is a ISceneNode or some derived type. The scene nodes are reference counted, so you should be sure to grab() or drop() them as necessary, and remove() them from the scene graph.

You should not call node->remove() if the node is part of a list that is currently being iterated over [i.e. while the node is being rendered]. If you remove the node from the list that is being iterated over, that can cause the list to be accessed in a bad way.

You should also be sure that if you remove() a node that you remove all references to that scene node that you may have. If you are keeping an array of pointers to the 'bad guys', and you remove one of them, you should be sure to remove that same node from your array of bad guys.

Travis
kennypu666
Posts: 26
Joined: Thu Apr 26, 2007 6:57 am

Post by kennypu666 »

thank you for the reply vitek, if you don't mind, I have a question. How can I use an array to create multiple nodes? I've done it in a different programming language other than c++ so i'm not sure how to do it in here. Also after i create an array for a node, how do i delete each one properly? thanks
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

From your last post, it sounds like you are under the impression that you should be keeping scene nodes in an array. That is not what I'm saying. You can do it if it makes sense for your application, but if it is not necessary, it just makes things more complicated. I suggest you don't add an array of scene nodes unless you really need to do it.

If your application is crashing after you use node->remove(), it is likely that some part of your code is using the node after it has been removed. One situation where this can happen if you are using triangle selectors for collision and you don't remove the triangle selector for that node.
How can I use an array to create multiple nodes?
Maybe this is just a language issue, but you don't use an array to _create_ nodes. An array can be used to hold node pointers. Example...

Code: Select all

core::array<scene::ISceneNode*> SceneNodes;

// create a node and add it to the array
SceneNodes.push_back(smgr->addMeshSceneNode(Mesh));
Also after i create an array for a node, how do i delete each one properly?
You would remove it from the array, and then you would remove the node from the scene just like you would if it was not in an array.

Code: Select all

// assuming 'node' is the scene node you want to remove

// remove the node from the array
s32 found = SceneNodes.reverse_linear_search(node);
if (found != -1)
  SceneNodes.erase(found);

// remove the node from the scene
node->remove();
Travis
kennypu666
Posts: 26
Joined: Thu Apr 26, 2007 6:57 am

thankx

Post by kennypu666 »

thank you very much, ill use them for reference. This is offtopic, but is it possible to create another window, or 2 views inside one window with 2 cameras, one doing its tink and the other looking at the other camera? I wanted to do this so that i can make sure I can see the mesh that is a child to the first camera.

heres a visual aid if hard to understand.lol:

Image
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Of course you can. Either use the splitscreen technique with view ports or use separate windows and pass the window ids via endScene.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Or rendertotexture if thats your kinda thing :P
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, would also work, but would require three render passes instead of the two for both other techniques (the final texture has to be presented). However, since RTT should not be as slow as rendering to a screen the slowdown might be neglectible.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

If you're interested, you could use the CGUIViewport class that I wrote a while back. You can find the source code here.

You would have to write a tiny bit of code to switch the active camera before drawing the gui.

Code: Select all

if (driver->beginScene(...))
{
  smgr->setActiveCamera(camera2);
  smgr->drawAll();

  smgr->setActiveCamera(camera1);
  gui->drawAll();

  driver->endScene();
}
The one issue that you will run into would be getting the correct camera, or both cameras, to process input events. Only one camera will receive input events from the scene manager. The one that is active when the device->run() call is made will be the one that responds to keyboard/mouse input.

Travis
kennypu666
Posts: 26
Joined: Thu Apr 26, 2007 6:57 am

Post by kennypu666 »

thanxs everybody for your replys. They are helping me a lot. I have a nother quetion, and im afraid this one is too noobie. well anyways, in addCameraSceneNodeFPS(),there is a EKA_JUMP_UP,but i'm not sure how to exactly use it. can anybody show me a example code, or snippet that makes the scene node jump? thanks
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

By default the J key should make the camera jump. You need to use a collision response animator on the camera to apply gravity so that the camera will fall. Basically...

Code: Select all

// create a camera, by default the j key makes it jump
  // create a camera, by default the j key makes it jump 
  scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 100, 500, -1, 0, 0, false, .5f);

  // load a terrain 
  scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode("../../media/terrain-heightmap.bmp", 0, -1,
    core::vector3df(0, 0, 0),
    core::vector3df(0, 0, 0),
    core::vector3df(10, .5f, 10)); 
  if (terrain) 
  { 
    terrain->setMaterialTexture(0, driver->getTexture("../../media/terrain-texture.jpg")); 
    terrain->setMaterialFlag(video::EMF_LIGHTING, false);

    scene::ITriangleSelector* selector = smgr->createTerrainTriangleSelector(terrain); 
      terrain->setTriangleSelector(selector); 
    selector->drop(); 

    core::vector3df pos(terrain->getBoundingBox().getCenter());
    camera->setPosition(pos);

    // add a collision response animator to the camera so it will fall after jump 
    scene::ISceneNodeAnimatorCollisionResponse* animator = 
      smgr->createCollisionResponseAnimator(terrain->getTriangleSelector(), camera, core::vector3df(30, 60, 30), core::vector3df(0,-1.f,0)); 
      camera->addAnimator(animator); 
    animator->drop(); 
  }
If you want to change the keys that are used to control the camera, you need to create a key map.

Code: Select all

  SKeyMap keyMap[9];
  keyMap[0].Action = EKA_MOVE_FORWARD;
  keyMap[0].KeyCode = KEY_UP;
  keyMap[1].Action = EKA_MOVE_FORWARD;
  keyMap[1].KeyCode = KEY_KEY_W;

  keyMap[2].Action = EKA_MOVE_BACKWARD;
  keyMap[2].KeyCode = KEY_DOWN;
  keyMap[3].Action = EKA_MOVE_BACKWARD;
  keyMap[3].KeyCode = KEY_KEY_S;

  keyMap[4].Action = EKA_STRAFE_LEFT;
  keyMap[4].KeyCode = KEY_LEFT;
  keyMap[5].Action = EKA_STRAFE_LEFT;
  keyMap[5].KeyCode = KEY_KEY_A;

  keyMap[6].Action = EKA_STRAFE_RIGHT;
  keyMap[6].KeyCode = KEY_RIGHT;
  keyMap[7].Action = EKA_STRAFE_RIGHT;
  keyMap[7].KeyCode = KEY_KEY_D;

  keyMap[8].Action = EKA_JUMP_UP;
  keyMap[8].KeyCode = KEY_KEY_J;

  scene::ICameraSceneNode* camera = sm->addCameraSceneNodeFPS(0, 100.0f, 400.0f, -1, keyMap, 9, false, .5f);
Travis
Last edited by vitek on Tue May 29, 2007 4:27 pm, edited 1 time in total.
kennypu666
Posts: 26
Joined: Thu Apr 26, 2007 6:57 am

Post by kennypu666 »

I have all the gravity and animators added, but it still wont jump. the only difference between your example and my code is that in smgr->createCollisionResponseAnimator(), yours is would be;

Code: Select all

smgr->createCollisionResponseAnimator(node->getTriangleSelector(),cam);
while mine is;

Code: Select all

 smgr->createCollisionResponseAnimator(selector,cam,core::vector3df(30,50,30),core::vector3df(0,-1,0),core::vector3df(0,50,0)); 
I think i got that from one of the examples. I tried using your code but I couldnt jump either. This is my camera and the keymap;

Code: Select all

	///////////////////////////////////////////////camera//////////////////////////
	SKeyMap keyMap[5];
			keyMap[0].Action = EKA_MOVE_FORWARD;
			keyMap[0].KeyCode = KEY_KEY_W;

			keyMap[1].Action = EKA_MOVE_BACKWARD;
			keyMap[1].KeyCode = KEY_KEY_S;

			keyMap[2].Action = EKA_STRAFE_LEFT;
			keyMap[2].KeyCode = KEY_KEY_A;

			keyMap[3].Action = EKA_STRAFE_RIGHT;
			keyMap[3].KeyCode = KEY_KEY_D;

			keyMap[4].Action = EKA_JUMP_UP;
			keyMap[4].KeyCode = KEY_SPACE;
//////////////////////////////////////////camera//////////////////////////////////////////////
  	scene::ICameraSceneNode* cam=smgr->addCameraSceneNodeFPS(0,100.0f,500.0f,-1,keyMap,5,false,0.0f);
    cam->setFarValue(4000.0f);
    cam->setPosition(core::vector3df(200.0f,0.0f,200.0f)); //    
thank you for your help though.ken
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Whoops. I forgot that you need to supply a jumpspeed to addCamerasceneNodeFPS() call. The last parameter is the jumpspeed. I've updated and tested the source code in my previous post.

Travis
kennypu666
Posts: 26
Joined: Thu Apr 26, 2007 6:57 am

Post by kennypu666 »

thank you very much for your help!! it works now, i dont have any question for now :oops: thanks very mucho for all your replys
kennypu666
Posts: 26
Joined: Thu Apr 26, 2007 6:57 am

sorry

Post by kennypu666 »

..sorry guys, i thought i can figure it out by my self but aprerently not. I have question for the array of nodes part (sorry i think i wasnt paying enough attention to what you wrote vitek). First question is, on the second snippet, it says;

Code: Select all

 // assuming 'node' is the scene node you want to remove 

// remove the node from the array 
s32 found = SceneNodes.reverse_linear_search(node); 
if (found != -1) 
  SceneNodes.erase(found); 

// remove the node from the scene 
node->remove(); 
How did the node in for example reverse_linear_search(node); <- get there, and my other question is, did u make a mistake and is it suppose to be linear_reverse_search(node);? sorry for all the question.
Post Reply