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.
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; } |