Historique des modifications - Message

Message #4056

Sujet: Collision et sceneNode


Type Date Auteur Contenu
Dernière modification 23-05-2008 04:48:35 nikska
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 message 23-05-2008 03:24:36 nikska
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

Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
192 invités en ligne
membre en ligne: -
RSS Feed