#0 

14-04-2010 08:13:50

nabouill
Abonné
Date d'inscription: 17-09-2009
Messages: 242
Corrections: 1

Voici une camera FPS que je trouve un peut optimisé. La différence avec celle intégré à Irrlicht:

-On peut lui indiquer des vitesses différente pour avancé, reculé et le déplacement latérale.
-elle se déplace parfaitement horizontalement, c'est à dire que contrairement a celle d'Irrlicht, elle ne saute pas sur place lorsque regarde vers le haut, ni se déplace 2 fois moins vite lorsqu'on regarde vers le bas (bien que l'on peut très facilement changer ce mode de déplacement et revenir au classique).

Dans ce code, pour la simplicité, je n'est pas fait une classe "cameraFPS" mais intégrer son fonctionnement directement dans un code de base.
Aussi, j'ai laisser le curseur visible pour voir comment il réagit.

Voilà la bête:

Code c++ :


#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;


}



J'ai commenté les lignes les plus importantes.

Et pour ceux que veulent la tester directement, l'exemple est téléchargeable ici:
une camera FPS

A+


mes sites: www.manga-vf.fr et www.series-vf.fr

Hors ligne


#1 

30-05-2012 21:25:02

Kirk
Membre
Date d'inscription: 02-02-2012
Messages: 14

Merci c'est super mais on ne peut pas sauter...


wofwar.olympe.in

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
Analysé par
880 membres
1424 sujets
11113 messages
Dernier membre inscrit: mandrifidy
33 invités en ligne
Aucun membre connecté
RSS Feed