Here is a full source for loading a IRRFile the parse it to get the Occtree from the scene and add them to the MetaSelector to be applied then to the Camera (FPS in this case) CollisionResponseAnimator.
Remember that your objects that you want to have collision must be OCCTREE in IRREDIT. All other types are not treated.
Also that code check for the first Camera Node then apply the Position to the FPS Camera. So you can define a Camera in IRRedit, and this code will retrieve it and position your FPS Camera accordingly.
Vitek helped me a lot on this code. It took me 1 hour to create that source, but 2-3 months to understand the Vitek source clearly.
I think this code could help a lots of new user to IrrLicht get their hands on the engine fast using IRREdit and test it under that source.
Here is the code:
Code: Select all
#include <irrlicht.h>
#pragma comment(lib, "Irrlicht.lib")
#include <iostream>
#include <windows.h>
using namespace irr;
using namespace irr::core;
using namespace irr::scene;
IrrlichtDevice *intro = 0;
video::IVideoDriver* driver = 0;
scene::ISceneManager* smgr;
scene::IMetaTriangleSelector* metaSelector;
scene::ISceneNodeAnimatorCollisionResponse* anim;
ICameraSceneNode* camera = 0;
bool fin1;
void recursiveFillMetaSelector(scene::ISceneNode* node, scene::IMetaTriangleSelector* meta )
{
//
// the following if is basically the same as ISceneNode_assignTriangleSelector
//
printf ("Node name is: %s \n",node->getName());
printf ("Node id is: %d \n",node->getID());
printf ("Node type:");
// printf ("Node type: %s=",smgr->getSceneNodeTypeName());
if (node->getType() == ESNT_UNKNOWN) printf("Unknown mesh type \n\n");
if (node->getType() == ESNT_MESH) printf("Standard Mesh \n\n");
if (node->getType() == ESNT_ANIMATED_MESH) printf("Animated Mesh! \n\n");
if (node->getType() == ESNT_SKY_BOX) printf("SkyBox! \n\n");
if (node->getType() == ESNT_CAMERA_FPS) printf("Fps Camera! \n\n");
if (node->getType() == ESNT_CAMERA_MAYA ) printf("Maya Camera! \n\n");
if (node->getType() == ESNT_CAMERA )
{ printf("STD Camera! \n");
printf ("The current position of this camera is: %f,%f,%f\n\n",node->getPosition().X,node->getPosition().Y,node->getPosition().Z);
camera->setPosition(node->getPosition());
}
if (node->getType() == ESNT_PARTICLE_SYSTEM ) printf("Particles! \n\n");
if (node->getType() == ESNT_LIGHT ) printf("Light! \n\n");
if (node->getType() == ESNT_OCT_TREE)
{
// Occ Trees are for land
printf("Occtree! \n");
io::IAttributes* attribs = intro->getFileSystem()->createEmptyAttributes();
if (attribs)
{// get the mesh name out
node->serializeAttributes(attribs);
core::stringc name = attribs->getAttributeAsString("Mesh");
attribs->drop();
// get the animated mesh for the object
scene::IAnimatedMesh* mesh = smgr->getMesh(name.c_str());
if (mesh)
{
scene::ITriangleSelector* selector =
smgr->createOctTreeTriangleSelector(mesh->getMesh(0), node, 128);
node->setTriangleSelector(selector);
metaSelector->addTriangleSelector(selector);
selector->drop();
}
}
}
// now recurse on children...
core::list<scene::ISceneNode*>::Iterator begin = node->getChildren().begin();
core::list<scene::ISceneNode*>::Iterator end = node->getChildren().end();
for (; begin != end; ++begin)
recursiveFillMetaSelector(*begin, meta);
}
int main()
{
// Get the full desktop size from Windows.H
// First the width
int nWidth = GetSystemMetrics(0);
// Second the Height
int nHeight = GetSystemMetrics(1);
intro = createDevice(video::EDT_DIRECT3D9, core::dimension2d<s32>(800, 600), 32, false, true, true);
driver = intro->getVideoDriver();
smgr = intro->getSceneManager();
core::stringw str = "Level Demo";
intro->setWindowCaption(str.c_str());
// Define the Keyboard to use for the camera moves
SKeyMap keyMap[9];
keyMap[0].Action = EKA_MOVE_FORWARD;
keyMap[0].KeyCode = KEY_UP;
keyMap[1].Action = EKA_MOVE_FORWARD;
keyMap[1].KeyCode = KEY_KEY_W;
keyMap[2].Action = EKA_MOVE_BACKWARD;
keyMap[2].KeyCode = KEY_DOWN;
keyMap[3].Action = EKA_MOVE_BACKWARD;
keyMap[3].KeyCode = KEY_KEY_S;
keyMap[4].Action = EKA_STRAFE_LEFT;
keyMap[4].KeyCode = KEY_LEFT;
keyMap[5].Action = EKA_STRAFE_LEFT;
keyMap[5].KeyCode = KEY_KEY_A;
keyMap[6].Action = EKA_STRAFE_RIGHT;
keyMap[6].KeyCode = KEY_RIGHT;
keyMap[7].Action = EKA_STRAFE_RIGHT;
keyMap[7].KeyCode = KEY_KEY_D;
keyMap[8].Action = EKA_JUMP_UP;
keyMap[8].KeyCode = KEY_SPACE ;
// Setup the ZIP file "MyLevel.pk3" to be read directly
intro->getFileSystem()->addZipFileArchive("levels/MyLevel.pk3");
// Load the scene file from the archive
smgr->loadScene("MyLevel.irr");
camera = smgr->addCameraSceneNodeFPS(0, 120.0f, 120.0f, -1, keyMap, 9, true,0.25f);
camera->setRotation(core::vector3df(0,135,0));
camera->setFarValue(11000.0);
camera->setAspectRatio(16/10);
camera->setFOV(PI/2.5);
metaSelector = smgr->createMetaTriangleSelector();
recursiveFillMetaSelector( smgr->getRootSceneNode(), metaSelector );
// DEfine the collision reponse for the FPS Camera
anim = smgr->createCollisionResponseAnimator( metaSelector, camera, core::vector3df(10,26,10),
//metaSelector, camera, core::vector3df(10,26,10),
core::vector3df(0,-1.0f,0),
core::vector3df(0,24,0));
camera->addAnimator(anim);
anim->drop();
metaSelector->drop();
while(intro->run() and fin1==false)
{
if (intro->isWindowActive())
{
driver->beginScene(true, true, video::SColor(0,0,0,0));
smgr->drawAll();
driver->endScene();
}
}
intro->closeDevice();
return 0;
}
A) I've put a little code in there to get the desktop width and height and get them. The variable are there but not applied (If you would like that it take your full desktop resolution, it's in there (Variables: nWidth, nHeight).
Since the codes for getting the desktop resolution is windows only, Linux users should remove the "windows.h" and the 2 variables definitions and it should work also fine.
B) This code should run fine in IrrLicht 1.2 and 1.3.1 but not in 1.3. In 1.3 there is a bug that prevent one of the function there to operate correctly.
EDIT: Here is a modified version of the code that should work in 1.4, 1.5 version of IRRlicht:
Code: Select all
#include <irrlicht.h>
#pragma comment(lib, "Irrlicht.lib")
#include <iostream>
#include <windows.h>
using namespace irr;
using namespace irr::core;
using namespace irr::scene;
IrrlichtDevice *intro = 0;
video::IVideoDriver* driver = 0;
scene::ISceneManager* smgr;
scene::IMetaTriangleSelector* metaSelector;
scene::ISceneNodeAnimatorCollisionResponse* anim;
ICameraSceneNode* camera = 0;
bool fin1;
void recursiveFillMetaSelector(scene::ISceneNode* node, scene::IMetaTriangleSelector* meta )
{
//
// the following if is basically the same as ISceneNode_assignTriangleSelector
//
printf ("Node name is: %s \n",node->getName());
printf ("Node id is: %d \n",node->getID());
printf ("Node type:");
// printf ("Node type: %s=",smgr->getSceneNodeTypeName());
if (node->getType() == ESNT_UNKNOWN) printf("Unknown mesh type \n\n");
if (node->getType() == ESNT_MESH) printf("Standard Mesh \n\n");
if (node->getType() == ESNT_ANIMATED_MESH) printf("Animated Mesh! \n\n");
if (node->getType() == ESNT_SKY_BOX) printf("SkyBox! \n\n");
if (node->getType() == ESNT_CAMERA_FPS) printf("Fps Camera! \n\n");
if (node->getType() == ESNT_CAMERA_MAYA ) printf("Maya Camera! \n\n");
if (node->getType() == ESNT_CAMERA )
{ printf("STD Camera! \n");
printf ("The current position of this camera is: %f,%f,%f\n\n",node->getPosition().X,node->getPosition().Y,node->getPosition().Z);
camera->setPosition(node->getPosition());
}
if (node->getType() == ESNT_PARTICLE_SYSTEM ) printf("Particles! \n\n");
if (node->getType() == ESNT_LIGHT ) printf("Light! \n\n");
if (node->getType() == ESNT_OCT_TREE)
{
// Occ Trees are for land
printf("Occtree! \n");
io::IAttributes* attribs = intro->getFileSystem()->createEmptyAttributes();
if (attribs)
{// get the mesh name out
node->serializeAttributes(attribs);
core::stringc name = attribs->getAttributeAsString("Mesh");
attribs->drop();
// get the animated mesh for the object
scene::IAnimatedMesh* mesh = smgr->getMesh(name.c_str());
if (mesh)
{
scene::ITriangleSelector* selector =
smgr->createOctTreeTriangleSelector(mesh->getMesh(0), node, 128);
node->setTriangleSelector(selector);
metaSelector->addTriangleSelector(selector);
selector->drop();
}
}
}
// now recurse on children...
core::list<scene::ISceneNode*>::ConstIterator begin = node->getChildren().begin();
core::list<scene::ISceneNode*>::ConstIterator end = node->getChildren().end();
for (; begin != end; ++begin)
recursiveFillMetaSelector(*begin, meta);
}
int main()
{
// Get the full desktop size from Windows.H
// First the width
int nWidth = GetSystemMetrics(0);
// Second the Height
int nHeight = GetSystemMetrics(1);
intro = createDevice(video::EDT_DIRECT3D9, core::dimension2d<s32>(800, 600), 32, false, true, true);
driver = intro->getVideoDriver();
smgr = intro->getSceneManager();
core::stringw str = "Level Demo";
intro->setWindowCaption(str.c_str());
// Define the Keyboard to use for the camera moves
SKeyMap keyMap[9];
keyMap[0].Action = EKA_MOVE_FORWARD;
keyMap[0].KeyCode = KEY_UP;
keyMap[1].Action = EKA_MOVE_FORWARD;
keyMap[1].KeyCode = KEY_KEY_W;
keyMap[2].Action = EKA_MOVE_BACKWARD;
keyMap[2].KeyCode = KEY_DOWN;
keyMap[3].Action = EKA_MOVE_BACKWARD;
keyMap[3].KeyCode = KEY_KEY_S;
keyMap[4].Action = EKA_STRAFE_LEFT;
keyMap[4].KeyCode = KEY_LEFT;
keyMap[5].Action = EKA_STRAFE_LEFT;
keyMap[5].KeyCode = KEY_KEY_A;
keyMap[6].Action = EKA_STRAFE_RIGHT;
keyMap[6].KeyCode = KEY_RIGHT;
keyMap[7].Action = EKA_STRAFE_RIGHT;
keyMap[7].KeyCode = KEY_KEY_D;
keyMap[8].Action = EKA_JUMP_UP;
keyMap[8].KeyCode = KEY_SPACE ;
// Setup the ZIP file "MyLevel.pk3" to be read directly
intro->getFileSystem()->addZipFileArchive("levels/MyLevel.pk3");
// Load the scene file from the archive
smgr->loadScene("MyLevel.irr");
camera = smgr->addCameraSceneNodeFPS(0, 120.0f, 120.0f, -1, keyMap, 9, true,0.25f);
camera->setRotation(core::vector3df(0,135,0));
camera->setFarValue(11000.0);
camera->setAspectRatio(16/10);
camera->setFOV(PI/2.5);
metaSelector = smgr->createMetaTriangleSelector();
recursiveFillMetaSelector( smgr->getRootSceneNode(), metaSelector );
// DEfine the collision reponse for the FPS Camera
anim = smgr->createCollisionResponseAnimator( metaSelector, camera, core::vector3df(10,26,10),
//metaSelector, camera, core::vector3df(10,26,10),
core::vector3df(0,-1.0f,0),
core::vector3df(0,24,0));
camera->addAnimator(anim);
anim->drop();
metaSelector->drop();
while(intro->run() and fin1==false)
{
if (intro->isWindowActive())
{
driver->beginScene(true, true, video::SColor(0,0,0,0));
smgr->drawAll();
driver->endScene();
}
}
intro->closeDevice();
return 0;
}
Enjoy...