Collision detection

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
VeneX
Posts: 228
Joined: Sun Nov 30, 2003 3:32 pm
Location: The Netherlands
Contact:

Collision detection

Post by VeneX »

I have a problem with collision detection. In the techdemo you can walk through the fairy models. How can you set collision detection on models?

When you use physics for al falling box, is it necessarily to use collision detection. I heared collision detection is heavy for your computer but, how heavy. Can anybody add an tutorial of using camera attached to the floor positions (if it is possible to use the usability of a wall (not walk through it)).
Visit my website @ www.venex.be
Plethora project will be added to the site
AMD AthlonXP 2600+, 512MB DDR, Radeon M10 (mobile 9600) PRO 64MB, WinXP
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

First of all, the techdemo is an example of a camera which (with gravity enabled) is limited to the floor, and which cannot walk thru walls.

Secondly, you definately have to use collision detection for any object which you want to rect to another object's surface. This includes a 'falling box'. And depending on how many boxes, and how fast they are moving, the collision detection/resolution shouldnt be too horrible.

Finally, I cant answer your question about detecting collisions against the fairys. However, I would wager that if you look at how they told the camera to check against the BSP level in the TechDemo, that you would follow a similar proceedure in adding any Mesh to your list of things to do CD against.

I expect someone more knowledgable in IrrLicht to follow me up on that last bit.
a screen cap is worth 0x100000 DWORDS
[dx/x]=HUNT3R
Posts: 271
Joined: Sat Aug 23, 2003 5:52 pm
Location: Hurricane Central, Florida

Post by [dx/x]=HUNT3R »

you need to create a triangle selector for every object you want to have collision detection with and in turn add all of the triangle selectors to one main triangle selector, the metaTriangleSelector (look it up in the API). And then the metaTriangleSelector is the one that is added to the camera.
VeneX
Posts: 228
Joined: Sun Nov 30, 2003 3:32 pm
Location: The Netherlands
Contact:

Post by VeneX »

ok, is it easy to change the techdemo, so you can't walk through the fairy's anymore with a few lines of code. I don't get that totally.
Visit my website @ www.venex.be
Plethora project will be added to the site
AMD AthlonXP 2600+, 512MB DDR, Radeon M10 (mobile 9600) PRO 64MB, WinXP
VeneX
Posts: 228
Joined: Sun Nov 30, 2003 3:32 pm
Location: The Netherlands
Contact:

Post by VeneX »

I have added

Code: Select all

scene::IAnimatedMesh* gun = smgr->getMesh("./data/gloc.3ds");
	scene::IAnimatedMeshSceneNode* gunnode = smgr->addAnimatedMeshSceneNode( gun );

	if (gunnode)
	{	
		gunnode->setFrameLoop(0, 310);
		gunnode->setPosition(core::vector3df(0,0,-90));
		gunnode->setMaterialTexture( 0,       
		driver->getTexture("./data/glocmap.jpg") );
	}

scene::ITriangleSelector* gunselector = 0;

		if (gunnode)
	{
		gunselector = smgr->createOctTreeTriangleSelector(gun->getMesh(0), gunnode, 128);
		gunnode->setTriangleSelector(gunselector);
		gunselector->drop();
	}
to the collision tutorial. But it doesn't work
Can someone help me please?[/code]
Visit my website @ www.venex.be
Plethora project will be added to the site
AMD AthlonXP 2600+, 512MB DDR, Radeon M10 (mobile 9600) PRO 64MB, WinXP
VeneX
Posts: 228
Joined: Sun Nov 30, 2003 3:32 pm
Location: The Netherlands
Contact:

Post by VeneX »

Can someone please find the bug, I am just a n00b. It is an edited code of the collision detection example. Notice I am still using Irrlicht 0.4! The place where the bug is is fat marked.

Code: Select all

#include <irrlicht.h>

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

scene::ICameraSceneNode* camera = 0;

class MyEventReceiver : public IEventReceiver
{
public:
	virtual bool OnEvent(SEvent event)
	{
		if (camera)
			return camera->OnEvent(event);

		return false;
	}
};

	// main

int main()
{
	MyEventReceiver receiver;

	IrrlichtDevice *device =
		createDevice(video::DT_DIRECTX8, core::dimension2d<s32>(640, 480), 16, false, false, &receiver);

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();

	
	device->getFileSystem()->addZipFileArchive("./data/map-20kdm2.pk3");

	
	scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp");
	scene::ISceneNode* q3node = 0;
	
	if (q3levelmesh)
		q3node = smgr->addOctTreeSceneNode(q3levelmesh->getMesh(0));

	/*
	So far so good, we've loaded the quake 3 level like in tutorial 2. Now, here
	comes something different: We create a triangle selector. A triangle selector
	is a class which can fetch the triangles from scene nodes for doing different
	things with them, for example collision detection. There are different triangle
	selectors, and all can be created with the ISceneManager. In this example,
	we create an OctTreeTriangleSelector, which optimizes the triangle output a l
	little bit by reducing it like an octree. This is very useful for huge meshes
	like quake 3 levels.
	Afte we created the triangle selector, we attach it to the q3node. This is not
	necessary, but in this way, we do not need to care for the selector, for example
	dropping it after we do not need it anymore.
	*/

	scene::ITriangleSelector* selector = 0;
	
	if (q3node)
	{		
		q3node->setPosition(core::vector3df(-1370,-130,-1400));

		selector = smgr->createOctTreeTriangleSelector(q3levelmesh->getMesh(0), q3node, 128);
		q3node->setTriangleSelector(selector);
		selector->drop();
	}
	
	/*
	We add a first person shooter camera to the scene for being able to move in the quake 3
	level like in tutorial 2. But this, time, we add a special animator to the 
	camera: A Collision Response animator. This thing modifies the scene node to which
	it is attached to in that way, that it may no more move through walls and is affected
	by gravity. 
	*/

	camera = smgr->addCameraSceneNodeFPS(0,100.0f,300.0f);
	camera->setPosition(core::vector3df(0,100,0));

	scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
		selector, camera, core::vector3df(30,50,30),
		core::vector3df(0,-100,0), 100.0f, 
		core::vector3df(0,50,0));
	camera->addAnimator(anim);
	anim->drop();

	// disable mouse cursor

	device->getCursorControl()->setVisible(false);

	// add 3 animated faeries.

	video::SMaterial material;
	material.Texture1 = driver->getTexture("./data/faerie2.bmp");
	material.Lighting = true;

	scene::IAnimatedMeshSceneNode* node = 0;
	scene::IAnimatedMesh* faerie = smgr->getMesh("./data/faerie.md2");

	if (faerie)
	{
		node = smgr->addAnimatedMeshSceneNode(faerie);
		node->setPosition(core::vector3df(-70,0,-90));
		node->setMD2Animation(scene::EMAT_RUN);
		node->getMaterial(0) = material;

		node = smgr->addAnimatedMeshSceneNode(faerie);
		node->setPosition(core::vector3df(-70,0,-30));
		node->setMD2Animation(scene::EMAT_SALUTE);
		node->getMaterial(0) = material;

		node = smgr->addAnimatedMeshSceneNode(faerie);
		node->setPosition(core::vector3df(-70,0,-60));
		node->setMD2Animation(scene::EMAT_JUMP);
		node->getMaterial(0) = material;
	}

	material.Texture1 = 0;
	material.Lighting = false;

	// add a gun

	scene::IAnimatedMesh* gun = smgr->getMesh("./data/gloc.3ds");
	scene::IAnimatedMeshSceneNode* gunnode = smgr->addAnimatedMeshSceneNode( gun );
	scene::ITriangleSelector* gunselector = 0;

	if (gunnode)
	{	
		gunnode->setFrameLoop(0, 310);
		gunnode->setPosition(core::vector3df(0,0,-90));
		gunnode->setMaterialTexture( 0,       
		driver->getTexture("./data/glocmap.jpg") );
	// collision detection
		gunselector = smgr->createOctTreeTriangleSelector(gun->getMesh(0), gunnode, 128);
		gunnode->setTriangleSelector(gunselector);
		gunselector->drop();
	}

/*
code for collision <- I think here is the bug, but how should it be?
Collision.exe - 1 error(s), 0 warning(s)
error C2065: 'vector3df' : undeclared identifier
*/

Code: Select all

	anim = smgr->createCollisionResponseAnimator(
		gunselector, gunnode, vector3df(30,13,10),
		core::vector3df(0,-1,0), 100.0f, 
		core::vector3df(0,0,0));
	gunnode->addAnimator(anim);
	anim->drop();

	// add a light

	smgr->addLightSceneNode(0, core::vector3df(-60,100,400),
		video::SColorf(1.0f,1.0f,1.0f,1.0f),
		600.0f);

	/*
	For not making it to complicated, I'm doing picking inside the drawing loop.
	We take two pointers for storing the current and the last selected scene node and 
	start the loop.
	*/

	scene::ISceneNode* selectedSceneNode = 0;
	scene::ISceneNode* lastSelectedSceneNode = 0;

	
	int lastFPS = -1;

	while(device->run())
	{
		driver->beginScene(true, true, 0);

		smgr->drawAll();

		/*
		That's it, we just have to finish drawing.
		*/

		driver->endScene();

		int fps = driver->getFPS();

		if (lastFPS != fps)
		{
			wchar_t tmp[1024];
			swprintf(tmp, 1024, L"Collision detection example - Irrlicht Engine (fps:%d) Triangles:%d", 
				fps, driver->getPrimitiveCountDrawn());

			device->setWindowCaption(tmp);
			lastFPS = fps;
		}
	}

	device->drop();
	
	return 0;
}
Visit my website @ www.venex.be
Plethora project will be added to the site
AMD AthlonXP 2600+, 512MB DDR, Radeon M10 (mobile 9600) PRO 64MB, WinXP
SuryIIID
Posts: 14
Joined: Mon Dec 29, 2003 8:54 pm
Location: Bulgaria..?

Post by SuryIIID »

Can someone please find the bug, I am just a n00b. It is an edited code of the collision detection example. Notice I am still using Irrlicht 0.4! The place where the bug is is fat marked.
Ok i slightly modified the Collision detection example to make it work with fairies..now you cannot go through them and now it's much like a skeleton for a FPS or adventure game.
This is the part of the code wich handles collisions :Note that it checks the fairies bounding boxes only but that's more than enough for a simple FPS i think

Code: Select all

scene::ITriangleSelector* selector = 0;
        selector = smgr->createOctTreeTriangleSelector(q3levelmesh->getMesh(0), q3node, 128);
		q3node->setTriangleSelector(selector);
		
		scene::ITriangleSelector* fairselector = 0;
        fairselector = smgr->createTriangleSelectorFromBoundingBox(node);
        
		scene::IMetaTriangleSelector* selector1;
	  	selector1 = smgr->createMetaTriangleSelector();
		selector1->addTriangleSelector(selector);
        selector1->addTriangleSelector(fairselector);
			 
        selector->drop();
		
		scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
		selector1, camera, core::vector3df(30,50,30),
		core::vector3df(0,-100,0), 100.0f, 
		core::vector3df(0,50,0));
	    camera->addAnimator(anim);
	    anim->drop();
        selector1->drop(); 
but i guess you will feel much more confortable if i post the whole code so you can just copy and paste it in your project but fully understandinging the Irrlicht logic is always recommended :)

Code: Select all

#include <irrlicht.h>

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

scene::ICameraSceneNode* camera = 0;

class MyEventReceiver : public IEventReceiver
{
public:
	virtual bool OnEvent(SEvent event)
	{
		if (camera)
			return camera->OnEvent(event);

		return false;
	}
};


int main()
{
	MyEventReceiver receiver;

	IrrlichtDevice *device =
		createDevice(video::DT_DIRECTX8, core::dimension2d<s32>(800, 600), 32, false, false, &receiver);

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();

	
	device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3");

	
	scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp");
	scene::ISceneNode* q3node = 0;
	
	if (q3levelmesh)
		q3node = smgr->addOctTreeSceneNode(q3levelmesh->getMesh(0));
	
	if (q3node)
	{		
		q3node->setPosition(core::vector3df(-1370,-130,-1400));

		
	}
camera = smgr->addCameraSceneNodeFPS(0,100.0f,300.0f);
camera->setPosition(core::vector3df(0,100,0));
	device->getCursorControl()->setVisible(false);

	// add billboard

	scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode();
	bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
	bill->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp"));
	bill->setMaterialFlag(video::EMF_LIGHTING, false);
	bill->setSize(core::dimension2d<f32>(20.0f, 20.0f));
// add 3 animated faeries.

	video::SMaterial material;
	material.Texture1 = driver->getTexture("../../media/faerie2.bmp");
	material.Lighting = true;

	scene::IAnimatedMeshSceneNode* node = 0;
	scene::IAnimatedMesh* faerie = smgr->getMesh("../../media/faerie.md2");
if (faerie)
	{
		node = smgr->addAnimatedMeshSceneNode(faerie);
		node->setPosition(core::vector3df(-70,0,-90));
		node->setMD2Animation(scene::EMAT_RUN);
		node->getMaterial(0) = material;

		node = smgr->addAnimatedMeshSceneNode(faerie);
		node->setPosition(core::vector3df(-70,0,-30));
		node->setMD2Animation(scene::EMAT_SALUTE);
		node->getMaterial(0) = material;

		node = smgr->addAnimatedMeshSceneNode(faerie);
		node->setPosition(core::vector3df(-70,0,-60));
		node->setMD2Animation(scene::EMAT_JUMP);
		node->getMaterial(0) = material;

	 	}  
		
	    scene::ITriangleSelector* selector = 0;
        selector = smgr->createOctTreeTriangleSelector(q3levelmesh->getMesh(0), q3node, 128);
		q3node->setTriangleSelector(selector);
		
		scene::ITriangleSelector* fairselector = 0;
        fairselector = smgr->createTriangleSelectorFromBoundingBox(node);
        
		scene::IMetaTriangleSelector* selector1;
	  	selector1 = smgr->createMetaTriangleSelector();
		selector1->addTriangleSelector(selector);
        selector1->addTriangleSelector(fairselector);
			 
        selector->drop();
		
		scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
		selector1, camera, core::vector3df(30,50,30),
		core::vector3df(0,-100,0), 100.0f, 
		core::vector3df(0,50,0));
	    camera->addAnimator(anim);
	    anim->drop();
        selector1->drop();


	material.Texture1 = 0;
	material.Lighting = false;

	// Add a light

	smgr->addLightSceneNode(0, core::vector3df(-60,100,400),
		video::SColorf(1.0f,1.0f,1.0f,1.0f),
		600.0f);
	scene::ISceneNode* selectedSceneNode = 0;
	scene::ISceneNode* lastSelectedSceneNode = 0;

	
	int lastFPS = -1;

	while(device->run())
	{
		driver->beginScene(true, true, 0);

		smgr->drawAll();
	core::line3d<f32> line;
		line.start = camera->getPosition();
		line.end = line.start + (camera->getTarget() - line.start).normalize() * 3000.0f;

		core::vector3df intersection;
		core::triangle3df tri;

		if (smgr->getSceneCollisionManager()->getCollisionPoint(
			line, selector, intersection, tri))
		{
			bill->setPosition(intersection);
				
			driver->setTransform(video::TS_WORLD, core::matrix4());
			driver->setMaterial(material);
			driver->draw3DTriangle(tri, video::SColor(0,255,0,255));
		}
	selectedSceneNode = smgr->getSceneCollisionManager()->getSceneNodeFromCameraBB(camera);

		if (lastSelectedSceneNode)
			lastSelectedSceneNode->setMaterialFlag(video::EMF_LIGHTING, true);

		if (selectedSceneNode == q3node || selectedSceneNode == bill)
			selectedSceneNode = 0;

		if (selectedSceneNode)
			selectedSceneNode->setMaterialFlag(video::EMF_WIREFRAME, false);

		lastSelectedSceneNode = selectedSceneNode;
	driver->endScene();

		int fps = driver->getFPS();

		if (lastFPS != fps)
		{
			wchar_t tmp[1024];
			swprintf(tmp, 1024, L"Collision detection example - Irrlicht Engine (fps:%d) Triangles:%d", 
				fps, driver->getPrimitiveCountDrawn());

			device->setWindowCaption(tmp);
			lastFPS = fps;
		}
	}

	device->drop();
	
	return 0;
}
Hope this will help...
VeneX
Posts: 228
Joined: Sun Nov 30, 2003 3:32 pm
Location: The Netherlands
Contact:

Post by VeneX »

Thank you very much, I fully understand the code but am not such for I know where to place several pieces of code :oops: . I will have to learn, I am 16 years old, an leaped in the "dark" world of programming without experiences :lol: .
Visit my website @ www.venex.be
Plethora project will be added to the site
AMD AthlonXP 2600+, 512MB DDR, Radeon M10 (mobile 9600) PRO 64MB, WinXP
Post Reply