Suggested addition to example 15.LoadIrrFile

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Suggested addition to example 15.LoadIrrFile

Post by rogerborg »

I guess that most users will want to do collision detection on their IrrEdit scenes, and AFAICT there's no example of how to do that in the tutorials.

I suggest adding it to example 15, and I've swiped Travis' code from here to do it.

To make it easier on the app, I also suggest that we introduce an ESNT_ANY type so that all scene nodes can be retrieved with one getSceneNodesFromType() call. The recursion through the scene is already in CSceneManager, so why burden users with having to do it themselves?

Code: Select all

Index: examples/15.LoadIrrFile/main.cpp
===================================================================
--- examples/15.LoadIrrFile/main.cpp	(revision 1262)
+++ examples/15.LoadIrrFile/main.cpp	(working copy)
@@ -64,17 +64,81 @@
 	*/
 
 	// load the scene
-
 	smgr->loadScene("../../media/example.irr");
 
-	/* 
-	That was it already. Now add a camera and draw the scene
-	*/
+	// Now we'll create a camera, and give it a collision response animator
+	// that's built from the mesh nodes in the scene we just loaded.
+	scene::ICameraSceneNode * camera = smgr->addCameraSceneNodeFPS(0, 50, 100);
 
-	// add a user controlled camera
+	// Create a meta triangle selector to hold several triangle selectors.
+	scene::IMetaTriangleSelector * meta = smgr->createMetaTriangleSelector();
 
-	smgr->addCameraSceneNodeFPS();
+	// Now we will find all the nodes in the scene and create triangle 
+	// selectors for all suitable nodes.  Typically, you would want to make a
+	// more informed decision about which nodes to performs collision checks
+	// on; you could capture that information in the node name or Id.
+	core::array<scene::ISceneNode *> nodes;
+	smgr->getSceneNodesFromType(scene::ESNT_ANY, nodes); // Find all nodes
 
+	for(u32 i  = 0; i < nodes.size(); ++i)
+	{
+		scene::ISceneNode * node = nodes[i];
+		scene::ITriangleSelector * selector = 0;
+
+		switch(node->getType())
+		{
+		case scene::ESNT_CUBE:
+		case scene::ESNT_ANIMATED_MESH: // Because the selector won't animate with the mesh,
+			// and is only being used for camera collision, we'll just use an approximate 
+			// bounding box instead of ((scene::IAnimatedMeshSceneNode*)node)->getMesh(0)
+			selector = smgr->createTriangleSelectorFromBoundingBox(node);
+			break;
+
+		case scene::ESNT_MESH:
+		case scene::ESNT_SPHERE: // Derived from IMeshSceneNode
+			selector = smgr->createTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node);
+			break;
+
+		case scene::ESNT_TERRAIN:
+			selector = smgr->createTerrainTriangleSelector((scene::ITerrainSceneNode*)node);
+			break;
+
+		case scene::ESNT_OCT_TREE:
+			selector = smgr->createOctTreeTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node);
+			break;
+
+		default:
+			// Don't create a selector for this node type
+			break;
+		}
+
+		if(selector)
+		{
+			// Add it to the meta selector, which will take a reference to it
+			meta->addTriangleSelector(selector);
+			// And drop my reference to it, so that the meta selector owns it.
+			selector->drop();
+		}
+	}
+
+	// Now that the mesh scene nodes have had triangle selectors created and added
+	// to the meta selector, create a collision response animator from that meta selector.
+	scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
+		meta, camera, core::vector3df(5,5,5),
+		core::vector3df(0,0,0));
+	meta->drop(); // I'm done with the meta selector now
+
+	camera->addAnimator(anim);
+	anim->drop(); // I'm done with the animator now
+
+	// And set the camera position so that it doesn't start off stuck in the geometry
+	camera->setPosition(core::vector3df(0.f, 20.f, 0.f));
+
+	// Point the camera at the cube node, by finding the first node of type ESNT_CUBE
+	scene::ISceneNode * cube = smgr->getSceneNodeFromType(scene::ESNT_CUBE);
+	if(cube)
+		camera->setTarget(cube->getAbsolutePosition()); 
+	
 	// and draw everything.
 
 	int lastFPS = -1;
Index: include/ESceneNodeTypes.h
===================================================================
--- include/ESceneNodeTypes.h	(revision 1262)
+++ include/ESceneNodeTypes.h	(working copy)
@@ -76,7 +76,11 @@
 		ESNT_MD3_SCENE_NODE	= MAKE_IRR_ID('m','d','3','_'),
 
 		//! Unknown scene node
-		ESNT_UNKNOWN        = MAKE_IRR_ID('u','n','k','n')
+		ESNT_UNKNOWN        = MAKE_IRR_ID('u','n','k','n'),
+
+		//! Will match with any scene node when checking types
+		ESNT_ANY            = MAKE_IRR_ID('a','n','y','_')
+
 	};
 
 
Index: include/ISceneManager.h
===================================================================
--- include/ISceneManager.h	(revision 1262)
+++ include/ISceneManager.h	(working copy)
@@ -862,7 +862,7 @@
 		virtual ISceneNode* getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start=0) = 0;
 
 		//! returns scene nodes by type.
-		/** \param type: Type of scene node to find.
+		/** \param type: Type of scene node to find (ESNT_ANY will return all child nodes).
 		\param outNodes: array to be filled with results.
 		\param start: Scene node to start from. All children of this scene
 		node are searched. If null is specified, the root scene node is
Index: source/Irrlicht/CSceneManager.cpp
===================================================================
--- source/Irrlicht/CSceneManager.cpp	(revision 1262)
+++ source/Irrlicht/CSceneManager.cpp	(working copy)
@@ -1559,7 +1559,7 @@
 	if (start == 0)
 		start = getRootSceneNode();
 
-	if (start->getType() == type)
+	if (start->getType() == type || ESNT_ANY == type)
 		return start;
 
 	ISceneNode* node = 0;
@@ -1582,7 +1582,7 @@
 	if (start == 0)
 		start = getRootSceneNode();
 
-	if (start->getType() == type)
+	if (start->getType() == type || ESNT_ANY == type)
 		outNodes.push_back(start);
 
 	const core::list<ISceneNode*>& list = start->getChildren();
Last edited by rogerborg on Tue Feb 26, 2008 2:59 pm, edited 3 times in total.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

Hear hear! We do get lots of questions on how to do this so it should definetly be covered in the tutorials. I guess if the .irr file has only one mesh it should probably be updated a bit to show what you can do with irrEdit...
Image Image Image
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Mmm, and ideally we'd add selectors for the cube and sphere nodes, but since they don't have getMesh() methods, I think that's a little too bloaty to shoehorn it into the same example.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

The Sphere node has turned into a mesh scene node in the latest SVN :D So it can be added for 1.5, go ahead
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

So it has! Huzzah.

[UPDATE] Actually, I've just swiped some of Travis' code, plus I think it might be in the Irrlicht idiom to provide a simple way of retrieving every scene node with a single method call.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Post Reply