Two meshes, one collision.

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
Azert
Posts: 18
Joined: Sun Feb 18, 2007 11:34 am
Location: Belgium

Two meshes, one collision.

Post by Azert »

I've heard that there's only a limited polygon maximum on each mesh so I tried a code (actually the collision tutorial) that loads two meshes. The meshes are no problem and they load, but one of them has no collision, I just fall through.

I've entered the code, the land2.obj file is the one who has no collision, the other: land1.obj works perfect. Anyone who knows how to put collision on the second mesh? (Whitout losing the collision of the first mesh)

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;

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


int main()
{
	// let user select driver type

	video::E_DRIVER_TYPE driverType;

	printf("Please select the driver you want for this example:\n"\
		" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 

1.5\n"\
		" (d) Software Renderer\n (e) Burning's Software 

Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_DIRECT3D8;break;
		case 'c': driverType = video::EDT_OPENGL;   break;
		case 'd': driverType = video::EDT_SOFTWARE; break;
		case 'e': driverType = video::EDT_SOFTWARE2;break;
		case 'f': driverType = video::EDT_NULL;     break;
		default: return 0;
	}

	// create device

	IrrlichtDevice *device =
		createDevice(driverType, core::dimension2d<s32>(640, 

480), 16, false);
		
	if (device == 0)
		return 1; // could not create selected driver.

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

smgr->getMesh("../../media/land2.obj");
	scene::ISceneNode* q3node = 0;

	if (q3levelmesh)
		q3node = 

smgr->addOctTreeSceneNode(q3levelmesh->getMesh(0));

	scene::ITriangleSelector* selector = 0;
	
	if (q3node)
	{		
		q3node->setPosition(core::vector3df(-10,-10,-10));
        q3node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
		selector = 

smgr->createOctTreeTriangleSelector(q3levelmesh->getMesh(0), q3node, 

128);
		q3node->setTriangleSelector(selector);
		selector->drop();
	}

scene::IAnimatedMesh* q4levelmesh = 

smgr->getMesh("../../media/land1.obj");
	scene::ISceneNode* q4node = 0;

	if (q4levelmesh)
		q4node = 

smgr->addOctTreeSceneNode(q4levelmesh->getMesh(0));
	
	if (q4node)
	{		
		q4node->setPosition(core::vector3df(0,0,0));
        q4node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
		selector = 

smgr->createOctTreeTriangleSelector(q4levelmesh->getMesh(0), q4node, 

128);
		q4node->setTriangleSelector(selector);
		selector->drop();
	}

	scene::ICameraSceneNode* camera = 
		smgr->addCameraSceneNodeFPS(0, 100.0f, 300.0f, -1, 0, 

0, true);
    camera->setPosition(core::vector3df(-100,50,-150));

	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);
	anim->drop();

	// disable mouse cursor

	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->setMaterialFlag(video::EMF_ZBUFFER, false);
	bill->setSize(core::dimension2d<f32>(20.0f, 20.0f));

	// 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())
	if (device->isWindowActive())
	{
		driver->beginScene(true, true, 0);

		smgr->drawAll();	

		core::line3d<f32> line;
		line.start = camera->getPosition();
		line.end = line.start + (camera->getTarget() - 

line.start).normalize() * 1000.0f;

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

		if 

(smgr->getSceneCollisionManager()->getCollisionPoint(
			line, selector, intersection, tri))
		{
			bill->setPosition(intersection);
				
			driver->setTransform(video::ETS_WORLD, 

core::matrix4());
			driver->draw3DTriangle(tri, 

video::SColor(0,255,0,0));
		}

		selectedSceneNode = 

smgr->getSceneCollisionManager()->getSceneNodeFromCameraBB(camera);

		if (selectedSceneNode == q3node || selectedSceneNode == 

bill)
			selectedSceneNode = 0;

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

		if (selectedSceneNode)
			

selectedSceneNode->setMaterialFlag(video::EMF_LIGHTING, false);

		lastSelectedSceneNode = selectedSceneNode;


		driver->endScene();

		int fps = driver->getFPS();

		if (lastFPS != fps)
		{
		  core::stringw str = L"Collision detection example - 

Irrlicht Engine [";
		  str += driver->getName();
		  str += "] FPS:";
		  str += fps;

		  device->setWindowCaption(str.c_str());
		  lastFPS = fps;
		}
	}

	device->drop();
	
	return 0;
}

fakin
Posts: 14
Joined: Wed Jan 24, 2007 9:02 pm
Location: zagreb, croatia

Post by fakin »

I'm not sure but i think you need to add collisionResponseAnimator to the camera twice. once for obj1 and once for obj2.


so... add this ...

Code: Select all

scene::ICameraSceneNode* camera =
      smgr->addCameraSceneNodeFPS(0, 100.0f, 300.0f, -1, 0,

0, true);
    camera->setPosition(core::vector3df(-100,50,-150));
... before this...

Code: Select all

smgr->getMesh("../../media/land2.obj");
   scene::ISceneNode* q3node = 0;

   if (q3levelmesh)
      q3node =

smgr->addOctTreeSceneNode(q3levelmesh->getMesh(0));

   scene::ITriangleSelector* selector = 0;
   
   if (q3node)
   {      
      q3node->setPosition(core::vector3df(-10,-10,-10));
        q3node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
      selector =

smgr->createOctTreeTriangleSelector(q3levelmesh->getMesh(0), q3node,

128);
      q3node->setTriangleSelector(selector);
      selector->drop();
   }
... and now you add this ...

Code: Select all

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);
   anim->drop();
... and just leave the rest as is, just remember to delete the second camera :)
i think now it should work
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

You should be using a meta triangle selector. You create each of the selectors just like you are currently doing, and you add each of those selectors to the meta selector. Then you pass the meta selector to createCollisionResponseAnimator().

Travis
Azert
Posts: 18
Joined: Sun Feb 18, 2007 11:34 am
Location: Belgium

Post by Azert »

I've tried the metaTriangleSelector the best I could (I'm a dissaster when it comes to programming) but he gives two errors: on line 60 and 75: "invalid conversion from 'irr::scene::ITriangleSelector*' to 'irr::scene::IMetaTriangleSelector*'...
So I have somehow te replace metaTriangleSelector? I have no clue... :(

Code: Select all

#include <irrlicht.h>
#include <iostream>
#include <IMetaTriangleSelector.h> 

using namespace irr;

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


int main()
{
	// let user select driver type

	video::E_DRIVER_TYPE driverType;

	printf("Please select the driver you want for this example:\n"\
		" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
		" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_DIRECT3D8;break;
		case 'c': driverType = video::EDT_OPENGL;   break;
		case 'd': driverType = video::EDT_SOFTWARE; break;
		case 'e': driverType = video::EDT_SOFTWARE2;break;
		case 'f': driverType = video::EDT_NULL;     break;
		default: return 0;
	}

	// create device

	IrrlichtDevice *device =
		createDevice(driverType, core::dimension2d<s32>(640, 480), 16, false);
		
	if (device == 0)
		return 1; // could not create selected driver.

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();
    scene::ICameraSceneNode* q4camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 300.0f, -1, 0, 0, true); 
    q4camera->setPosition(core::vector3df(-100,50,-150));
    scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("../../media/dat/Artisan_1.obj");
	scene::ISceneNode* q3node = 0;

	if (q3levelmesh)
		q3node = smgr->addOctTreeSceneNode(q3levelmesh->getMesh(0));

	irr::scene::IMetaTriangleSelector* mainTriangleSelector = 0; 
	
	if (q3node)
	{		
		q3node->setPosition(core::vector3df(0,1000,0));
        q3node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
        mainTriangleSelector = smgr->createOctTreeTriangleSelector(q3levelmesh->getMesh(0), q3node, 128);
		q3node->setTriangleSelector(mainTriangleSelector);
		mainTriangleSelector->drop();
	}

    scene::IAnimatedMesh* q4levelmesh = smgr->getMesh("../../media/dat/Artisan_1.obj");
	scene::ISceneNode* q4node = 0;

	if (q4levelmesh)
		q4node = smgr->addOctTreeSceneNode(q4levelmesh->getMesh(0));
	
	if (q4node)
	{		
        q4node->setPosition(core::vector3df(0,0,0));
        q4node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
        mainTriangleSelector = smgr->createOctTreeTriangleSelector(q4levelmesh->getMesh(0), q4node, 128);
		q4node->setTriangleSelector(mainTriangleSelector);
        q4node->setMaterialType(irr::video::EMT_SOLID);
        mainTriangleSelector->drop();
	}


    q4camera->setPosition(core::vector3df(-100,50,-150)); 
    scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator( 
      mainTriangleSelector, q4camera, core::vector3df(30,50,30), 
      core::vector3df(0,-3,0), 
      core::vector3df(0,50,0)); 
   q4camera->addAnimator(anim); 
   anim->drop(); 

	// disable mouse cursor

	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->setMaterialFlag(video::EMF_ZBUFFER, false);
	bill->setSize(core::dimension2d<f32>(20.0f, 20.0f));

	// 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())
	if (device->isWindowActive())
	{
		driver->beginScene(true, true, 0);

		smgr->drawAll();	

		core::line3d<f32> line;
		line.start = q4camera->getPosition();
		line.end = line.start + (q4camera->getTarget() - line.start).normalize() * 1000.0f;

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

		if (smgr->getSceneCollisionManager()->getCollisionPoint(
			line, mainTriangleSelector, intersection, tri))
		{
			bill->setPosition(intersection);
				
			driver->setTransform(video::ETS_WORLD, core::matrix4());
			driver->draw3DTriangle(tri, video::SColor(0,255,0,0));
		}

		selectedSceneNode = smgr->getSceneCollisionManager()->getSceneNodeFromCameraBB(q4camera);

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

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

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

		lastSelectedSceneNode = selectedSceneNode;


		driver->endScene();

		int fps = driver->getFPS();

		if (lastFPS != fps)
		{
		  core::stringw str = L"Collision detection example - Irrlicht Engine [";
		  str += driver->getName();
		  str += "] FPS:";
		  str += fps;

		  device->setWindowCaption(str.c_str());
		  lastFPS = fps;
		}
	}

	device->drop();
	
	return 0;
}


Post Reply