Bouger la caméra [D3D] - Programmation
Marsh Posté le 03-12-2001 à 22:20:18
J'ai essayé un autre moyen, voici ma class:
class CCamera
{
public:
void Rotate(double x, double y, double z);
void Move(float x, float y, float z);
};
void CCamera::Move(float x, float y, float z)
{
D3DXMATRIX mtrans;
D3DXMatrixTranslation(&mtrans, x, y, z);
D3DXMatrixMultiply(&ViewMatrix, &mtrans, &ViewMatrix);
g_lpD3DDevice->SetTransform(D3DTS_VIEW, &ViewMatrix);
}
void CCamera::Rotate(double x, double y, double z)
{
D3DXMATRIX mrot;
D3DXMatrixRotationYawPitchRoll(&mrot, y, x, z);
D3DXMatrixMultiply(&ViewMatrix, &mrot, &ViewMatrix);
g_lpD3DDevice->SetTransform(D3DTS_VIEW, &ViewMatrix);
}
Le problème, c'est que ce n'est pas la caméra qui bouge mais les objets... Si j'avance ou recule sans avoir changé l'angle ça va, mais si je change l'angle, ce n'est pas la caméra qui tourne mais les objets... Je ne comprends pas...
Marsh Posté le 03-12-2001 à 22:51:38
boufer la caméra ? 'ttention quand même ...
ça veut dire quoi bouger ... colinéire ... axe ... etc. ?
ta caméra est un objet comme un autre, à savoir qu'elle peut avoir une position, une matrice de rotation, un vecteur de scaling, etc. donc déjà un point sur l'architecture : c'est mieux de faire une classe de base de laquelle tu dérives ta classe caméra, ta classe mesh, tes classes primitives (sphere torus cube etc.) ... que tu bouges n'importe lequel de ces objets dans l'espace, ils réagiront tous de la même façon.
maintenant, la caméra a besoin d'un service en plus : la matrice view, qui transforme les objets dans le repère caméra. ce n'est pas la matrice citée plus haut, car celle-ci donne l'orientation de l'objet dans le repère world. la matrice caméra est tout simplement l'inverse de la matrice world. pourquoi ? car la matrice citée plus haut est en fait la matrice qu'on peut appeler localToWorld, qui transforme l'objet de son repère local vers le repère world. nous on veut transformer le repère world dans le repère caméra. la matrice localToWorld s'appelerait pour la caméra cameraToWorld. on veut worldToCamera, qui n'est autre que l'inverse de cameraToWorld.
clair ? mettons que tu as deux objets dans ta scène, un cube et une caméra. on a :
* la matrice de transformation du cube de son repère local vers le repère world : cubeToWorld
* la matrice de transformation du repère world vers le repère caméra : worldToCamera (qui est tj l'inverse de cameraToWorld)
donc le 'repère' final est cubeToWorld * worldToCamera = cubeToCamera, ce qu'on souhaite obtenir.
//
annexe : la matrice localToWorld est une matrice de rotation des angles de l'objet, ou le résultat du quaternion, à laquelle on colle les données de translation / scaling / pivot / etc.
c'est bon ?
Marsh Posté le 04-12-2001 à 17:11:10
Donc pour résumer, pour faire ma caméma je fais:
un point qui donne les coordonées de la caméra
je la translate ou je lui fait subir une rotation
je prends la matrice locale qui est le produit de la matrice de translation et de rotation
je prends l'opposé de chaque éléments de la matrice locale et je les rentre dans la matrice VIEW
si c'est pas ça, alors j'ai rien compris du tout...
Marsh Posté le 04-12-2001 à 18:50:42
c'est bon ! sauf qu'il te manque apparemment qq bases mathématiques sur les matrices. l'inverse N d'une matrice M est telle que M * N = MatriceIdentité. cherche dans d3dx, il doit y avoir une fonction pour faire ça.
edit : je dis ça pour la dernière partie de ton message, prendre l'opposé de chaque élément ne marchera pas.
[edtdd]--Message édité par youdontcare--[/edtdd]
Marsh Posté le 04-12-2001 à 19:46:24
Bon je crois que je suis arrivé à faire marcher un peu le binz, le seul problème c'est que pour faire le mouvement souhaité il faut le faire puis faire son opposé.
Par exemple, je veux tourner à droite: je dois tourner à droite puis tourner à gauche, si je tourne que à droite ça marche pas...
Le problème, c'est que je n'ai jamais étudié les matrices donc c'est un peu dur de les utiliser.
Si vous pouviez m'aider encore un peu
Voici le code actuel:
class CCamera
{
public:
void Rotate(double x, double y, double z);
void Move(float x, float y, float z);
};
void CCamera::Move(float x, float y, float z)
{
D3DXMATRIX mtrans;
D3DXMatrixTranslation(&mtrans, x, y, z);
D3DXMatrixMultiply(&ViewMatrix, &mtrans, &ViewMatrix);
D3DXMatrixInverse(&ViewMatrix, NULL, &ViewMatrix);
g_lpD3DDevice->SetTransform(D3DTS_VIEW, &ViewMatrix);
}
void CCamera::Rotate(double x, double y, double z)
{
D3DXMATRIX mrot;
D3DXMatrixRotationYawPitchRoll(&mrot, y, x, z);
D3DXMatrixMultiply(&ViewMatrix, &mrot, &ViewMatrix);
D3DXMatrixInverse(&ViewMatrix, NULL, &ViewMatrix);
g_lpD3DDevice->SetTransform(D3DTS_VIEW, &ViewMatrix);
}
Marsh Posté le 04-12-2001 à 19:56:49
là ce n'est pas un problème de matrices, mais un problème d'angles d'euler. je ne sais pas comment marche la fonction de d3dx ... des rotations dans l'ordre x, y, z donnent un résultat différent de z, y, x. ça peut marcher, mais ce n'est peut-être pas indiqué pour une transfo caméra.
tu devrais plutôt essayer avec deux angles pour commencer x et y. créé les deux matrices de rotation, essaye les deux sens de multiplication.
même, essaye juste avec une translation et une seule rotation.
et pour un contrôle parfait de la chose, il faut passer aux quaternions. les angles d'euler c'est bien sympa pour faire des trucs simples, mais si tu veux commencer à faire ne serait-ce qu'un contrôle qui te permet d'orienter ton objet comme tu veux (comme la virtual sphere de maya), c'est mort.
Marsh Posté le 05-12-2001 à 11:38:17
ce n'est pas un probleme d'angles d'euler
vu qu'on travaille avec des matrices.
C'est la maniere dont tu appliques tes matrices
qui pose probleme.
il faut que tu memorises la position(vecteur) et l'orientation (quaternion ou systeme d'angles) de ta camera.
Tu crees une methode apply_matrix
qui en debut de trace
va charger une matrice avec l'identite
(ne pas oublier ca, je sais pas si le constructeur le fait).
tu appliques une matrice de translation (-vecteur pos de ta camera) et tu appliques une matrice de rotation (-rotation de ta camera !attention! -rotation <> -matrice de rotation comme il a deja ete precise)
et tu charges ca dans ta matrice view
(sans faire de multiply sinon les transformations s'ajoutent!)
A+
LEGREG
Marsh Posté le 03-12-2001 à 21:34:16
Connaissez-vous des sites expliquant la façon de boufer la caméra? C'est à dire de calculer une matrice VIEW une fois qu'on bouge d'un vecteur qui n'est pas colinéaire à un des axes du repère?
Le code de mon bouquin sur D3D ne marche pas, alors je fais appel à votre aide.
Merci.