Collision et sceneNode

Proposé par nikska

le 23 May 2008 à 05h 24mn 36s

5945 visualisations



Voila je vous présente un code d'essai des collisions.

fichier main.cpp

Code:

#include <irrlicht.h>
#include "MyEventReceiver.h"

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;


int main(int argc, char** argv)
{


    IrrlichtDevice* device = createDevice( video::EDT_OPENGL, core::dimension2d<s32>(1000, 800),32, false, false, false);


    device->setWindowCaption(L"Collisions");


    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* guienv = device->getGUIEnvironment();


    IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
    IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );


    if (node)
    {
        node->setMaterialFlag(EMF_LIGHTING, false);
        node->setFrameLoop(0, 0);
        node->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp") );


    }


    scene::ICameraSceneNode * camera = smgr->addCameraSceneNodeFPS(0);
    camera->setPosition(core::vector3df(0, 55, -30));

    // ajout du terrain
    scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
                                            "../../media/terrain-heightmap.bmp",
                                            0,                                        // parent node
                                            -1,                                        // node id
                                            core::vector3df(-1000.f, -500.f, -1000.f),            // position
                                            core::vector3df(0.f, 0.f, 0.f),            // rotation
                                            core::vector3df(40.f, 4.4f, 40.f),        // scale
                                            video::SColor ( 255, 255, 255, 255 ),    // vertexColor,
                                            5,                                        // maxLOD
                                            scene::ETPS_17,                            // patchSize
                                            4                                        // smoothFactor
                                        );

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

    // création du selector du terrain
    scene::ITriangleSelector* selector = smgr->createTerrainTriangleSelector(terrain, 0);
    terrain->setTriangleSelector(selector);

    // create collision response animator and attach it to the camera
    scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
                                          selector, camera, core::vector3df(60,50,60),
                                          core::vector3df(0,0,0),
                                          core::vector3df(0,50,0));

    //création de l'animator et l'attache au mesh de sydney
    scene::ISceneNodeAnimator* anim2 = smgr->createCollisionResponseAnimator(
                                          selector, node, core::vector3df(30,50,30),
                                          core::vector3df(0,-100,0));

    selector->drop();
    camera->addAnimator(anim);
    node->addAnimator(anim2);
    anim->drop();
    anim2->drop();

    MyEventReceiver receiver(node);
    device->setEventReceiver(&receiver);

    bool bouje; 
    bool boujeActif;
    while (device->run())
    {

        driver->beginScene(true, true, SColor(0,200,200,200));

        smgr->drawAll();
        guienv->drawAll();

        driver->endScene();
        receiver.majPosMesh();
    }


    device->drop();

    return 0;
}

fichier MyEventReceiver.h

Code:

#ifndef DEF_MYEVENTRECEIVER
#define DEF_MYEVENTRECEIVER

#include <irrlicht.h>


class MyEventReceiver : public irr::IEventReceiver
{
public:

    MyEventReceiver(irr::scene::IAnimatedMeshSceneNode* );
    virtual bool OnEvent(const irr::SEvent& );

    //met à jour la position de l'objet
    void majPosMesh();


private :
    //Le modele qu'on va controler.
    irr::scene::IAnimatedMeshSceneNode* m_Nmodele;

   //va permettre de changer la position de l'objet par rapport à son axe
    irr::core::matrix4 Mat; 

    //Indique si l'objet est en mouvement
    bool m_isMoving;

    //reçoit la valeur de la touche enfoncée
    char *myKeyPressed;

};

#endif

fichier MyEventReceiver.cpp

Code:

#include <irrlicht.h>
#include "MyEventReceiver.h"

using namespace irr;

MyEventReceiver::MyEventReceiver(scene::IAnimatedMeshSceneNode* Nmodele )
{
    //On pointe le mesh passe en parametre.
    m_Nmodele = Nmodele;
    //Par defaut on ne bouge pas
    m_isMoving = false;
    myKeyPressed = NULL;

}

bool MyEventReceiver::OnEvent(const SEvent& event)
{
   //Si l'objet existe et qu'une touche est préssé
    if (m_Nmodele != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT
            && (event.KeyInput.Key == irr::KEY_KEY_Z
                ||event.KeyInput.Key == irr::KEY_KEY_S
                ||event.KeyInput.Key == irr::KEY_KEY_Q
                ||event.KeyInput.Key == irr::KEY_KEY_D))
    {
       //gère les différent cas suivant la touche
        switch (event.KeyInput.Key)
        {
        case irr::KEY_KEY_Z:
            //On y ajoute la valeur de déplacement
            myKeyPressed="Z";
            //On renvoie la nouvelle position
            break;
        case irr::KEY_KEY_S:
            myKeyPressed="S";

            break;
        case irr::KEY_KEY_Q:
            myKeyPressed="Q";
            break;
        case irr::KEY_KEY_D:
            myKeyPressed="D";
            break;
        default :
            break;
        }
        m_isMoving = event.KeyInput.PressedDown;

        return true;
    }
    return false;
}


void MyEventReceiver::majPosMesh()
{

    //faire tomber un mesh
    //sans cette ligne, le mesh ne tombe pas et donc ne suivra plus le terrain en descente
    //faite un test sans cette ligne vous comprendrez
    m_Nmodele->setPosition(m_Nmodele->getPosition() - core::vector3df(0.0, 0.05, 0.0));

    //On vérifie que le pointeur vers le mesh est
    //ok et que la touche est enfoncée
    if (m_Nmodele != 0 && m_isMoving == true)
    {
        //On commence par récupérer la position actuelle
        core::vector3df v = m_Nmodele->getPosition();
        //et sa rotation pour que l'objet bouge en se basant sur son axe
        core::vector3df r = m_Nmodele->getRotation();

        if (myKeyPressed=="Z")
        {

            //On y ajoute la valeur de deplacement
            Mat.setRotationDegrees(m_Nmodele->getRotation());
            core::vector3df Target(0.2,0,0);
            Mat.transformVect(Target);
            core::vector3df NewPos=m_Nmodele->getPosition();
            NewPos += Target;
            m_Nmodele->setPosition(NewPos);



        }
        else if (myKeyPressed=="S")
        {
            Mat.setRotationDegrees(m_Nmodele->getRotation());
            core::vector3df Target(-0.2,0,0);
            Mat.transformVect(Target);
            core::vector3df NewPos=m_Nmodele->getPosition();
            NewPos += Target;
            m_Nmodele->setPosition(NewPos);
        }
        if (myKeyPressed=="Q")
        {
            r.Y-= 0.1;
            m_Nmodele->setRotation(r);
        }
        else if (myKeyPressed=="D")
        {

            r.Y+= 0.1;
            m_Nmodele->setRotation(r);
        }

    }

}

C'est un code à améliorer mais au moins ca donne une base.

Je suis persuadé de la fonction smgr->createCollisionResponseAnimator(); n'est pas adapté à une sceneNode mais bon... j'ai pas trouvé mieux pour l'instant !
Si quelqu'un avait une idée...


#1 

07-11-2010 23:33:44

mmorpglefilm
Abonné
Lieu: la galaxie UDFy-38135539
Date d'inscription: 18-05-2010
Messages: 162
Site web

Merci pour se petit tuto, tu ma bien aider...

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
883 membres
1429 sujets
11121 messages
Dernier membre inscrit: Saidov17
138 invités en ligne
Aucun membre connecté
RSS Feed