Collsion with a irredit scene

Post your questions, suggestions and experiences regarding game design, integration of external libraries here. For irrEdit, irrXML and irrKlang, see the
ambiera forums
fastbit
Posts: 4
Joined: Thu Nov 23, 2006 11:47 am

Collsion with a irredit scene

Post by fastbit »

Hello Folks,

how can I create a pointer (node) to a irredit scene?

I'm trying to add a collisionanimator to the scene and I guess a node is necessary to accomplish.

The function LoadIrrScene returns only TRUE if successfull but no pointer.


Thanx for helping.

Andi
wallytod
Posts: 4
Joined: Fri Nov 03, 2006 8:48 am

Post by wallytod »

I've got the same question to.
My irrScene contain only one mesh (a simply room) and i've got to made the collision between it and the camera.
In IrrEdit i notice that it's possible to add an OctTree (Edit->Insert->OctTree) and to add a CollisionResponse (from the Property menu click on '+' then 'collisionResponse').
Some ideas?
Bye bye,
Wally
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

You want to apply an animator to the entire scene? smgr->getRootSceneNode() will return a pointer to the root of the scene graph. You should be able to put an animator on that. If you want to apply an animator to some node within the scene, you have two options. You can search the scene graph for the node you want [using name, type and/or id]. You could use irrEdit to apply the animator to the object before writing out the .irr file.

The one issue with the second solution is that you can't apply user-created animators from within irrEdit. You could edit the xml with a text editor and add the necessary information directly.

I'm trying to talk with Niko about making it possible to do scene node and scene node animator factories to irrEdit dynamically.

If you are trying to add collision to a specific node in the tree, the best thing to do is search the scene graph for the right node, make sure it is the right type, cast it to the right type, and use that to access the type specific member variables.

Travis
wallytod
Posts: 4
Joined: Fri Nov 03, 2006 8:48 am

Post by wallytod »

Thanks for your answer. I understand.
Unfortunatly i'm new at Irrlicht.. can you help me a little more?

Look, suppose that i've got a scene called "Scene1.irr" and, in it, a single mesh called "Mesh1" (nothing more, no camera, no light).

First I use the loadScene and the getRootSceneNode to retrieve the node

Code: Select all

smgr->loadScene("Scene1.irr")

// add a user controlled camera
smgr->addCameraSceneNodeFPS();

scene::ISceneNode* node = smgr->getRootSceneNode();
Ok, this should be right..
Now... i've got my collision routine..

Code: Select all

	if (node)
	{		
		selector = smgr->createOctTreeTriangleSelector(mesh->getMesh(0), node, 128);
		node->setTriangleSelector(selector);
		selector->drop();
	}


	scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f, -1, 0, 0, true);
	//camera->setPosition(core::vector3df(0,1000,0));
	camera->setPosition(core::vector3df(0,0,0));

	scene::ISceneNodeAnimator* anim = 
			smgr->createCollisionResponseAnimator(selector, 
	camera, 
	core::vector3df(30,50,30),
	core::vector3df(0,-3,0), 
	core::vector3df(0,50,0));
camera->addAnimator(anim);
... but to use it i need to have the "mesh" in the rootnode (to make the substitution of the "getMesh" in the CreateOctTreeTriangleSelector

Code: Select all

smgr->createOctTreeTriangleSelector(mesh->getMesh(0), node, 128);
How can i retrieve this mesh from the root node?


:oops: I'm sorry, too new to irrlicht :wink:

Thanks!
Bye bye,
Wally
nevans06
Posts: 1
Joined: Tue Dec 05, 2006 3:47 pm

Collsion with a irredit scene

Post by nevans06 »

Hi,

Have you resolved this problem? I am also looking to do collision detection with a .irr scene file. Any help Greatly appreciated!

Cheers. :wink:
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

You don't want the root node. The root node doesn't have a mesh. The node that you want is somewhere under the root. You have to find it by searching the scene node graph.

The scene manager provides functions for finding nodes given their id or name. You just have to use them.

Code: Select all

ISceneNode* scene_node = smgr->getSceneNodeFromName("ball1");
if (scene_node && scene_node->getType() == ESNT_MESH)
{
  IMeshSceneNode* node = (IMeshSceneNode*)scene_node;
  // add collision stuff...
}
The other way is to add collision information as the object is read back from the xml file using a data serializer. You would create a class derived from ISceneUserDataSerializer and in the derived class createUserData you would create an attribute, and set a flag indicating whether or not to add collision, and return it. In OnReadUserData you would check the scene node type and the flag. If they both indicate you should do so, you would create collision data for the scene node.

Travis
jingquan
Posts: 222
Joined: Sun Aug 20, 2006 4:10 am
Contact:

Post by jingquan »

How can I do that in C#? I've been trying to figure it out whole afternoon but to no success. Could anyone help please?
atomhamster
Posts: 13
Joined: Wed Feb 14, 2007 3:32 pm
Location: HH | Germany
Contact:

Post by atomhamster »

it looks like it's not yet in C#. i stumbled across this mayself.

i wonder if it would be of help when someone (e.g. me) ports this part and contributes it back to the next release?
liger13
Posts: 119
Joined: Tue Jul 18, 2006 4:17 am

Post by liger13 »

ok umm, im having troubles with this..
i have an .irr file named ship which holds all the objects ect. in my level. inside the Irr is a model named Ship which is a .obj.

so i load up te irr file, get the node from searching then typecast it to IAnimatedMesh*:

Code: Select all

	smgr->loadScene("media/levels/Ship.irr");


	ISceneNode* scene_node = smgr->getSceneNodeFromName("Ship");
	scene::IAnimatedMesh* levelMesh;

	if (scene_node)
	{
		levelMesh = (IAnimatedMesh*)scene_node;
	} 
i then setup a new scene node and triangle selector:

Code: Select all

 scene::ISceneNode* levelNode = 0;
	
	if (levelMesh)
		levelNode = smgr->addOctTreeSceneNode(levelMesh->getMesh(0));

	scene::ITriangleSelector* selector = 0;
	
	if (levelNode)
	{		
		levelNode->setPosition(core::vector3df(0,0,0));

		selector = smgr->createOctTreeTriangleSelector(levelMesh->getMesh(0), levelNode, 128);
		levelNode->setTriangleSelector(selector);
		selector->drop();
	}

	scene::ICameraSceneNode* camera = 
		smgr->addCameraSceneNodeFPS(0, 100.0f, 25.0f, -1, 0, 0, true);
	camera->setPosition(core::vector3df(-30,15,4));

	scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
		selector, camera, core::vector3df(3,1,3),
		core::vector3df(0,-2,0), 
		core::vector3df(0,7,0));
	camera->addAnimator(anim);
	anim->drop();
is this how i do it? it compiles fine but crahes while it loads up the models
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Code: Select all

ISceneNode* scene_node = smgr->getSceneNodeFromName("Ship"); 
scene::IAnimatedMesh* levelMesh; 

if (scene_node) 
{ 
   levelMesh = (IAnimatedMesh*)scene_node; 
} 
You are casting an ISceneNode to an IAnimatedMesh. The two types are not related. When you are using C style casts, you need to be totally sure you are casting the object to the correct type. I'm sure you should be doing something more like this [almost exactly what i posted above]...

Code: Select all

ISceneNode* scene_node = smgr->getSceneNodeFromName("Ship"); 
scene::IAnimatedMesh* levelMesh; 

if (scene_node) 
{
   IAnimatedMeshSceneNode* msn = (IAnimatedMeshSceneNode*)scene_node; 
   levelMesh = scene_node->getAnimatedMesh(); 
} 
liger13
Posts: 119
Joined: Tue Jul 18, 2006 4:17 am

Post by liger13 »

ok thnx alot. im still getting the hang of how Irrlicht works :P
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

That isn't really an Irrlicht specific question, it's more of a general C/C++ question.

Travis
liger13
Posts: 119
Joined: Tue Jul 18, 2006 4:17 am

Post by liger13 »

yah but i forgot that the ISceneNode wasn't an IAnimatedMesh... thats an irrlicht thing.

and im hoping that

Code: Select all

levelMesh = scene_node->getAnimatedMesh(); 
was suposed to be

Code: Select all

levelMesh = msn->getMesh();
also my program crashes on the

Code: Select all

levelMesh = msn->getMesh();
line.

in the debugger it shows that msn connected to the right node that i searched for, but an error comes up and says:
Unhandled exception at 0x20642528 in collision test.exe: 0xC0000005: Access violation reading location 0x20642528.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

There are some differences between the code I originally wrote and the code you are using.

Code: Select all

ISceneNode* scene_node = smgr->getSceneNodeFromName("ball1"); 
if (scene_node && scene_node->getType() == ESNT_MESH) 
{ 
  IMeshSceneNode* node = (IMeshSceneNode*)scene_node; 
  // add collision stuff... 
} 

Code: Select all

ISceneNode* scene_node = smgr->getSceneNodeFromName("Ship"); 
scene::IAnimatedMesh* levelMesh; 

if (scene_node) 
{ 
   IAnimatedMeshSceneNode* msn = (IAnimatedMeshSceneNode*)scene_node; 
   levelMesh = scene_node->getAnimatedMesh(); 
} 
Notice in the first block of code I explicitly check the type of the scene node before I go and cast it. This is the only way that you can tell if it is safe to cast the scene node to a derived scene node type [kinda like dynamic_cast]. The code you provided later doesn't do that. Looking at your code, I see that the actual node is an oct-tree scene node. The oct-tree scene node type is not related to IAnimatedMeshSceneNode, so the cast isn't something that you can legally do.

For oct-tree nodes, you'll want to do something like this.

Code: Select all

ISceneNode* scene_node = smgr->getSceneNodeFromName("Ship");
if (scene_node && scene_node->getType() == ESNT_OCT_TREE) 
{
  core::IAttributes* attribs = fileSystem->createEmptyAttributes();  
  if (attribs)
  {
    scene_node->serializeAttributes(attribs);

    // get the mesh name out
    core::stringc mesh_name = attribs->getAttributeAsString("Mesh");

    attribs->drop();

    // get a mesh from the name
    IMesh* mesh = smgr->getMesh(mesh_name)->getMesh(0);

    ITriangleSelector* selector = smgr->createOctTreeTriangleSelector(mesh->getMesh(0), scene_node, 128); 
      scene_node->setTriangleSelector(selector); 
    selector->drop();
  }
}
Travis
Last edited by vitek on Tue Feb 20, 2007 3:37 am, edited 1 time in total.
liger13
Posts: 119
Joined: Tue Jul 18, 2006 4:17 am

Post by liger13 »

sweet, thnx a whole lot again :)

one quick question, how do u convert between a stringc and a c8 data type?
cause i get the error:
error C2664: 'irr::scene::ISceneManager::getMesh' : cannot convert parameter 1 from 'irr::core::stringc' to 'const irr::c8 *'
Post Reply