Salut,
j'ai implementé ma propore classe camera utilisant opengl, mais je costate que le mouvement est un peu ... bizarre .
je sens que je ne suis pas tout a fait à l'aise quand je me deplace dans la scene, mais je ne sais pas pourquoi.
Voici camera.h:
#ifndef CAMERA_H_INCLUDED
#define CAMERA_H_INCLUDED
#include "Vector3D.h"
#include <math.h>
#include <SFML/Window.hpp>
#include <GL/gl.h>
#include <GL/glu.h>
class Camera {
public:
Camera(const Vector3D& = Vector3D(0, 0, -100));
void Translate(const double, const double);
void OnEvent(const sf::Input& , const double dt);
void Look();
protected:
void VectorFromAngles();
Vector3D m_position;//position in the world
Vector3D m_target;
//directions
Vector3D m_forward;
Vector3D m_left;
Vector3D m_up;
//the traget of the camera
Vector3D m_traget;
//rotation
double m_theta;
double m_phi;
double m_speed;
double m_pi;
double m_oldX;
double m_oldY;
};
#endif // CAMERA_H_INCLUDED
Tu peux préciser un peu ce que tu appelles bizarre?
La seule chose d'incorrect que je vois, c'est que tu multiplies le déplacement de la souris par dt * m_speed:
La vitesse de rotation est indépendante de la vitesse de déplacement. Je présume que tu t'en es rendu compte et c'est pour cela que tu as ajouté cette constante 0.1. Les deux vitesses sont suffisamment indépendante pour justifier deux variables (même les unités sont totalement différentes, la première est en degré/pixel et la seconde en unité/seconde).
Il n'y a pas besoin de multiplier par dt, le nombre de pixels dont s'est déplacée la souris depuis la dernière frame suffit à rendre la rotation indépendante du framerate. En effet, plus tu auras de frames par seconde et moins la souris aura le temps de se déplacer entre chaque frame, au final ça s'équilibrera. En multipliant par dt, tu prends en compte deux fois le framerate et du coup, tu dois sans doute avoir des variations de vitesses de rotation quand celui ci varie.
Et par logique, j'aurais plutôt calculer les rotations avant les déplacements, le second dépendant du premier mais pas l'inverse, mais je ne pense pas que la différence soit perceptible.
Non, ça ne va pas. Tu n'as pas compris a quoi sert le vecteur UP.
Imagine que tu es la caméra.
Le vecteur UP part du haut de ta tete, et va vers le ciel.
Si tu décides de lever le nez, le vecteur UP part en arriere.
Si tu hoches la tete, le vecteur s'incline a gauche ou a droite.
Le vecteur up doit toujours etre orthogonal au vecteur de vue.
et on le calcule comment?sinon je crois que c'est toi qui n'a pas compris, moi j'utilise le veteur up SEULEMENT pour calculer le vecteur left, et pas pour autre chose, donc qu'il soit perpendicualire a forward ou au monde entier, ça ne change rien au final!
Parce que Kyle fait varier le point position et le point target sur le meme plan Z. Dans ce cas particulier la, up n'a pas besoin de bouger (c'est comme si tu te déplaçais dans un monde sans jamais lever la tete).
Toi, ce n'est pas le cas (puisque tu as un angle Psi) donc il faut que tu modifies le vecteur up.
Je te laisse voir mon petit programme "Klostro Laby" (cf ma signature), qui te propose 6 degrés de liberté, pour voir que je ne te dis pas de conneries.
ok, merci pour toutes tes reponses Fvirtman!
MAIS CE QUE JE NE COMPREND PAS? C4EST QUE COMMENT KAYL POUVAIT IL S4EN SORTIR SANS CALUCULER LE UP? ALORS QUE SA DEMO MARCHE NICKEL!
gluLookAt projette le vecteur up sur le plan de la caméra, il n'y a donc pas besoin de le faire soi même. La seule chose à s'assurer, c'est que ton vecteur direction ne soit pas colinéaire à ton vecteur up, ce qui arrive quand theta vaut 90° ou -90° modulo 360.
Y'a pas nécessairement besoin que le vecteur UP soit orthogonal au vecteur de direction (EyeX-CenterX): gluLookAt le fait lui-même (http://www.opengl.org/documentation/sp [...] u/lookat.html). Ce qui est absolument nécessaire, c'est que le vecteur UP et le vecteur de direction soient linéairement indépendant, pour qu'il ne reste qu'un seul vecteur à trouver pour établir une base de l'espace a trois dimension dans lequel on travail. (En fait c'est un espace a 4 dimension, mais dans ce cas particulier, on travail sur un sous-espace, et glulookat complète la base par un quatrième vecteur: (0,0,0,1)... Avis aux amateurs d'algèbre linéaire!)
Repense un peu toutes les étapes de ton calcul. Tu as visiblement voulu découpé le problème em plusieurs parties, mais peut-etre un peu trop, ou pas de la bonne manière.
Prend un crayon, du papier, dessine un système d'axes, les vecteur qui decrivent ta camera, les angles, etc.
Ensuite reflechi à ce qui doit etre temporaire, et a ce qui ne doit pas l'etre.
L'etat de ta caméra est décrit par trois choses: une position <math>\(\vec P\)</math> et 2 angles (<math>\(\theta, \phi\)</math>). La souris modifie la valeur des deux angles. Le clavier modifie la position, mais c'est un peu plus compliqué:
si <math>\(\vec P(t_{0}) = \vec P_{0}\)</math>, on a: <math>\(\vec P(t_{0} + dt) = \vec P_0 + dt\cdot \vec d\cdot v\)</math>, ou <math>\(\vec d\)</math> est le vecteur unitaire qui pointe vers l'avant, et <math>\(v\)</math> la vitesse de deplacement. <math>\(\vec d\)</math> doit etre calculé en fonction de tes 2 angles <math>\(\theta \text{ et } \phi\)</math>. Formellement, il s'agit de passer d'un système de coordonnées sphérique en coordonnées cartésiennes. (cf wikipedia, pour de plus amples info)
je crois que c'est ce que j'ai fait dans la fonction VectorFromAngles(), non? je passe des angles alpha et phi au vecteur forward(vers l'avant) et puis au vecteur left!
Oui, peut-etre. Mais c'est pas une bonne idée d'un point de vue conceptuelle de faire une fonction qui "modifie juste" un attribut, pour l'utiliser ensuite. Pense plutot a une fonction qui retourne un "Vecteur3D"..
C'est la même chose pour le vecteur left.
A prioris, ces vecteur sont des objets "temporaire" du calcul de la position, donc c'est pas très malin de les mettre en attributs. Sauf si tu penses avoir a les réutiliser ailleurs.
EDIT: Et surtout, ton calcul pour trouver "m_Forward" est faux! Ou alors je vois pas a quoi correspondent les angles, et la verticale (habituellement z...) (cf. wikipedia)
ok, je vais faire ces modifs cette nuit, et je verrais ce que ça donnerais!entout cas je laisse ce topic non resolu pour mes eventuels futur-problemes.
merci à toi aussi Gravstein !
ok, je me rétractes, je ne pensais pas que glulookat recalculait un vecteur up en fonction de celui entré (avec 2 produits vectoriels donc), je pensais qu'il fallait l'entrer correctement sois meme.
Je pense qu'il est tout de meme important de savoir ce qu'il se passe, et qu'est ce que ce mystérieux vecteur up.
En fait, l'idée du gluLookAt, c'est de multiplier la matrice courante par une matrice de changement de base:
le vecteur de direction normalisé sera la nouvelle coordonnees Z, le Up' (donc le Up recalculé par gluLookAt) sera la coordonnée y, et le vecteur Left (resultat d'un produit vectoriel entre Up' et direction) sera la coordonnée x. Le tout est ensuite multiplié par une matrice de translation pour tenir compte de la position de la caméra.
C'est trivial, mais sans quelques notions d'algèbre linéaire, ça peu paraître obscure..
mnt je me trouve confronté a un autre probleme: j'essaye d'avoir un cube devant ma camera(qui va la suivre tout en restant devant), mais malheureureusemenet, les resultats sont un peu bizarres là encore :(. Voici le code responsable:
const Vector3D& pos = Cam.Position();
glRotated(Cam.phi(), 1, 0, 0);//rotation autour de l'axe des x
glRotated(Cam.theta(), 0, 0, 1);//rotation autour de Z
glTranslatef(pos.X , pos.Y + 2, pos.Z - 0.3);
cube(.5);//dessiner un cube
Moi j'essayerai d'inverser l'ordre des glRotated et du glTranslate.
Le but c'est bien de le tourner dans l'orientation de la caméra, einh?
Avec opengl, il faut réflechir au transformation dans l'ordre inverse: La dernière transformation que tu donnes est la première qui est appliquée à ton objet.
Donc la tu dois:
1 - Orienter ton cube
2 - Le placer en face de la camera..
Donc l'ordre est:
1 - glTranslate()
2 - glRotate(m_Phi, ...); glRotate(m_Theta, ...);
Et il ne faut pas juste décrémenter la coordonnée Z de la caméra, ca ca marche pas: il va juste placer le cube "sous" la position de la camera.
A mon avis, c'est pas la bonne solution.
Utilise plutot une première camera pour dessiner ton cube (genre une projection le long de Z, gluOrtho2D, par ex, ou simplement gluPerspective, mais sans la déplacer après) et ensuite tu utilise une autre camera pour le reste du dessin. (C'est exactement le principe utilisé pour les Gui, et autre truc qui s'affichent à l'écran dans les jeux)
[OpenGL]classe camera: mouvement(srtout la rotation) bizarre
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html