#include <irrlicht.h>
using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace gui;
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// GESTION EVENEMENT
///////////////////////////////////////////////////////////////////////////////////////////////////////
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
// Remember whether each key is down or up
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// MES FONCTIONS
///////////////////////////////////////////////////////////////////////////////////////////////////////
void moveCamera(irr::scene::ISceneNode *node, vector3df unite)
{
matrix4 m;
m.setRotationDegrees(vector3df(0, node->getRotation().Y, 0));
m.transformVect(unite);
node->setPosition(node->getPosition() + unite);
node->updateAbsolutePosition();
}
void targetCamera(ICameraSceneNode* camera)
{
vector3df rotCam = camera->getRotation();
vector3df pos(0.0f,0.0f,1000.0f);//1000 en Z pour regarder a 1000 unité devant nous
matrix4 mat;
mat.setRotationDegrees(rotCam);
mat.transformVect(pos);
camera->setTarget(camera->getAbsolutePosition() + pos);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// LA FONCTIONS MAIN
///////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
int Lwindows = 640;//important de stocker la taille de la fenetre dans des variable pour positionner le curseur
int Hwindows = 480;
IrrlichtDevice *device = createDevice(EDT_DIRECT3D9, core::dimension2d<u32>(Lwindows,Hwindows),32,false,false,false);
IVideoDriver* driver = device->getVideoDriver ();
ISceneManager* sceneMgr = device->getSceneManager ();
MyEventReceiver myReceiver;
device->setEventReceiver(&myReceiver);
device->getCursorControl()->setVisible(true);
///creation d'une camera basic
ICameraSceneNode* myCamera = sceneMgr->addCameraSceneNode();
myCamera->setPosition(vector3df(1000,2000,1000));
//création du terrain
scene::ITerrainSceneNode* terrain = sceneMgr->addTerrainSceneNode(
"media/terrain-heightmap.bmp",
0,
-1,
core::vector3df(0.f, 0.f, 0.f),
core::vector3df(0.f, 0.f, 0.f),
core::vector3df(20.f, 1.0f, 20.f),
video::SColor ( 255, 255, 255, 255 ),
5,
scene::ETPS_17,
4
);
terrain->setMaterialFlag(video::EMF_LIGHTING, false);
terrain->setMaterialTexture(0,driver->getTexture("media/terrain-texture.jpg"));
terrain->setMaterialTexture(1,driver->getTexture("media/detailmap3.jpg"));
terrain->setMaterialType(video::EMT_DETAIL_MAP);
terrain->scaleTexture(1.0f, 20.0f);
// create triangle selector for the terrain
ITriangleSelector* selector = sceneMgr->createTerrainTriangleSelector(terrain, 0);
terrain->setTriangleSelector(selector);
// terrain->setVisible(false);
// create collision response animator and attach it to the camera
ISceneNodeAnimator* anim = sceneMgr->createCollisionResponseAnimator(
selector, myCamera,
vector3df(60,200,60),
vector3df(0,-10,0),
vector3df(10,10,10),
0.0001f);//pour un meilleur glissement
selector->drop();
myCamera->addAnimator(anim);
anim->drop();
///creation d'un curseur et initialisation des vitesse de deplacement de la camera
ICursorControl* curseur = device->getCursorControl();
//on met le curseur au milieu de l'ecran
curseur->setPosition(Lwindows/2,Hwindows/2);
f32 move_speed_front = 600;
f32 move_speed_back = 200;
f32 move_speed_latt = 300;
f32 rot_speed = 100;
u32 then = device->getTimer()->getTime();
u32 now = device->getTimer()->getTime();
f32 frameDeltaTime;
int fps;
int lastFPS;
while(device->run())
{
// Work out a frame delta time.
now = device->getTimer()->getTime();
frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
then = now;
///rotation
//on recupere la position du curseur
vector2d<f32> posMouse= curseur->getRelativePosition();
//on fait faire une rotation a la camera suivant la position du curseur
myCamera->setRotation(myCamera->getRotation()+
vector3df( (posMouse.Y - 0.5f)*rot_speed,
(posMouse.X - 0.5f) * rot_speed,
0));
//on verifie si notre camera ne regarde pas trop haut ou trop bas, sinon on ajuste
if(myCamera->getRotation().X > 89.0f)
{
myCamera->setRotation(vector3df(89, myCamera->getRotation().Y, 0.0f));
}
if(myCamera->getRotation().X < -89.0f)
{
myCamera->setRotation(vector3df(-89.0f, myCamera->getRotation().Y, 0.0f));
}
//mise a jour de la target
targetCamera(myCamera);
//on remet le curseur au milieu de l'ecran
curseur->setPosition(Lwindows/2,Hwindows/2);
/// pour avancé
if(myReceiver.IsKeyDown(KEY_UP))
{
f32 unit = move_speed_front*frameDeltaTime;
moveCamera(myCamera, vector3df(0,0.01,unit));
/* on a ajouté 0.01 sur l'axe Y, ceci ne parrait
abolument pas, mais empeche la camera a entrer
en collision avec des chose non souhaité */
}
/// pour RECULER
if(myReceiver.IsKeyDown(KEY_DOWN))
{
f32 unit = move_speed_back*frameDeltaTime;
moveCamera(myCamera, vector3df(0,0.01,-unit));
}
/// pour GAUCHE
if(myReceiver.IsKeyDown(KEY_LEFT))
{
f32 unit = move_speed_latt*frameDeltaTime;
moveCamera(myCamera, vector3df(-unit,0.01,0));
}
/// pour DROITE
if(myReceiver.IsKeyDown(KEY_RIGHT))
{
f32 unit = move_speed_latt*frameDeltaTime;
moveCamera(myCamera, vector3df(unit,0.01,0));
}
// pour quittez le programme
if(myReceiver.IsKeyDown(KEY_ESCAPE))
{ device->closeDevice();
}
driver->beginScene(true, true, SColor(0,0,255,255));
sceneMgr->drawAll();
driver->endScene();
fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"TEST CAMERA_FPS [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();// destruction de device
return 0;
}