![]() |
| Le forum de référence en programmation et développement. Articles, cours et tutoriels du débutant au chef de projet et DBA confirmé. | |||||||
|
|||||||
| OpenGL Forum d'entraide sur le développement en OpenGL. Avant de poster -> FAQ OpenGL |
![]() |
|
|
Outils de la discussion |
|
|
#1 (permalink) |
|
Membre éclairé
![]() Date d'inscription: janvier 2007
Messages: 323
|
Bonjour,
Je me suis inspiré d'un exemple du Net pour écrire ma propre classe qui gère la caméra dans une scène 3D sur OpenGL. La caméra avance, récule, se déplace à gauche, à droite parfaitement. Mais, elle déconne lorsque j'assaye de faire de rotations que ce soit verticalement ou horisontalement. Voilà le code java de ma classe : Code :
import javax.media.opengl.glu.GLU; //petiteange67@hotmail.fr //yannas67-cindy67@hotmail.fr public class Camera { float cosX,sinX,cosY,sinY; float step; float Deg2Radian=0.01745329f; float mCamera_PosX; // Position de la camera suivant X float mCamera_PosY; // Position de la camera suivant Y float mCamera_PosZ; // Position de la camera suivant Z float mCamera_AngleX=0.0f; float mCamera_AngleY=0.0f; float mCamera_TargX; // Cible de la camera suivant X float mCamera_TargY; // Cible de la camera suivant Y float mCamera_TargZ; // Cible de la camera suivant Z float mCamera_UpX; // Vecteur de roulis suivant X float mCamera_UpY; // Vecteur de roulis suivant Y float mCamera_UpZ; // Vecteur de roulis suivant Z float mCamera_StrafeX=1.0f; // Cible de la camera suivant X float mCamera_StrafeY=0.0f; // Cible de la camera suivant Y float mCamera_StrafeZ=0.0f; // Cible de la camera suivant Z int mCamera_Jump=0; float mCamera_YbeforeJump=0.0f; public Camera() {} //--------------------------------------------------------------------------------------------------------------------- /** * * @return mCamera_PosX */ public float getCameraPosX() { return mCamera_PosX; } //--------------------------------------------------------------------------------------------------------------------- /** * * @return mCamera_PosY */ public float getCameraPosY() { return mCamera_PosY; } //--------------------------------------------------------------------------------------------------------------------- /** * * @return mCamera_PosZ */ public float getCameraPosZ() { return mCamera_PosZ; } //--------------------------------------------------------------------------------------------------------------------- /** * * @return mCamera_TargX */ public float getCameraTargX() { return mCamera_TargX; } //--------------------------------------------------------------------------------------------------------------------- /** * * @return mCamera_TargY */ public float getCameraTargY() { return mCamera_TargY; } //--------------------------------------------------------------------------------------------------------------------- /** * * @return mCamera_TargZ */ public float getCameraTargZ() { return mCamera_TargZ; } //--------------------------------------------------------------------------------------------------------------------- /** * * @return mCamera_StrafeX */ public float getCameraUpX() { return mCamera_StrafeX; } //--------------------------------------------------------------------------------------------------------------------- /** * * @return mCamera_StrafeY */ public float getCameraUpY() { return mCamera_StrafeY; } //--------------------------------------------------------------------------------------------------------------------- /** * * @return mCamera_StrafeZ */ public float getCameraUpZ() { return mCamera_StrafeZ; } //--------------------------------------------------------------------------------------------------------------------- public void setCameraPosX(float PosX) { mCamera_PosX=PosX; } //--------------------------------------------------------------------------------------------------------------------- public void setCameraPosY(float PosY) { mCamera_PosY=PosY; } //--------------------------------------------------------------------------------------------------------------------- public void setCameraPosZ(float PosZ) { mCamera_PosZ=PosZ; } //--------------------------------------------------------------------------------------------------------------------- public void setCameraTargX(float TargX) { mCamera_TargX=TargX; } //--------------------------------------------------------------------------------------------------------------------- public void setCameraTargY(float TargY) { mCamera_TargY=TargY; } //--------------------------------------------------------------------------------------------------------------------- public void setCameraTargZ(float TargZ) { mCamera_TargZ=TargZ; } //--------------------------------------------------------------------------------------------------------------------- public void setCameraUpX(float UpX) { mCamera_StrafeX=UpX; } //--------------------------------------------------------------------------------------------------------------------- public void setCameraUpY(float UpY) { mCamera_StrafeY=UpY; } //--------------------------------------------------------------------------------------------------------------------- public void setCameraUpZ(float UpZ) { mCamera_StrafeZ=UpZ; } //--------------------------------------------------------------------------------------------------------------------- /////////////////////////////////////////////// /// Fixe une position à la camera /// /////////////////////////////////////////////// void CameraSetPosition( float newX, float newY, float newZ, float newTargX, float newTargY, float newTargZ, float newUpX, float newUpY, float newUpZ) { this.setCameraPosX(newX); // Position de la camera suivant X this.setCameraPosY(newY); // Position de la camera suivant Y this.setCameraPosY(newZ); // Position de la camera suivant Z this.setCameraTargX(newTargX); // Cible de la camera suivant X this.setCameraTargY(newTargY); // Cible de la camera suivant Y this.setCameraTargZ(newTargZ); // Cible de la camera suivant Z this.setCameraUpX(newUpX); // Vecteur de roulis suivant X this.setCameraUpY(newUpY); // Vecteur de roulis suivant Y this.setCameraUpZ(newUpZ); // Vecteur de roulis suivant Z } /////////////////////////////////////////////// /// Avance la camera /// /////////////////////////////////////////////// void CameraMoveFront(float speed) { step = (mCamera_TargX - mCamera_PosX)*speed; mCamera_PosX += step; mCamera_TargX += step; step = (mCamera_TargZ - mCamera_PosZ)*speed; mCamera_PosZ += step; mCamera_TargZ+= step; } /////////////////////////////////////////////// /// Recule la camera /// /////////////////////////////////////////////// void CameraMoveBack(float speed) { step = (mCamera_TargX - mCamera_PosX)*speed; mCamera_PosX -= step; mCamera_TargX -= step; step = (mCamera_TargZ - mCamera_PosZ)*speed; mCamera_PosZ -= step; mCamera_TargZ -= step; } /////////////////////////////////////////////// /// Deplacer la camera à droite /// /////////////////////////////////////////////// void CameraMoveRight(float speed) { step =(mCamera_TargZ - mCamera_PosZ)*speed; mCamera_PosX -= step; mCamera_TargX -= step; step = (mCamera_TargX - mCamera_PosX)*speed; mCamera_PosZ -= step; mCamera_TargZ -= step; } /////////////////////////////////////////////// /// Deplacer la camera à gauche /// /////////////////////////////////////////////// void CameraMoveLeft(float speed) { step =(mCamera_TargZ - mCamera_PosZ)*speed; mCamera_PosX += step; mCamera_TargX += step; step = (mCamera_TargX - mCamera_PosX)*speed; mCamera_PosZ += step; mCamera_TargZ += step; } /////////////////////////////////////////////// /// Strafe la camera à droite /// /////////////////////////////////////////////// void CameraStrafeRight(float speed) { mCamera_PosX += (mCamera_StrafeX*speed); mCamera_PosY += (mCamera_StrafeY*speed); mCamera_PosZ += (mCamera_StrafeZ*speed); mCamera_TargX += (mCamera_StrafeX*speed); mCamera_TargY += (mCamera_StrafeY*speed); mCamera_TargZ += (mCamera_StrafeZ*speed); } /////////////////////////////////////////////// /// Strafe la camera à gauche /// /////////////////////////////////////////////// void CameraStrafeLeft(float speed) { mCamera_PosX -= (mCamera_StrafeX*speed); mCamera_PosY -= (mCamera_StrafeY*speed); mCamera_PosZ -= (mCamera_StrafeZ*speed); mCamera_TargX -= (mCamera_StrafeX*speed); mCamera_TargY -= (mCamera_StrafeY*speed); mCamera_TargZ -= (mCamera_StrafeZ*speed); } /////////////////////////////////////////////// /// Rotation de la camera en haut /// /////////////////////////////////////////////// void CameraRotateUp(float speed) { mCamera_AngleX = mCamera_AngleX +speed; if(mCamera_AngleX>360.0) mCamera_AngleX -= 360.0; cosX = (float) Math.cos(mCamera_AngleX*Deg2Radian); sinX = (float) Math.sin(mCamera_AngleX*Deg2Radian); cosY = (float) Math.cos(mCamera_AngleY*Deg2Radian); sinY = (float) Math.sin(mCamera_AngleY*Deg2Radian); mCamera_TargX = (-cosX*sinY) + mCamera_PosX; mCamera_TargY = sinX + mCamera_PosY; mCamera_TargZ = (-cosX*cosY) + mCamera_PosZ; mCamera_StrafeX = cosY; mCamera_StrafeY = 0.0f; mCamera_StrafeZ = -sinY; } /////////////////////////////////////////////// /// Rotation de la camera en bas /// /////////////////////////////////////////////// void CameraRotateDown(float speed) { mCamera_AngleX = mCamera_AngleX -speed; if(mCamera_AngleX<360.0) mCamera_AngleX += 360.0; cosX = (float) Math.cos(mCamera_AngleX*Deg2Radian); sinX = (float) Math.sin(mCamera_AngleX*Deg2Radian); cosY = (float) Math.cos(mCamera_AngleY*Deg2Radian); sinY = (float) Math.sin(mCamera_AngleY*Deg2Radian); mCamera_TargX = (-cosX*sinY)+ mCamera_PosX; mCamera_TargY = sinX+ mCamera_PosY; mCamera_TargZ = (-cosX*cosY) + mCamera_PosZ; mCamera_StrafeX = cosY; mCamera_StrafeY = 0.0f; mCamera_StrafeZ = -sinY; } /////////////////////////////////////////////// /// Rotation de la camera à droite /// /////////////////////////////////////////////// void CameraRotateRight(float speed) { mCamera_AngleY = mCamera_AngleY -speed; if(mCamera_AngleY<360.0) mCamera_AngleY += 360.0; cosX = (float) Math.cos(mCamera_AngleX*Deg2Radian); sinX = (float) Math.sin(mCamera_AngleX*Deg2Radian); cosY = (float) Math.cos(mCamera_AngleY*Deg2Radian); sinY = (float) Math.sin(mCamera_AngleY*Deg2Radian); mCamera_TargX = (-cosX*sinY)+ mCamera_PosX; mCamera_TargY = sinX + mCamera_PosY; mCamera_TargZ = (-cosX*cosY) + mCamera_PosZ; mCamera_StrafeX = cosY; mCamera_StrafeY = 0.0f; mCamera_StrafeZ = -sinY; } /////////////////////////////////////////////// /// Rotation de la camera à gauche /// /////////////////////////////////////////////// void CameraRotateLeft(float speed) { mCamera_AngleY = mCamera_AngleY +speed; if(mCamera_AngleY>360.0) mCamera_AngleY -= 360.0; cosX = (float) Math.cos(mCamera_AngleX*Deg2Radian); sinX = (float) Math.sin(mCamera_AngleX*Deg2Radian); cosY = (float) Math.cos(mCamera_AngleY*Deg2Radian); sinY = (float) Math.sin(mCamera_AngleY*Deg2Radian); mCamera_TargX = (-cosX*sinY)+ mCamera_PosX; mCamera_TargY = sinX+ mCamera_PosY; mCamera_TargZ = (-cosX*cosY) + mCamera_PosZ; mCamera_StrafeX = cosY; mCamera_StrafeY = 0.0f; mCamera_StrafeZ = -sinY; } /////////////////////////////////////////////// /// Saut de la camera /// /////////////////////////////////////////////// void CameraJump() { if (mCamera_Jump==0) { mCamera_Jump=1; mCamera_YbeforeJump=mCamera_PosY; } } /////////////////////////////////////////////// /// Saut de la camera /// /////////////////////////////////////////////// void CameraUpDateJump() { float JumpHeight=0.0f; float gravite=0.1f; float temp; if (mCamera_Jump==1 && JumpHeight<3.0) { gravite+=0.1; JumpHeight+=0.2/gravite; mCamera_PosY+=0.2/gravite; mCamera_TargY+=0.2/gravite; } else if( mCamera_Jump==1 && JumpHeight>=3.0) { mCamera_Jump=2; } else if( mCamera_Jump==2 && JumpHeight>0.0) { gravite-=0.1; JumpHeight-=0.2/gravite; if( mCamera_PosY-(0.2/gravite)>=mCamera_YbeforeJump) { mCamera_PosY-=0.2/gravite; mCamera_TargY-=0.2/gravite; } } else if(mCamera_Jump==2 && JumpHeight<=0.0) { gravite=0.1f; JumpHeight=0.0f; temp=mCamera_YbeforeJump - mCamera_PosY; if(temp<0.0) temp=(-temp); mCamera_TargY= mCamera_TargY - temp; mCamera_PosY=mCamera_YbeforeJump; mCamera_Jump=0; } } } Ou, est ce que quelqu'un a une classe mieux que celle là? merci d'avance. |
|
|
|
|
|
#2 (permalink) | |
|
Expert Confirmé
![]() Date d'inscription: avril 2004
Localisation: TLS-Blagnac-Villecomtal
Messages: 1 666
|
Code :
mCamera_TargX = (-cosX*sinY) + mCamera_PosX; mCamera_TargY = sinX + mCamera_PosY; mCamera_TargZ = (-cosX*cosY) + mCamera_PosZ; mCamera_StrafeX = cosY; mCamera_StrafeY = 0.0f; mCamera_StrafeZ = -sinY; Je ne sais pas à quoi correspondent tes angles, donc je te laisse chercher les bons termes. Citation:
Au début, je magouillais avec des angles comme tu le fais, mais maintenant j'utilise les quaternions et c'est... magique! J'ai un tuto en préparation, mais normalement tu as toute la doc dans la FAQ matrices & quaternions pour ça si tu veux te lancer là-dedans.
__________________
"Errare humanum est, sed perseverare diabolicum" Si vous avez un terrain constructible dans l'est du Gers à vendre pas trop cher, contactez-moi par MP. |
|
|
|
|
|
|
#4 (permalink) |
|
Membre éclairé
![]() Date d'inscription: janvier 2007
Messages: 323
|
Aprés une petite recherche sur Internet, j'ai essayé d'appliquer les principes de rotation autour des axes X, Y et Z. Pour ce faire, je devrai utiliser les matrices de rotations pour ces trois axes qui sont:
1) Matrice de rotation autour de laxe X: Code :
|1 0 0 0| |0 cos(A) -sin(A) 0| |0 sin(A) cos(A) 0| |0 0 0 1| .... 3) Matrice de rotation autour de laxe Z: ..... Aprés, comme le gluLookAt uilise 9 paramètres qui sont: 1) posx, posy, posz : la position de la caméra. 2) tragx, tragz, targz : la position où la caméra regarde. 3) upx, upy, upz : l'axe autour duquel la caméra doit tourner. j'ai essayé de faire la rotation des (posx, posy, posz ) et des (tragx, tragz, targz ) autour de X, Y ou Z. Par exemple autour de X, je multiplis la matrice de rotation autour le l'axe X par respectivement (posx, posy, posz ) et(tragx, tragz, targz ), alors j'obtient les valeurs suivantes : Code :
mCamera_PosX=mCamera_PosX; // ne change pas car c'est autour de l'axe X mCamera_PosY= mCamera_PosY*CosAngleX - mCamera_PosZ*SinAngleX; mCamera_PosZ= mCamera_PosY*SinAngleX + mCamera_PosZ*CosAngleX; mCamera_TargX= mCamera_TargX; // ne change pas car c'est autour de l'axe X mCamera_TargY = mCamera_TargY*CosAngleX - mCamera_TargZ*SinAngleX;; mCamera_TargZ = mCamera_TargY*SinAngleX + mCamera_TargZ*CosAngleX; mCamera_UpX=1; mCamera_UpY=0; mCamera_UpZ=0; Pourriez vous m'aider à résoudre mon problème? Dernière modification par choko83 ; 17/11/2008 à 18h31 |
|
|
|
|
|
#5 (permalink) | |
|
Expert Confirmé
![]() Date d'inscription: avril 2004
Localisation: TLS-Blagnac-Villecomtal
Messages: 1 666
|
Citation:
Au vu des formules, ça n'a rien d'aléatoire, ça doit juste sortir de l'écran. Teste sans modifier le target pour commencer, et en le plaçant au milieu de tes objets à afficher. Toutefois, recalculer les coordonnées pour refaire un gluLookAt, ce n'est pas hyper optimisé à mon avis. Tu peux récupérer la matrice de transformation de ta caméra, et l'appliquer à la matrice du modèle. Je suis en train de préparer un tuto justement sur ce sujet, mais il ne sera pas prêt avant quelques temps (plus la relecture et la correction). En gros, dans mon display(), je fais un: Code :
glu.gluLookAt(10, 0, 0, 0, 0, 0, 0, 0, 1); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT); gl.glMatrixMode(GL.GL_MODELVIEW_MATRIX); gl.glLoadMatrixf(this.camera.getCameraMatrix()); Code :
public FloatBuffer getCameraMatrix() { Matrix4 matRot=this.quatRot.getMatrix(); // matrice de rotation (quaternion) Matrix4 matScale=Matrix4.getScaleMatrix(this.scale); // matrice d'échelle Matrix4 matTrans=Matrix4.getTranslationMatrix(this.transVect); // matrice de translation return matTrans.mult(matScale).mult(matRot).toFloatBuffer(); } Tu fais un gluLookAt au départ, avec tes coordonnées de base, pour localiser la caméra et la cible, et ensuite tu appliques les transformations à ton monde 3D. Beaucoup plus simple que de gérer la position de la caméra quand ça bouge Attention à l'ordre de multiplication des matrices par contre, il faut y réfléchir en fonction des transformations que tu souhaites obtenir. Et puis ce n'est pas encore optimisé, et il doit y avoir d'autres méthodes pour arriver à ce résultat... mais le principe doit y être!
__________________
"Errare humanum est, sed perseverare diabolicum" Si vous avez un terrain constructible dans l'est du Gers à vendre pas trop cher, contactez-moi par MP. |
|
|
|
|
|
|
#7 (permalink) |
|
Membre éclairé
![]() Date d'inscription: janvier 2007
Messages: 323
|
J'ai compris pourquoi ça marche pas mais je ne sais pas la solution.
En fait, moi je travaille avec des coordonnées sur 5 chiffres (exemple: x=72390). En calculant les matrices de rotation, la position de la caméra devient trés loin de la cible de telle façon que l'objet devient invisibe. |
|
|
|
|
|
#8 (permalink) | |
|
Expert Confirmé
![]() Date d'inscription: avril 2004
Localisation: TLS-Blagnac-Villecomtal
Messages: 1 666
|
Alors tu n'as pas "compris", tu as "trouvé"...
Citation:
De plus, si tu fixes ta target sur l'objet, je vois mal comment tu peux le perdre de vue... règle les znear et zfar du gluLookAt assez large pour ne pas être embêté (mais avec des nombres à 5 chiffres...)
__________________
"Errare humanum est, sed perseverare diabolicum" Si vous avez un terrain constructible dans l'est du Gers à vendre pas trop cher, contactez-moi par MP. |
|
|
|
|
|
![]() |
![]() |
||
classe caméra qui déconne
|
||
| Outils de la discussion | |
|
|