Gravity and Collision Detecting.
-
Eric the half a bee
Gravity and Collision Detecting.
Hello. I am trying to put together a short demo and it involves seeing a model run around a q2 level. Following the tutorial on collision detecting, I am able to set the camera to follow the normal rules of physics (ie the camera doesnt float and can't walk through walls. However, when I create a new SceneNodeAnimator, the model (node1) still floats. Anys suggestions?
Code below:
#include<irrlicht.h>
#include<wchar.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>(640, 480), 16, false, false, &receiver);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
device->getFileSystem()->addZipFileArchive("map-20kdm2.pk3");
scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
scene::ISceneNode* node = 0;
if (mesh)
node = smgr->addOctTreeSceneNode(mesh->getMesh(0));
if (node)
node->setPosition(core::vector3df(-1300,-70,-1249));
scene::ITriangleSelector* selector = 0;
if (node)
{
selector = smgr->createOctTreeTriangleSelector(
mesh->getMesh(0), node, 128);
node->setTriangleSelector(selector);
selector->drop();
}
scene::IAnimatedMesh* mesh1 = smgr->getMesh("sydney.md2");
scene::IAnimatedMeshSceneNode* node1 = smgr->addAnimatedMeshSceneNode( mesh1 );
node1->setScale(core::vector3df(2,2,2));
node1->setPosition(core::vector3df(0,100,0));
if (node1)
{
node1->setMaterialFlag(video::EMF_LIGHTING, false);
node1->setMaterialTexture( 0, driver->getTexture("sydney.bmp") );
node1->setMD2Animation(scene::EMAT_RUN);
}
scene::ISceneNodeAnimator* anim1 = 0;
anim1 = smgr->createCollisionResponseAnimator(selector, node1, core::vector3df(30,50,30),
core::vector3df(0,-100,0), 100.0f,
core::vector3df(0,50,0));
node1->addAnimator(anim1);
anim1->drop();
scene::ISceneNodeAnimator* anim = 0;
camera = smgr->addCameraSceneNodeFPS(0,100.0f,300.0f);
camera->setPosition(core::vector3df(0,100,0));
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();
device->getCursorControl()->setVisible(false);
int lastFPS = -1;
while(device->run())
{
driver->beginScene(true, true, video::SColor(0,100,100,100));
smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
wchar_t tmp[1024];
swprintf(tmp, 1024, L"Quake 3 Map Example - Irrlicht Engine (fps:%d) Triangles:%d",
fps, driver->getPrimitiveCountDrawn());
device->setWindowCaption(tmp);
lastFPS = fps;
}
}
device->drop();
return 0;
}
Code below:
#include<irrlicht.h>
#include<wchar.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>(640, 480), 16, false, false, &receiver);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
device->getFileSystem()->addZipFileArchive("map-20kdm2.pk3");
scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
scene::ISceneNode* node = 0;
if (mesh)
node = smgr->addOctTreeSceneNode(mesh->getMesh(0));
if (node)
node->setPosition(core::vector3df(-1300,-70,-1249));
scene::ITriangleSelector* selector = 0;
if (node)
{
selector = smgr->createOctTreeTriangleSelector(
mesh->getMesh(0), node, 128);
node->setTriangleSelector(selector);
selector->drop();
}
scene::IAnimatedMesh* mesh1 = smgr->getMesh("sydney.md2");
scene::IAnimatedMeshSceneNode* node1 = smgr->addAnimatedMeshSceneNode( mesh1 );
node1->setScale(core::vector3df(2,2,2));
node1->setPosition(core::vector3df(0,100,0));
if (node1)
{
node1->setMaterialFlag(video::EMF_LIGHTING, false);
node1->setMaterialTexture( 0, driver->getTexture("sydney.bmp") );
node1->setMD2Animation(scene::EMAT_RUN);
}
scene::ISceneNodeAnimator* anim1 = 0;
anim1 = smgr->createCollisionResponseAnimator(selector, node1, core::vector3df(30,50,30),
core::vector3df(0,-100,0), 100.0f,
core::vector3df(0,50,0));
node1->addAnimator(anim1);
anim1->drop();
scene::ISceneNodeAnimator* anim = 0;
camera = smgr->addCameraSceneNodeFPS(0,100.0f,300.0f);
camera->setPosition(core::vector3df(0,100,0));
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();
device->getCursorControl()->setVisible(false);
int lastFPS = -1;
while(device->run())
{
driver->beginScene(true, true, video::SColor(0,100,100,100));
smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
wchar_t tmp[1024];
swprintf(tmp, 1024, L"Quake 3 Map Example - Irrlicht Engine (fps:%d) Triangles:%d",
fps, driver->getPrimitiveCountDrawn());
device->setWindowCaption(tmp);
lastFPS = fps;
}
}
device->drop();
return 0;
}
The elipsoid you use for your sydney model is too big I suspect. In general, you should be able to use:
This gets the size of the node's bounding box and divides it by 2 so you have the bounding box's radius in all 3 dimensions. Then use this in your collision response animator constructor. ie:
Note that I also set the offset (the last paramter) to zero. You may need to adjust this somewhat to get the feet perfectly on the ground.
Code: Select all
irr::core::vector3df elipsoidSize = node->getBoundingBox()->MaxEdge - node->getBoundingBox()->MinEdge;
elipsoidSize = elipsoidSize/2.0f;Code: Select all
anim1 = smgr->createCollisionResponseAnimator(selector, node1, elipsoidSize,
core::vector3df(0,-100,0), 100.0f,
core::vector3df(0,0,0));-
Eric the half a bee
Gravity and Collision Detection
Thanks for the swift reply. I am now just trying to get my compiler to get over the following error:
error C2819: type 'irr::core::aabbox3d<float>' does not have an overloaded member 'operator ->'
error C2227: left of '->MaxEdge' must point to class/struct/union
error C2819: type 'irr::core::aabbox3d<float>' does not have an overloaded member 'operator ->'
error C2227: left of '->MinEdge' must point to class/struct/union
Error executing cl.exe.
map.obj - 4 error(s), 0 warning(s)
Any assistance greatly appreciated.
Ta.
error C2819: type 'irr::core::aabbox3d<float>' does not have an overloaded member 'operator ->'
error C2227: left of '->MaxEdge' must point to class/struct/union
error C2819: type 'irr::core::aabbox3d<float>' does not have an overloaded member 'operator ->'
error C2227: left of '->MinEdge' must point to class/struct/union
Error executing cl.exe.
map.obj - 4 error(s), 0 warning(s)
Any assistance greatly appreciated.
Ta.
hello.
Dont work for me !!!! help !!!
video::SMaterial material;
material.Texture1 = driver->getTexture("faerie2.bmp");
material.Lighting = true;
scene::IAnimatedMeshSceneNode* node = 0;
scene::IAnimatedMesh* faerie = smgr->getMesh("faerie.md2");
node = smgr->addAnimatedMeshSceneNode(faerie);
node->setPosition(core::vector3df(-70,0,-60));
node->setMD2Animation(scene::EMAT_JUMP);
node->getMaterial(0) = material;
node->setScale(core::vector3df(2.0f,2.0f,2.0f));
irr::core::vector3df elipsoidSize = node->getBoundingBox().MaxEdge - node->getBoundingBox().MinEdge;
elipsoidSize = elipsoidSize/2.0f;
scene::ISceneNodeAnimator* anim2 = smgr->createCollisionResponseAnimator(
selector, node, elipsoidSize,core::vector3df(0,-100,0), 10.0f, core::vector3df(0,0,0));
node->addAnimator(anim2);
anim2->drop();
help me please !!!
Dont work for me !!!! help !!!
video::SMaterial material;
material.Texture1 = driver->getTexture("faerie2.bmp");
material.Lighting = true;
scene::IAnimatedMeshSceneNode* node = 0;
scene::IAnimatedMesh* faerie = smgr->getMesh("faerie.md2");
node = smgr->addAnimatedMeshSceneNode(faerie);
node->setPosition(core::vector3df(-70,0,-60));
node->setMD2Animation(scene::EMAT_JUMP);
node->getMaterial(0) = material;
node->setScale(core::vector3df(2.0f,2.0f,2.0f));
irr::core::vector3df elipsoidSize = node->getBoundingBox().MaxEdge - node->getBoundingBox().MinEdge;
elipsoidSize = elipsoidSize/2.0f;
scene::ISceneNodeAnimator* anim2 = smgr->createCollisionResponseAnimator(
selector, node, elipsoidSize,core::vector3df(0,-100,0), 10.0f, core::vector3df(0,0,0));
node->addAnimator(anim2);
anim2->drop();
help me please !!!
Ah yes. For that you will need to create a MetaTriangleSelector. Then add the level's OctTreeTriangleSelector to it, as well as a triangleSelector for each faerie. eg:
That's the basic idea. The code will likely have to be debugged. This is kind of inefficient though, especially if you start getting lots of faeries (or other nodes). Irrlicht doesn't really have a good way of doing collision detection on things other than the level. If you find this method takes too much time, you'll have to write your own method which will first do collision detection on bounding boxes only, then if they are close enough, do use a triangle selector.
Unless there is some other more efficient method, but I've never heard anyone talk about one on the forums.
Code: Select all
irr::scene::IMetaTriangleSelector bob = smgr->createMetaTriangleSelector();
bob->addTriangleSelector(selector);
irr::scene::ITriangleSelector *faerie = smgr->createTriangleSelector(fmesh1,fnode1);
bob->addTriangleSelector(faerie);
faerie->drop();
irr::scene::ITriangleSelector *faerie = smgr->createTriangleSelector(fmesh2,fnode2);
bob->addTriangleSelector(faerie);
faerie->drop();
scene::ISceneNodeAnimator* anim2 = smgr->createCollisionResponseAnimator(
bob, node, elipsoidSize,core::vector3df(0,-100,0), 10.0f, core::vector3df(0,0,0));
node->addAnimator(anim2);
anim2->drop(); Unless there is some other more efficient method, but I've never heard anyone talk about one on the forums.
Ok, thank you very much.
I will try to make my own Collide method but i have a lot of question.
In my case the game is looked in 3d but the collision should be in 2d (a platform game).
What is the essence of the collision methods ??
Only store the collision box dates or cylinder and position of every ObjectCollider and check for every one if it is colliding with every ObjectCollider in the world ??? with a "while" or "for" moving along of an list of ObjectCollider ????
I think it is too slow.
Again, thank you.
I will try to make my own Collide method but i have a lot of question.
In my case the game is looked in 3d but the collision should be in 2d (a platform game).
What is the essence of the collision methods ??
Only store the collision box dates or cylinder and position of every ObjectCollider and check for every one if it is colliding with every ObjectCollider in the world ??? with a "while" or "for" moving along of an list of ObjectCollider ????
I think it is too slow.
Again, thank you.
epsilon, that is the very first and most basic way of doing collision detection-- brute force.
from there, you add code to speed it up:
1) use culling methods (similar to frustrum culling, but dealing with whole objects instead of individual triangles). For instance, if you're using a portal renderer, and one of the monsters is in a portal you're not currently able to view-- you dont have to check collision with it.
2) get the distance between the current object and the object you're testing against-- if the distance is greater than your radius plus their radius, you cant possibly be colliding
3) get your movement direction and their movement direction, if neither of the objects are moving towards the other, you cant possibly colliding
it may seem like putting all these checks before your actual collision detection code means you'll be doing a lot more work right? wrong: most objects will not even pass the first test, which means you're only doing a few small checks instead of a full collision check on most objects. It will make the full collision check a little longer, but statistics shows that overall this is much faster.
from there, you add code to speed it up:
1) use culling methods (similar to frustrum culling, but dealing with whole objects instead of individual triangles). For instance, if you're using a portal renderer, and one of the monsters is in a portal you're not currently able to view-- you dont have to check collision with it.
2) get the distance between the current object and the object you're testing against-- if the distance is greater than your radius plus their radius, you cant possibly be colliding
3) get your movement direction and their movement direction, if neither of the objects are moving towards the other, you cant possibly colliding
it may seem like putting all these checks before your actual collision detection code means you'll be doing a lot more work right? wrong: most objects will not even pass the first test, which means you're only doing a few small checks instead of a full collision check on most objects. It will make the full collision check a little longer, but statistics shows that overall this is much faster.
a screen cap is worth 0x100000 DWORDS
hi again !.
I think is not so dificult make a simplest collision detection for simplest objects, like the body od the player or something, but how can i make the gravity for collide with the terrain like in tutorial 8 the terrain is room.3ds, i already tryed using the irrlicht function
scene::IAnimatedMesh* mesh = smgr->getMesh("../irrlicht/media/room.3ds");
smgr->getMeshManipulator()->makePlanarTextureMapping(mesh->getMesh(0), 0.008f);
scene::ISceneNode* node = 0;
node = smgr->addAnimatedMeshSceneNode(mesh);
node->setMaterialTexture(0, driver->getTexture("../irrlicht/media/wall.jpg"));
scene::ITriangleSelector* selector = 0;
if (node)
{
selector = smgr->createOctTreeTriangleSelector(mesh->getMesh(0), node, 128);
node->setTriangleSelector(selector);
selector->drop();
}
and making some other objectcollider
mesh = smgr->getMesh("cuchillo.3ds");
anode = smgr->addAnimatedMeshSceneNode(mesh);
anode->setPosition(core::vector3df(-50,80,-60));
camera = smgr->addCameraSceneNodeFPS();
camera->setPosition(core::vector3df(-50,50,-150));
scene::IMetaTriangleSelector *bob = smgr->createMetaTriangleSelector();
bob->addTriangleSelector(selector);
scene::ITriangleSelector *cuchillo = smgr->createOctTreeTriangleSelector(mesh->getMesh(0), anode, 128);
//scene::ITriangleSelector *cuchillo = smgr->createTriangleSelector(mesh,anode);
bob->addTriangleSelector(cuchillo);
cuchillo->drop();
anim = smgr->createCollisionResponseAnimator(
bob, camera, core::vector3df(30,50,30),
core::vector3df(0,-100,0), 100.0f,
core::vector3df(0,35,0));
camera->addAnimator(anim);
anim->drop();
thanks.
I think is not so dificult make a simplest collision detection for simplest objects, like the body od the player or something, but how can i make the gravity for collide with the terrain like in tutorial 8 the terrain is room.3ds, i already tryed using the irrlicht function
scene::IAnimatedMesh* mesh = smgr->getMesh("../irrlicht/media/room.3ds");
smgr->getMeshManipulator()->makePlanarTextureMapping(mesh->getMesh(0), 0.008f);
scene::ISceneNode* node = 0;
node = smgr->addAnimatedMeshSceneNode(mesh);
node->setMaterialTexture(0, driver->getTexture("../irrlicht/media/wall.jpg"));
scene::ITriangleSelector* selector = 0;
if (node)
{
selector = smgr->createOctTreeTriangleSelector(mesh->getMesh(0), node, 128);
node->setTriangleSelector(selector);
selector->drop();
}
and making some other objectcollider
mesh = smgr->getMesh("cuchillo.3ds");
anode = smgr->addAnimatedMeshSceneNode(mesh);
anode->setPosition(core::vector3df(-50,80,-60));
camera = smgr->addCameraSceneNodeFPS();
camera->setPosition(core::vector3df(-50,50,-150));
scene::IMetaTriangleSelector *bob = smgr->createMetaTriangleSelector();
bob->addTriangleSelector(selector);
scene::ITriangleSelector *cuchillo = smgr->createOctTreeTriangleSelector(mesh->getMesh(0), anode, 128);
//scene::ITriangleSelector *cuchillo = smgr->createTriangleSelector(mesh,anode);
bob->addTriangleSelector(cuchillo);
cuchillo->drop();
anim = smgr->createCollisionResponseAnimator(
bob, camera, core::vector3df(30,50,30),
core::vector3df(0,-100,0), 100.0f,
core::vector3df(0,35,0));
camera->addAnimator(anim);
anim->drop();
thanks.