serik Posté(e) le 18 février 2007 Partager Posté(e) le 18 février 2007 Salut à tous, je cherche à faire ma class camera, mais si pour la translation elle marche bien, il n'en va pas de même pour la rotation. Donc je cherche soit une class toute faite pour prendre exemple, soit si quelqu'un a le courage de se pencher sur mon code... Je ne souhaite pas utiliser de quaternion, vu que je ne les ai jamais étudié. Il est important aussi pour moi d'avoir une matrice inversée prête à l'emploi (la matrice back dans mon code). Enfin, c'est destiné à du calcul assez lourd, donc la classe devra être assez performante. Voici ma class: #include "Camera.hpp" #include <iostream> #include "Math3D/Vector3D.hpp" using namespace std; Camera::Camera(){ back = Matrix4(); back.loadIdentity(); rx=ry=rz=tx=ty=tz=0; } void Camera::rotatef(float angle, float x, float y, float z){ Vector3D v(x,y,z); Vector3D vt = back*v; back.rotatef(-angle,x,y,z); rx+=vt.getX()*angle; ry+=vt.getY()*angle; rz+=vt.getZ()*angle; } void Camera::translatef(float x, float y, float z){ Vector3D v(-x,-y,-z); Vector3D vt = back*v; tx+=vt.getX(); ty+=vt.getY(); tz+=vt.getZ(); back.translatef(x,y,z); } void Camera::setPerspective(){ glLoadIdentity(); glRotatef(rx,1,0,0); glRotatef(ry,0,1,0); glRotatef(rz,0,0,1); glTranslatef(tx,ty,tz); } J'ai aussi une autre question : Soit deux rotations successives : glRotatef(20,1,0,0); glRotatef(10,0,1,0); -> Quel serait l'équivalent en un seul appel? Merci à tous. Je rajoute le header au cas où : #ifndef CAMERA_H #define CAMERA_H 1 #include "Math3D/Matrix4.hpp" #include "GL/gl.h" class Camera{ private: Matrix4 back; float tx,ty,tz; float rx,ry,rz; protected: public: Camera(); void rotatef(float angle, float x, float y, float z); void translatef(float x, float y, float z); void setPerspective(); }; #endif Lien vers le commentaire Partager sur d’autres sites More sharing options...
16ar Posté(e) le 22 février 2007 Partager Posté(e) le 22 février 2007 Je sais que tu ne vas pas m'aimer, mais pour des rotations fluide et performantes, les quaternions ca reste vraiment le top. Ca se voit direct un jeu qui utilise des quaternions pour des rotations ou pas Y'a un bon tutorial sur gamasutra.com, je te le recherche : http://www.gamasutra.com/features/19980703...ternions_01.htm (il faut être enregistré chez eux, mais bon, c gratuit et comme c'est une bonne ressource pour tout ce qui est jeu 3D temps réel, je ne pense pas que tu regretteras ) J'ai aussi une autre question : Soit deux rotations successives : glRotatef(20,1,0,0); glRotatef(10,0,1,0); -> Quel serait l'équivalent en un seul appel? Il faut que tu fasses les calculs préliminaires pour determiner la valeur du vecteur suivant lequel tu vas tourner et aussi savoir de combien tu vas tourner. Ca demande des maths en effet. La j'ai pas la tete a ca ^^. Une solution moins propre pour le rendu final, ca serait de passer par les matrices. C'est un peu complexe a comprendre, mais avec les matrices, on fait ce qu'on veut. Bon ca, c'est ce que je sais ... Si ca se trouve y'a une fonction openGL ou GLUT qui le fait de base. Lien vers le commentaire Partager sur d’autres sites More sharing options...
lorinc Posté(e) le 22 février 2007 Partager Posté(e) le 22 février 2007 regarde un peu là, sinon : http://fr.wikipedia.org/wiki/Rotation_vectorielle La composition de deux rotation est une isometrie dont la matrice est déterminée à partir de M1M2 - t(M1M2). Mais effectivement, wiki semble plutôt dire que les quaternions caybon. Sinon, sur cette page, tu as aussi la formule d'Olinde Rodrigues donnant l'explicitation de la matrice de rotation à partir de son axe et son angle. Tu peux toujours faire une routine qui construit cette matrice (et tu peux construire et stocker la matrice inverse adns une pile, ce qui sera moins coûteux que d'inverser). Lien vers le commentaire Partager sur d’autres sites More sharing options...
serik Posté(e) le 25 février 2007 Auteur Partager Posté(e) le 25 février 2007 Merci pour vos réponses. J'ai lu l'article de gamasutra, malheureusement il manque beaucoup trop de choses pour arriver à ce que je veux faire. J'ai aussi regardé la Class Camera de NeheGL, mais elle a le même défaut que beaucoup d'autres : La caméra est définie dans l'équivalent d'un système de corrdonée polaires, lorsque l'on regarde tout droit, la rotation suivant X par rapport à l'écran se passe bien, mais quand on lève la tête, la rotation se fait toujours par rapport à un plan parallèle à XOZ, et lorsque l'on est au pôle, on tourne sur sois même! Je cherche, à partir d'une position de caméra quelconque (j'accepte les quaternions cette fois-ci), à ajouter une rotation RELATIVE suivant l'axe X ou Y de l'écran. Comment ça se traduitait sur un quaternion? Merci encore une fois. Lien vers le commentaire Partager sur d’autres sites More sharing options...
serik Posté(e) le 27 février 2007 Auteur Partager Posté(e) le 27 février 2007 Merci pour vos réponses. J'ai lu l'article de gamasutra, malheureusement il manque beaucoup trop de choses pour arriver à ce que je veux faire. J'ai aussi regardé la Class Camera de NeheGL, mais elle a le même défaut que beaucoup d'autres : La caméra est définie dans l'équivalent d'un système de corrdonée polaires, lorsque l'on regarde tout droit, la rotation suivant X par rapport à l'écran se passe bien, mais quand on lève la tête, la rotation se fait toujours par rapport à un plan parallèle à XOZ, et lorsque l'on est au pôle, on tourne sur sois même! Je cherche, à partir d'une position de caméra quelconque (j'accepte les quaternions cette fois-ci), à ajouter une rotation RELATIVE suivant l'axe X ou Y de l'écran. Comment ça se traduitait sur un quaternion? Merci encore une fois. Bon, après des heures de recherche, j'ai peut-être la solution, voici ma class Camera : #ifndef QCAMERA_H #define QCAMERA_H 1 #include "Math3D/Matrix4.hpp" #include "GL/gl.h" #include "Math3D/Vector3D.hpp" #include "Math3D/Quaternion.hpp" class QCamera{ private: Quaternion rot; float tx, ty, tz; protected: public: QCamera(); void rotatef(float angle, float x, float y, float z); void translatef(float x, float y, float z); void setPerspective(); }; #endif ----------------------------------------------------------------------------------------------------- #include "QCamera.hpp" #include <iostream> using namespace std; QCamera::QCamera(){ tx = ty = tz = 0.0f; } void QCamera::rotatef(float angle, float x, float y, float z){ Quaternion q; q.fromAxisAngle(x, y, z, angle); q*=this->rot; this->rot = q; } void QCamera::translatef(float x, float y, float z){ Vector3D v(x,y,z); Vector3D vt; this->rot.reversetransform(v,vt); tx-=vt.getX(); ty-=vt.getY(); tz-=vt.getZ(); } void QCamera::setPerspective(){ float matrix[16]; this->rot.toMatrix(matrix); glLoadIdentity(); glMultMatrixf(matrix); glTranslatef(tx,ty,tz); } A priori, ça se passe bien. Reste une question que je me pose : j'ai beaucoup entendu parlé du GimbalLock, qui intervient lorsque l'on ne fait pas appel à glLoadIdentity() à chaque frame. Certes, j'ai un appel dans setPerspective(), mais dans le fond, j'ai un Quaternion de départ que je ne cesse de multiplier. Est-il possible que j'arrive un jour sur un GimbalLock? Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.