http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=26191
However, i have made a few modifications, mostly just creatieing the collision cam function. Here is the complete code. I would like to load stuff that is not an octree and still have collision with out the bounding box. I know it could eat up processer, but it is neccesary and what i am looking at is a small levle.
Please help!
Code: Select all
/*
Since version 1.1, Irrlicht is able to save and load
the full scene graph into an .irr file, an xml based
format. There is an editor available to edit
those files, named irrEdit on http://www.ambiera.com/irredit,
which can also be used as world and particle editor.
This tutorial shows how to use .irr files.
Lets start: Create an Irrlicht device and setup the window.
*/
#include <irrlicht.h>
#include <iostream>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
class CollisionMaker : public irr::scene::ISceneUserDataSerializer
{
irr::IrrlichtDevice* mDevice;
irr::scene::IMetaTriangleSelector* mSelector;
public:
CollisionMaker(irr::IrrlichtDevice* pDev);
irr::scene::IMetaTriangleSelector* getSelector();
irr::io::IAttributes* createUserData (irr::scene::ISceneNode *forSceneNode); //override from
void OnReadUserData (irr::scene::ISceneNode *forSceneNode, irr::io::IAttributes *userData);
void LoadScene(const c8 *filename);
void AddCollisionCam ();
};
CollisionMaker::CollisionMaker(irr::IrrlichtDevice* pDev)
{
mDevice = pDev;
mSelector = mDevice->getSceneManager()->createMetaTriangleSelector();
}
irr::scene::IMetaTriangleSelector* CollisionMaker::getSelector()
{
return mSelector;
}
irr::io::IAttributes* CollisionMaker::createUserData (irr::scene::ISceneNode *forSceneNode)
{
//Sending 0 caus' we don't care
return (irr::io::IAttributes*)0;
}
void CollisionMaker::OnReadUserData (irr::scene::ISceneNode *forSceneNode, irr::io::IAttributes *userData)
{
//if the attribute is not set, it's considered false. If it's false, we don't do anything.
if(userData->getAttributeAsBool("Collidee"))
{
//Detecting node type
if(forSceneNode->getType()==irr::scene::ESNT_OCT_TREE)
{
//Node is an octree, let's get mesh info
irr::io::IAttributes *attributes = mDevice->getFileSystem()->createEmptyAttributes();
forSceneNode->serializeAttributes(attributes);
irr::scene::IAnimatedMesh* mesh = mDevice->getSceneManager()->getMesh(attributes->getAttributeAsString("Mesh").c_str());
attributes->drop();
//Creating selector based on mesh
irr::scene::ITriangleSelector* thisSelector = mDevice->getSceneManager()->createOctTreeTriangleSelector(mesh->getMesh(0), forSceneNode, 128);
//Adding the selector to the meta selector
mSelector->addTriangleSelector(thisSelector);
thisSelector->drop();
}
else
{
//Node isn't an octree, we build a triangle selector based on bounding box
//Node isn't an octree, we build a triangle selector based on bounding box
irr::scene::ITriangleSelector* thisSelector = mDevice->getSceneManager()->createTriangleSelectorFromBoundingBox(forSceneNode);
//And we add it to the metaSelector
mSelector->addTriangleSelector(thisSelector);
thisSelector->drop();
}
}
if(userData->getAttributeAsBool("Collider"))
{
//Now we animate nodes that are supposed to respond to collisions based on the metaselector
//create an animator using the metaselector. Collision values are arbitrary. Elipsoid is made according to mesh bounding box
irr::scene::ISceneNodeAnimatorCollisionResponse* anim = mDevice->getSceneManager()->createCollisionResponseAnimator(
mSelector, forSceneNode, forSceneNode->getBoundingBox().MaxEdge,
irr::core::vector3df(0,-1,0), irr::core::vector3df(0,0,0));
//Adding the animator to the node
forSceneNode->addAnimator(anim);
anim->drop();
std::cout<< "here at collider";
}
}
void CollisionMaker::LoadScene(const c8 *filename)
{
mDevice->getSceneManager()->loadScene(filename, this);
}
void CollisionMaker::AddCollisionCam ()
{
//This is my code! I adapted the collision camera code from the collision tut
//Basically I added a new function that creates a camera that collides with stuff
//to the class. I did it in the class for neatness and because all of the stuff was declared here
//any way. As to the changes to the Collision tut code i replaces smgr with
//mDevice->getSceneManager() this gets the secen manager from mDevice. Also selcector (one mesh)
//is replaced with the mSlector (definged eirler, contains sub slectors in one big slector)
/*
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. The only thing we have to tell the animator is how the world looks like,
how big the scene node is, how gravity and so on. After the collision response animator
is attached to the camera, we do not have to do anything more for collision detection,
anything is done automaticly, all other collision detection code below is for picking.
And please note another cool feature: The collsion response animator can be attached
also to all other scene nodes, not only to cameras. And it can be mixed with other
scene node animators. In this way, collision detection and response in the Irrlicht
engine is really, really easy.
Now we'll take a closer look on the parameters of createCollisionResponseAnimator().
The first parameter is the TriangleSelector, which specifies how the world, against
collision detection is done, looks like. The second parameter is the scene node, which
is the object, which is affected by collision detection, in our case it is the camera.
The third defines how big the object is, it is the radius of an ellipsoid. Try it out
and change the radius to smaller values, the camera will be able to move closer to walls
after this. The next parameter is the direction and speed of gravity. You could
set it to (0,0,0) to disable gravity. And the last value is just a translation: Without
this, the ellipsoid with which collision detection is done would be around the camera,
and the camera would be in the middle of the ellipsoid. But as human beings, we are
used to have our eyes on top of the body, with which we collide with our world, not
in the middle of it. So we place the scene node 50 units over the center of the
ellipsoid with this parameter. And that's it, collision detection works now.
*/
scene::ICameraSceneNode* camera =
mDevice->getSceneManager()->addCameraSceneNodeFPS(0, 100.0f, 300.0f, -1, 0, 0, true);
camera->setPosition(core::vector3df(0,1300,0));
if (mSelector)
{
scene::ISceneNodeAnimator* animcam = mDevice->getSceneManager()->createCollisionResponseAnimator(
mSelector, camera, core::vector3df(10,50,10),
core::vector3df(0,-0.1,0),
core::vector3df(0,50,0));
mSelector->drop();
camera->addAnimator(animcam);
animcam->drop();
}
}
int main()
{
// ask user for driver
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_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
// create device and exit if creation failed
IrrlichtDevice* device =
createDevice(driverType, core::dimension2d<s32>(640, 480));
if (device == 0)
return 1; // could not create selected driver.
device->setWindowCaption(L"Load .irr file example");
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
/* Now load our .irr file.
.irr files can store the whole scene graph including animators, materials
and particle systems. And there is also the possibility to store arbitrary
user data for every scene node in that file. To keep this
example simple, we are simply loading the scene here. See the documentation
at ISceneManager::loadScene and ISceneManager::saveScene for more information.
So to load and display a complicated huge scene, we only need a single call
to loadScene().
*/
// load the scene
CollisionMaker mk(device);
mk.LoadScene("scenes/Scene.irr");
std::cout<< "here at load";
/*
That was it already. Now add a camera and draw the scene
*/
// add a user controlled camera
mk.AddCollisionCam ();
// and draw everything.
int lastFPS = -1;
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, video::SColor(0,200,200,200));
smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Load Irrlicht File example - Irrlicht Engine [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();
return 0;
}