Historique des modifications - Message

Message #4056

Sujet: Collision et sceneNode


TypeDateAuteurContenu
Dernière modification23-05-2008 04:48:35nikska
Voila je vous présente un code d'essai des collisions.

fichier main.cpp
#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

#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

#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...
Création du message23-05-2008 03:24:36nikska
Voila je vous présente un code d'essai des collisions.

fichier main.cpp
#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

#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

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

Retour

OptionsLiens officielsCaractéristiquesStatistiquesCommunauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1441 sujets
11339 messages
Dernier membre inscrit: Saidov17
114 invités en ligne
membre en ligne: -
RSS Feed