#0 

06-08-2010 05:35:50

iLambda²
Membre
Date d'inscription: 07-02-2010
Messages: 29

Tout d'abord bonjour smile
Ca fait une bonne semaine que je me creuse sur la facon de déplacer un personnage en 3D (Node) en fonction de sa rotation, et comme je viens de finir, et de tester que le code est opérationnel, je dépose ce code, car, qui sait, il pourra aider les débutants comme moi ^^

Waypoint.hWaypoint.cppPath.hPath.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#ifndef DEF_WAYPOINT
#define DEF_WAYPOINT

#include <irr\irrlicht.h>
#include <vector>

enum WayPointType{
    LOOKAROUND, FOLLOW, FORWARD, FLYABLE
};

class Waypoint{

    private:
        bool visible;
        int GUID;

        WayPointType type;
        irr::core::vector3df position;
       
    public:
        Waypoint();
        Waypoint(irr::core::vector3df positionc, WayPointType typec, int GUIDc, bool visiblec = false);
        ~Waypoint();

    public:
        irr::core::vector3df getPosition();
        WayPointType getType();
        bool isVisible();
        int getGUID();

        void setType(WayPointType a);
        void setVisible(bool a);
        void setGUID(int a);

};

#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <irr\irrlicht.h>
#include "Waypoint.h"

Waypoint::Waypoint(){}
Waypoint::Waypoint(irr::core::vector3df positionc, WayPointType typec, int GUIDc, bool visiblec){
    position = positionc;
    type = typec;
    GUID = GUIDc;
    visible = visiblec;
}

irr::core::vector3df Waypoint::getPosition(){return position;}
WayPointType Waypoint::getType(){return type;}
bool Waypoint::isVisible(){return visible;}
int Waypoint::getGUID(){return GUID;}

void Waypoint::setType(WayPointType a){type = a;}
void Waypoint::setVisible(bool a){visible = a;}
void Waypoint::setGUID(int a){GUID = a;}   

Waypoint::~Waypoint(){}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#ifndef DEF_PATH
#define DEF_PATH

#include <irr/irrlicht.h>
#include <vector>

#include "Waypoint.h"
#include "Timer.h"

#define STEP_LOOP 0.0001f
#define STEP_LOOP_PRODUCT 10000

class Path{

    public:
        int length;
        int step;
        int i;

        std::vector<Waypoint> pathWaypoint;
        std::vector<irr::core::vector3df> pathFinal;

        irr::scene::ISceneNode* node;
        Timer t;

    public:
        Path();
        Path(int WaypointsGUID[], std::vector<Waypoint> intoSearchGUID, int length, int speed);
        ~Path();

    public:
        void updatePosition(irr::scene::ISceneNode* _node);

};

#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <irr\irrlicht.h>
#include <vector>

#include "Waypoint.h"
#include "Path.h"
#include "Timer.h"

Path::Path(){}
Path::Path(int WaypointsGUID[], std::vector<Waypoint> intoSearchGUID, int l, int speed){
    std::vector<Waypoint> pathWay;
    std::vector<irr::core::vector3df> pathFinalc;

    length = l;
    step = speed;
    i = 0;
    npc = 0;
    t.setInterval(1);


        for(int i = 0 ; i != intoSearchGUID.size() ; i++){
            for(int j = 0 ; j != l ; j ++){
                if(intoSearchGUID.at(i).getGUID() == WaypointsGUID[j]){
                    pathWay.push_back(intoSearchGUID.at(i));
                }
            }
        }

    for(int i = 0 ; i != l ; i++){
        for(int j = 0 ; j != STEP_LOOP_PRODUCT ; j++){
            if(i == l-1){

            }
            else{
                irr::core::vector3df toAdd = pathWay.at(i).getPosition().getInterpolated(pathWay.at(i+1).getPosition(), STEP_LOOP*(STEP_LOOP_PRODUCT-j));
                pathFinalc.push_back(toAdd);
            }
        }
    }

    pathWaypoint = pathWay;
    pathFinal = pathFinalc;

}

void Path::updatePosition(irr::scene::ISceneNode * _node){

    if(node == 0){
        node = _node;
    }

        if(t.isExceed() && i < pathFinal.size() - 1){
            node->setPosition(pathFinal.at(i));
            i += step;
            t.reset();
        }   
}

Path::~Path(){}


Je ne reposte pas le Timer.h car il provient du tuto de Nabouill dispo ici : href=http://irrlicht-fr.org/lire_tuto.php?id=1299
Très simple d'utilisation, il suffit de créer un vector qui contiendra tout les Waypoints (http://en.wikipedia.org/wiki/Waypoint), de donner des ID qui DOIVENT ETRE TOUTES DIFFERENTES aux Waypoint(voir constructeur), puis créer un Path en lui mettant en parametre un tableau qui contient les ID des Waypoint ou le node doit aller, de lui donner le std::vector qui contient les Waypoints, de lui donner le nombre de Waypoints a parcourir et surtout la vitesse (Nombre d'unités en 1ms), puis de placer path.updatePosition(node); dans la boucle de rendu.

(Le déplacement du node s'effectue grace a l'interpolation de divers vector3df entre le waypoint x et le waypoint x+1, donc mettez des Waypoints si vous avez a parcourir une grande ligne droite par exemple, pour éviter le déplacement saccadé.)

Exemple :

Code c++ :

    //Ajout des WayPoints (Waypoint(position, type, IDunique, visible);
    worldspawn_waypoints.push_back(Waypoint(irr::core::vector3df(30.6174f, 138.702f, -126.354f), WayPointType::FOLLOW, 0, false));
    worldspawn_waypoints.push_back(Waypoint(irr::core::vector3df(24.1609f, 138.702f, -253.591f), WayPointType::FOLLOW, 1, false));
    worldspawn_waypoints.push_back(Waypoint(irr::core::vector3df(-91.432f, 138.702f, -253.685f), WayPointType::FOLLOW, 2, false));

    //Mise en place du chemin a marcher pour le node
    int guids[] = {0, 1, 2};
    Path path(guids, worldspawn_waypoints, 3, 30);

    //Boucle de rendu
        while (device->run())
        {
            driver->beginScene(true, true, irr::video::SColor(255,0,0,0));
                [...]
            path.updatePosition(node);
                [...]
            smgr->drawAll();
            driver->endScene();
        }


Voila si vous avez besoin d'aide laissez un message ou MPez moi, je répondrai smile
Merci bien et bonne continuation avec IrrLicht smile

Dernière modification par iLambda² (06-08-2010 05:38:08)

Hors ligne


#1 

06-08-2010 11:29:18

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

Salut, ton code est sans doute parfaitement fonctionnel, mais je le trouve quand même peu lourd juste pour déplacer un node dans la bonne direction. Personnellement, j'utilise une toute autre méthode. Regarde ce petit bout de code:

Code c++ :


void move(ISceneNode *node, vector3df vel)
{
    matrix4 m;
    m.setRotationDegrees(node->getRotation());
    m.transformVect(vel);
    node->setPosition(node->getPosition() + vel);
    node->updateAbsolutePosition();
}



int main(int argc, char** argv)
{
// ...
    IAnimatedMeshSceneNode* personnage = sceneMgr->addAnimatedMeshSceneNode(sceneMgr->getMesh("personnage.b3d"));
   
    u32 now = device->getTimer()->getTime();;
    u32 then = now;
    f32 frameDeltaTime = 0
    f32 vitesse_deplacement = 50; // vitesse de depacement a 50 unitées par seconde
// ...
   while(device->run)
   {
        now = device->getTimer()->getTime();
        frameDeltaTime = (f32)(now - then) / 1000.f; // Temps en seconde
        then = now;

        if(myReceiver.IsKeyDown(KEY_UP))
        {
               unit = vitesse_deplacement * frameDeltaTime;
               move(personnage, vector3df(0.0, 0.0, unit));
        }
   }
}



A+


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

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
881 membres
1426 sujets
11116 messages
Dernier membre inscrit: Bidule
21 invités en ligne
Aucun membre connecté
RSS Feed