#0 

20-10-2007 12:08:26

Zangetsu
Petit nouveau
Date d'inscription: 27-02-2007
Messages: 6

Bonjours à tous, j'ai réalisé une class pour faire une camera a la 3eme personne en me basant sur une trouvé sur le net (http://irrlicht.sourceforge.net/phpBB2/ … php?t=1140).

Je l'ai largement modifieé afin qu'elle corresponde un peu plus a mes critères, en esperant que sa puisse venir en aide a certains.

Je ne suis pas un as de la programmation, ainsi toute les remarques et améliorations sont les bienvenus.

Derniere chose, j'ai utilisé irrlicht 1.2 pour compiler ce code, méfiance donc si vous utilisez une autre version, il me semble qu'il doit y avoir quelque petite modif.


FollowingCamera.hppexemple.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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

#include<irrlicht.h>

using namespace irr;
using namespace core;                 
using namespace scene;                                                   

class FollowingCamera
{
     ISceneNode* pTargetNode;
     ICameraSceneNode* Camera;

     vector3df LastTargetPosition;
     vector3df LastTargetRotation;
     
     vector3df NewCamPosition;
     vector3df FinalCamPosition;
     vector3df Vecteur;

     bool MonInitialPos;            // Mettre true pour utiliser la position initiale de la camera.
     f32 MaDistance;                // Distance entre l'objet et la camera.
     f32 MonAltitudeCamera;         // Hauteur de la camera, par rapport a l'objet.
     f32 MonDeltaCible;             // Permet d'incrementer ou de decrementer la hauteur du point cible (par defaut le centre de l'objet).
     vector3df MonInitialCamPosition;  // vecteur permettant d'initialiser la position de la camera.(facultatif)
                                       // par defaut la camera se place derriere l'objet suivant la distance et la hauteur indiqué.
     f32 EcartObj;
     f32 EcartXObj;
     f32 EcartZObj;
     f32 DistX;
     f32 VittX;
     f32 DistY;
     f32 VittY;
     f32 DistZ;
     f32 VittZ;
     f32 CoeffVittCam;
     f32 ix;
     f32 iy;
     f32 iz;
     
     bool TestNode ;
     bool Verrou ;

     public:
     // constructeur
     FollowingCamera(ISceneNode* TargetNode, ISceneManager*smgr,
                     bool InitialPos = false, ITriangleSelector* selectorCam,
                     f32 Distance = 200.0f, f32 AltitudeCamera = 100.0f, f32 DeltaCible = 0.0f,
                     vector3df InitialCamPosition = vector3df(-100.0f, 100.0f, 0.0f),
                     s32 id = -1);

     // destructeur
     ~FollowingCamera();

     ICameraSceneNode* getCam() { return Camera; }

     void Update();
};

// constructeur
FollowingCamera::FollowingCamera(ISceneNode* TargetNode, ISceneManager*smgr,
                                 bool InitialPos,
                                 ITriangleSelector* selectorCam = 0,
                                 f32 Distance, f32 AltitudeCamera, f32 DeltaCible,
                                 vector3df InitialCamPosition,
                                 s32 id )
{
     MonInitialPos = InitialPos;
     MaDistance = Distance;
     MonAltitudeCamera = AltitudeCamera;
     MonDeltaCible = DeltaCible;
     MonInitialCamPosition = InitialCamPosition;
     
     LastTargetPosition = TargetNode->getPosition();
     
     Vecteur = vector3df(LastTargetPosition.X,LastTargetPosition.Y+DeltaCible,LastTargetPosition.Z);

     TestNode = true;
     Verrou = false;
     
     CoeffVittCam = 200;       // coefficient de vitesse de replacement de camera (au plus il est petit, au plus elle va vite)
       
     if(InitialPos == true)
     {
          Camera = smgr->addCameraSceneNode(0,
                                            vector3df(InitialCamPosition.X,InitialCamPosition.Y + LastTargetPosition.Y,InitialCamPosition.Z),
                                            vector3df(LastTargetPosition.X,(LastTargetPosition.Y + DeltaCible),LastTargetPosition.Z),
                                            id );
     }
     else
     {
          EcartXObj = Distance * cos(TargetNode->getRotation().Y * PI/180.0f);
          EcartZObj = Distance * sin(TargetNode->getRotation().Y * PI/180.0f);

          Camera = smgr->addCameraSceneNode(0,
                                            vector3df(LastTargetPosition.X - EcartXObj,AltitudeCamera + LastTargetPosition.Y,LastTargetPosition.Z + EcartZObj),
                                            vector3df(LastTargetPosition.X,(LastTargetPosition.Y + DeltaCible),LastTargetPosition.Z),
                                            id );     
     }
     
     //collision
     ISceneNodeAnimator* CollisionCamera = smgr->createCollisionResponseAnimator(
     selectorCam, Camera, core::vector3df(10,10,10),
     vector3df(0,0,0),
     vector3df(0,0,0));
     Camera->addAnimator(CollisionCamera);
     CollisionCamera->drop();
         
     pTargetNode = TargetNode;
     pTargetNode->grab();
}

// destructeur
FollowingCamera::~FollowingCamera()
{
     pTargetNode->drop();
}

void FollowingCamera::Update()
{
     if(!Camera || !pTargetNode) return;
     
     vector3df CurrTargetPosition = pTargetNode->getPosition();
     
     if(Verrou == false)  // pour tester le premier deplacement de l'objet, avant de replacer la camera.
     {
           vector3df CurrTargetRotation = pTargetNode->getRotation();
           if((CurrTargetPosition.X != LastTargetPosition.X || CurrTargetPosition.Z != LastTargetPosition.Z || CurrTargetRotation.Y != LastTargetRotation.Y))
           {
                TestNode = false;
                Verrou = true;
           }
           LastTargetRotation = CurrTargetRotation;     
     } 
       
     if(TestNode == false)
     {           
          NewCamPosition = Camera->getPosition();

          EcartXObj = MaDistance * cos(pTargetNode->getRotation().Y * PI/180.0f);
          EcartZObj = MaDistance * sin(pTargetNode->getRotation().Y * PI/180.0f);
          FinalCamPosition = vector3df(CurrTargetPosition.X - EcartXObj,MonAltitudeCamera+CurrTargetPosition.Y,CurrTargetPosition.Z + EcartZObj);
         
          DistX = NewCamPosition.X - FinalCamPosition.X;
          DistY = NewCamPosition.Y - FinalCamPosition.Y;
          DistZ = NewCamPosition.Z - FinalCamPosition.Z;
          if( DistX > 0 ) {ix = -1;} else {ix = 1; DistX=(-1)*DistX;}
          if( DistY > 0 ) {iy = -1;} else {iy = 1; DistY=(-1)*DistY;}
          if( DistZ > 0 ) {iz = -1;} else {iz = 1; DistZ=(-1)*DistZ;}       
          VittX = DistX / CoeffVittCam;
          VittY = DistY / CoeffVittCam;
          VittZ = DistZ / CoeffVittCam;
          Camera->setPosition(vector3df(NewCamPosition.X +(ix*VittX),NewCamPosition.Y +(iy*VittY),NewCamPosition.Z +(iz*VittZ)));

          DistX = Vecteur.X - CurrTargetPosition.X;
          DistY = Vecteur.Y - (CurrTargetPosition.Y + MonDeltaCible);
          DistZ = Vecteur.Z - CurrTargetPosition.Z;
          if( DistX > 0 ) {ix = -1;} else {ix = 1; DistX=(-1)*DistX;}
          if( DistY > 0 ) {iy = -1;} else {iy = 1; DistY=(-1)*DistY;}
          if( DistZ > 0 ) {iz = -1;} else {iz = 1; DistZ=(-1)*DistZ;}       
          VittX = DistX / CoeffVittCam;
          VittY = DistY / CoeffVittCam;
          VittZ = DistZ / CoeffVittCam;
         
          Vecteur = vector3df(Vecteur.X+(ix*VittX),Vecteur.Y+(iy*VittY),Vecteur.Z+(iz*VittZ));
          Camera->setTarget(Vecteur);   
     }
     
     LastTargetPosition = CurrTargetPosition;
}
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

]#include<irrlicht.h>
#include<iostream>

#include"FollowingCamera.hpp"
 
using namespace irr;           
using namespace core;                               
using namespace scene;                                                           
using namespace video;                                                 
using namespace gui;                                         
using namespace io;                                         
         
#pragma comment(lib, "Irrlicht.lib")     

ISceneNode* player = 0;     
IrrlichtDevice* device = 0;   
   
//==============================================================================

class MonEcouteur : public IEventReceiver
{
public:   
   virtual bool OnEvent(SEvent event)   
   {     
      if (event.KeyInput.Key == KEY_KEY_A && event.KeyInput.PressedDown)
      { 
           player->setRotation( vector3df(0, player->getRotation().Y - 5.0f, 0) );
           return true;   
      }               
 
      if (event.KeyInput.Key == KEY_KEY_E && event.KeyInput.PressedDown)
      {
           player->setRotation( vector3df(0, player->getRotation().Y + 5.0f, 0) ); 
           return true;   
      } 

      if (event.KeyInput.Key == KEY_KEY_Z && event.KeyInput.PressedDown)
      {                       
           vector3df facing( cos( player->getRotation().Y * PI/180.0f ), 0, -sin( player->getRotation().Y * PI/180.0f ) );
           facing.normalize();
           vector3df newPos = player->getPosition() + (facing*5.0f); 
           player->setPosition( newPos );
           return true;
      }
     
      if (event.KeyInput.Key == KEY_KEY_S && event.KeyInput.PressedDown)       
      {
           vector3df facing( cos( player->getRotation().Y * PI/180.0f ), 0, -sin( player->getRotation().Y * PI/180.0f ) );
           facing.normalize();
           vector3df newPos = player->getPosition() - (facing*5.0f)  ;
           player->setPosition( newPos );
           return true;
      }     
      return false;
   }

};

//==============================================================================

int main()
{
    MonEcouteur receiver;
    IrrlichtDevice *device =
        createDevice( video::EDT_OPENGL, dimension2d<s32>(640, 480), 16,
            false, false, false, &receiver);
              
    device->setWindowCaption(L"Following Camera"); 
   
    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* guienv = device->getGUIEnvironment();
    
//=================================== objet ====================================

    device->getFileSystem()->addZipFileArchive("media/terrain/map-20kdm2.pk3");
   
    IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp");
    ISceneNode* q3node = 0;
   
    if (q3levelmesh)
        q3node = smgr->addOctTreeSceneNode(q3levelmesh->getMesh(0));

    ITriangleSelector* selector = 0;
   
    if (q3node)
    {       
        q3node->setPosition(vector3df(-1370,-130,-1400));
        selector = smgr->createOctTreeTriangleSelector(q3levelmesh->getMesh(0), q3node, 128);
        q3node->setTriangleSelector(selector);
        selector->drop();       
    }   

    player = smgr->addAnimatedMeshSceneNode(smgr->               
    getMesh("media/objet/faerie.md2"));     
    player->setRotation(irr::core::vector3df(0,0,0) );
    player->setMaterialTexture(0, driver->getTexture("media/texture/faerie5.bmp"));
    player->setMaterialFlag(video::EMF_LIGHTING , false);
    player->setPosition(vector3df(76,-25,-61));   
    player->setScale(core::vector3df(1.5,1.5,1.5));
       
    ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
        selector, player, vector3df(15,40,20),
        vector3df(0,-3,0),     
        vector3df(0,0,0)); 
    player->addAnimator(anim);     
    anim->drop();           
      
//==================================Camera======================================
                                         
    FollowingCamera* MaCamera = new FollowingCamera(player, smgr,
                                                  true,           // Pour utiliser une position initiale.
                                                  selector,       // Pour les collisions.
                                                  100,            // Distance.
                                                  50,             // Hauteur.
                                                  30,             // Delta cible.
                                                  vector3df(-50,200,-120));   // Position initiale.                   
    smgr->setActiveCamera( MaCamera->getCam() );         
     
//==============================================================================
       
    while(device->run())         
    {   
         
        driver->beginScene(true, true, SColor(255,100,101,140));
       
        smgr->drawAll(); 
        guienv->drawAll();
        if(MaCamera) {MaCamera->Update();}       
       
        driver->endScene();
            
    }           
    if(MaCamera) {delete MaCamera;}
    device->drop();

    return 0;
}

Hors ligne


#1 

20-10-2007 22:35:03

izguit
Administrateur
Lieu: 127.0.0.1
Date d'inscription: 14-09-2006
Messages: 306
Site web

merci beaucoup de ta contribution (c'est un peu rare en ce moment en plus smile)
Je déplace dans la section routines par contre smile


Athlon 64 3000+ // 1Go RAM // Geforce 6600GT 128Mo
Turion 64 X2 // 1Go RAM // ATI X1250

Hors ligne


#2 

21-10-2007 11:21:04

Copland
Modérateur
Lieu: ZarbiLand
Date d'inscription: 22-09-2006
Messages: 657
Site web

Oué merci pour la contrib c'est sympa wink.
Je viens de m'appercevoir qu'il y a également des contributions qui datent pfiou d'un bail et qui n'ont même pas été remercié, comme celle de BmarleyFR :s.


Config : I5 2400, ATI HD6870 1Go DDR5, 4Go DDR3.
Single Boot : Windows Seven.

Hors ligne


#3 

21-10-2007 11:36:31

gp2mv3
Abonné
Date d'inscription: 27-06-2007
Messages: 103
Site web

C'est cool, je voulais modifier le systeme de mon jeu à la 3eme personne.

Merci beaucoup.


Mon projet sous Irrlicht : RoM : Rebuilding on Mars
N'hésitez pas à y faire un tour wink

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
1427 sujets
11117 messages
Dernier membre inscrit: Bidule
23 invités en ligne
Aucun membre connecté
RSS Feed