Voir la version complète : Mouvement d'une caméra
Bonjour à tous,
J'ai une petite voiture, et j'aimerai implémenter une caméra qui la suivra, en prenant compte d'offset de position par rapport à l'origine de la voiture, et d'offset de point de visé. C'est à dire qu'on doit pouvoir dire à la caméra "tien toi derrière à 50 unité de la voiture, monte un peu de 10 unité, et regarde un peu au dessus de la voiture, disont 20 unité". J'ai fait une class Camera, ou l'on positionne l'entité à regarder et les 6 offsets (3 pour la position, 3 pour le point visé).
Je peux récupérer la position de la voiture, et les composantes X, Y, Z et W de son quaternion...
Voici ma première ébauche:
D3DXVECTOR3 eyePosition;
eyePosition.x = _entity->GetXPosition() + _xPositionOffset;
eyePosition.y = _entity->GetYPosition() + _yPositionOffset;
eyePosition.z = _entity->GetZPosition() + _zPositionOffset;
D3DXVECTOR3 lookAtPosition;
lookAtPosition.x = _entity->GetXPosition() + _xLookAtOffset;
lookAtPosition.y = _entity->GetYPosition() + _yLookAtOffset;
lookAtPosition.z = _entity->GetZPosition() + _zLookAtOffset;
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIX matrix;
D3DXMatrixLookAtLH( &matrix, &eyePosition, &lookAtPosition, &vUpVec );
DXUTGetD3DDevice()->SetTransform( D3DTS_VIEW, &matrix );
Le problème avec ce code, c'est que la caméra reste à la distance spécifiée par les offsets de position, mais sur le repère global, et donc elle ne reste pas "derrière" le kart.
Comment je peux faire?
Merci :)
A bientôt
Mets la caméra dans le repère local de ton kart, càd applique lui en premier lieu la transformation correspondante (je suppose que ton kart stocke sa matrice de transformation). D'autant plus que ça facilitera (un peu) ton code : ton origine sera non plus entity->GetPosition(), mais 0.
PS : si tu manipulais directement des vecteurs et non leurs composantes, tu écrirais 3 fois moins de code :)
PS2 : le préfixage par un underscore est reservé aux implémentations de la bibliothèque standard, autant éviter donc. Ca ne mange pas de pain de le dire.
Merci LouLou pour la rapidité et le conseil :)
Pour le "_", j'verrai ça plus tard ;) mais j'en tiens compte
J'ai fait ça:
D3DXMATRIX offsetPositionMatrix;
D3DXMatrixTranslation(&offsetPositionMatrix, _xPositionOffset, _yPositionOffset, _zPositionOffset);
D3DXMATRIX matrix = _entity->GetMatrix();
D3DXMatrixMultiply(&matrix, &matrix, &offsetPositionMatrix);
DXUTGetD3DDevice()->SetTransform( D3DTS_VIEW, &matrix );
Alors en faisant ça, tout est inversé :s
si _yPositionOffset est positif, la position de la caméra sera en dessous de la voiture. Si j'avance, la caméra recul, si je tourne a droite, la caméra tourne vers la gauche :s
J'ai rajouté ça
D3DXMatrixInverse(&matrix, NULL,&matrix);
et maintenant c'est correct :)
Mais bon, j'aurai aimé un LookAt aussi :s
J'ai rajouté ça
D3DXMatrixInverse(&matrix, NULL,&matrix);
et maintenant c'est correct
Oups, j'avais oublié de préciser ce détail. En effet, il ne faut jamais oublier que pour simuler une caméra, on va en fait appliquer les transformations inverses à la scène. Mais bon t'as trouvé tout seul :)
Mais bon, j'aurai aimé un LookAt aussi :s
Rien ne t'empêche de garder une matrice construite avec un D3DXMatrixLookAtLH, suffit d'adapter les paramètres au fait que tu es maintenant relatif au tank et non au repère global.
Ben c'est que je prévoit un peu pour la suite. Là actuellement, j'me calque sur la matrice de la voiture.
Si la voiture passe sur une mine et s'envole, j'veux pas que la caméra parte avec, et tourne également dans tous les sens, par exemple.
Donc j'me dit que se baser sur le repère de la voiture... c'est peut-être pas une bonne idée.
Erf j'suis un peu perdu, faudrai que je mette a plat le comportement de la caméra afin de déterminer l'algo qui la composera, en fonction de la matrice de la voiture, ses forces appliqué, sa vitesse de translation et de rotation afin de déterminer si la caméra suit le mouvement ou reste ou elle est juste en la pointant...
Erf j'vais devoir m'accrocher et réfléchir :'(
Faut que j'implémente un acteur physique aussi, pour être averti lors des collisions et dire à la caméra "attention, derrière y'a un mur, pousse toi un peu par là"...
Erf j'ai des migraines :'(
Effectivement là ça devient déjà plus compliqué.
Réflechit bien à ta conception et à tes algorithmes avant de coder, et... bonne chance.
L'implémentation d'une bonne gestion de caméra est un probleme complexe et pour avoir joué à *beaucoup* de jeux 3D sur console, je peux te dire (mais tu dois deja le savoir)que meme les grands studios de développement sont souvent infoutus de faire qq chose de bien (allez un exemple au pif: Sonic adventures sur Dreamcast...)
Alors il n'y a pas de complexe a trouver ca difficile :)
Voila c'etait juste pour t'encourager.
Maintenant est ce que qqun pourait controler ce que je dis:
Si on veut placer un objet sur la scene a une position correspondant a une matrice de transformation du monde matWorld
Que d'autre part la matrice de vue construite à partir de vecteur position, point de visée et verticale est matView
Alors il faut faire en pseudo code
SetTransform( D3DTS_VIEW, inverse(matWorld x matView) );
right?
Lenolian
01/12/2005, 23h08
Pourquoi se compliquer l'existence avec une multiplication et une inversion !
SetTransform(D3DTS_VIEW, &matview);
SetTransform(D3DTS_WORLD, &matworld);
et l'objet est placé là où il faut.
sont souvent infoutus de faire qq chose de bien
Joli néologisme :)
Lightness1024!
01/12/2005, 23h55
tu connaissais pas "infoutus" ?
(faut dire: "c'est pas faut" dans ce cas !)
huhu
non enfin koi c'est vrai infoutu ca se dit couramment ou c'est moi qui plane ?
pour en revenir a la caméra, je suis sur un systeme d'enregistrement de demos actuellement et j'utilise un systeme qui detecte des seuils d'acceleration pour distribuer la capture des points de controle du pathtrack en fonction de la "nervosité" des mouvements. je reproduis apres le mouvement avec une interpolation cubique a travers la fonction D3DXVec3Hermite tres pratique je trouve. (deux tangentes, deux points, un coef entre 0 et 1 et andale ! )
Bah j'y ai déjà réfléchit à ma conception. J'ai mis à plat les principaux comportement de ma caméra ainsi que les valeurs à prendre en compte, pour tout de suite implémenter l'exportation des données de l'entité que j'aurai besoin.
Quand j'aurai au moins 2-3h devant moi j'me lancerai dans l'algo car ça se fait pas 5 min vite fait entre deux trucs.
-Le comportement initial et global de la caméra, est de se tenir derrière la voiture, à une distance définie, en visant un point relatif à la voiture. Pour ça, j'ai besoin de la matrice de la voiture.
-Lorsque la voiture tourne, la caméra doit "appuyer" la rotation en se décalant légèrement, comme les vrais. Pour ça j'ai besoin de la force appliquée sur les roues avant de la voiture. J'y ai réfléchit pas mal de temps à ça. Car j'étais parti sur une base de trajectoire par rapport à la rotation, mais lorsque la voiture dérappe dans un virage, alors que plus aucune force n'est appliquée dans la direction, je voudrais "redresser" la caméra quand même afin que l'utilisateur puisse voire le danger arriver :p même s'il pourra pu faire grand chose lol.
-Lorsque la voiture monte ou déscend une pente, la caméra derrière doit suivre. Je voudrais un comportement ayant un minimum de souplesse, donc je testerai mais j'pense devoir implémenter une valeur limite de la vitesse de mouvement de la caméra, quoi que entre le moment ou la voiture quitte le plat et arrive à l'orientation maximal de la pente... faut implémenter et tester, voire retoucher si ça fait trop "rigide". Pour ça, il me faut le "pitch" de l'orientation. Là encore, un problème se pose, car les matrices du moteur physique n'offres pas la possibilité de récupérer les valeurs yaw, pitch et roll. Etant habitué à travailler avec ça, il va falloir que je convertisse le quaternion en ces 3 valeurs, ou que j'apprenne a maitriser ces derniers.
-Par la suite, la voiture aura un turbo, et pour accuenter cette sensation d'accélération (ou de décéllération lors du freinage), il faut que l'utilisateur ai l'impression que la voiture accélère tellement vite d'un coup que la caméra a du mal à suivre. Et inversement pour le freinage. Là il me faut la vitesse de translation sur l'axe de la caméra.
-Lorsque la voiture décolle en se prenant une mine, ou bien lors d'une collision avec une autre voiture, ou une arme, la caméra ne devra pas s'emballer, mais prendre du recul en fonction de la valeur du choc, et retourner derrière elle lorsque celle ci se "calme" et se pose, le tout progressivement, et en souplesse. Pour ça, j'ai besoin de la vitesse angulaire de la voiture, et faire jouer la position toujours dans le LookAt sans tenir compte de l'orientation lorsque cette vitesse devient trop importante.
-Pour finir, les collisions de la caméra avec le décors. Là il faut que j'implémente un objet physique correspondant à la caméra, surement une sphère, et que je "capte" les collision afin de faire bouger la caméra dans la direction opposé à la collision détecté. Ca ca va pas être facil. J'y ai réfléchit 5 min... ça sent le "tremblement de terre" qu'on retrouve souvent dans les jeux...
-Ha j'allais oublier... Lorsque la voiture est cachée par un objet, il faut rediriger la caméra pour la distinguée. Facil à détecter, mais pour déterminer si on fait tourner la caméra vers la droite ou la gauche, ou alors la faire monter ou descendre... c'est une autre histoire, mais j'ai ma p'tite idée.
Voilà, avec tout ça, il faut que je ponde 1 seul algo qui mélange tout et qui réponde à tout ces critères, en évitant un max les if/else if/else if/else if/else.
M'enfin, d'abord faut que je m'initie un peu à la physique et que je sache à quoi corresponde chaque valeur de chaque paramètre et chaque objet décrivant un acteur... histoire d'obtenir de bonnes conditions de tests.
J'vais pas m'faire chier quoi.
Voilà voilà...
Je vous tien au courant ;)
A bientôt
Moi je verrais bien des liaisons élastiques pour modéliser ca, du genre un ressort entre ta voiture et ta caméra...
C'est juste une idée a creuser... ou pas :)
(je te sens mal barré avec tes if then else :p mais j'espere avoir tort ^^)
La feinte "habituelle" lorsque un objet masque ton acteur princial: afficher cet objet en semi-transparence (alpha = 0,3 qq chose du genre) ou en wireframe, ou ne pas l'afficher du tout.
Mais a mon avis déplacer la caméra, ce serait galère, et puis d'un point de vue gameplay (je m'y connais plus en tant que joueur que programeur), les mouvements de caméra incontrolés c'est tres bien si c'est bien fait mais ca peut te faire lacher un jeu quand c'est mal fait... Achtung la jouabilité!!!
Ben.... merci pour tes conseils...
J'vous ferez tester j'pense lol, mais c'est pas pour tout de suite :'(, y'a des mots physique que je savais même pas que ça existais, alors j'doit d'abord régler ça avant de passer à la suite ;)
grob1212
02/12/2005, 09h54
Moi je verrais bien des liaisons élastiques pour modéliser ca, du genre un ressort entre ta voiture et ta caméra...
C'est juste une idée a creuser... ou pas :)
(je te sens mal barré avec tes if then else :p mais j'espere avoir tort ^^)
La feinte "habituelle" lorsque un objet masque ton acteur princial: afficher cet objet en semi-transparence (alpha = 0,3 qq chose du genre) ou en wireframe, ou ne pas l'afficher du tout.
Mais a mon avis déplacer la caméra, ce serait galère, et puis d'un point de vue gameplay (je m'y connais plus en tant que joueur que programeur), les mouvements de caméra incontrolés c'est tres bien si c'est bien fait mais ca peut te faire lacher un jeu quand c'est mal fait... Achtung la jouabilité!!!
Sans rire, j'ai eu exactement les mêmes idées pour ce problème ce matin dans mon lit !
Utiliser un potentiel d'élasticité qui relie virtuellement la caméra avec le véhicule et l'affichage en transparence pendant le passage au travers d'obstacles ! Reste à savoir quand est-ce que la voiture est masquée et quelles zones doivent être mises en transparences...
Parce que si ton véhicule entre par exemple dans un hangar, ta caméra va faire n'importe quoi si tu lui demande de contourner l'obstacle (sauf si biensur elle arrive à passer également la porte... comment ca se code ca ?)
Erf ça commence à m'souler cette histoire.
J'ai passé la nuit sur le moteur physique, pas moyen de le configurer, la voiture fait toujours a peine 2 grammes, même lorsque je configure la masse à 50 ou 500 ou 5000.
En plus, le SDK de novodex, quand on voi ce qu'ils ont réalisé avec, ça a l'air d'être méga puissant, mais la documentation laisse à désirer...
Peut tu nous décrire un peu ce modèle physique et comment tu l'as implémenté ? Mes comps en prog sont relativement basiques mais la physique je tate un peu, je peux peut-etre t'aider un peu trop de "peu"...)
Sinon rassure toi (je l'ai deja dit ^^) mais le modèle physique (faire en sorte que la voiture donne l'impression de faire son poids, qu'elle ait une inertie, que son adhérence a la route soit réaliste, etc.) fait aussi parti des choses les plus difficiles a faire meme chez les grands studios professionnels (je pense à GT3, Rallisport chalenge) Pour s'en convaincre il suffit de voir que le "modèle physique" ou le "moteur physique" est souvent un terme àla mode et repris comme argument de marketting dans les salons professionnels (je me rapelle d'halo 2 par exemple ou d'half life 2... Quand les devs reussissent un bon modele ils en sont pas peu fiers, c'est que ca doit pas etre a la portée de tous.
Donc tu t'attaques pas a du petit problemes mon ami :D
Gambare !!!
Pour l'occlusion, une idée comme ca et peut être que ceux qui s'y connaissent pourront développer: les occlusion queries. Le principe, si j'ai bien compris, consiste a effectuer un premier rendu de la scenne en off screen, en tres basse résolution (320x200...) et tessellation (LOD minimal voire utiliser les bouding boxes?) afin de compter pour chaque phase de rendu le nombre de pixels effectivement dessinés. S'il n'y en a pas c'est ue notre objet a de grandes chances d'etre masqué ou partiellement masqué dans la scene réelle. Ce compte de pixels est fait par le hard sur les cartes récentes. (A creuser, je n'en sais pas plus - meme pas sur de pas avoir dit d'inexactitude...)
grob1212
02/12/2005, 17h30
Pour l'occlusion, une idée comme ca et peut être que ceux qui s'y connaissent pourront développer: les occlusion queries. Le principe, si j'ai bien compris, consiste a effectuer un premier rendu de la scenne en off screen, en tres basse résolution (320x200...) et tessellation (LOD minimal voire utiliser les bouding boxes?) afin de compter pour chaque phase de rendu le nombre de pixels effectivement dessinés. S'il n'y en a pas c'est ue notre objet a de grandes chances d'etre masqué ou partiellement masqué dans la scene réelle. Ce compte de pixels est fait par le hard sur les cartes récentes. (A creuser, je n'en sais pas plus - meme pas sur de pas avoir dit d'inexactitude...)
Ce que tu as dit est parfaitement correct. Par contre je ne sais pas non plus si c'est un caps disponible sur tous les matos graphiques. Y'a un bon programme d'exemple sur le sujet chez ATI : http://www.ati.com/developer/samples/dx9/OcclusionQuery.html
J'ai utilisé cette capacité sur 6800GT pour calculer l'histogramme d'une image.
Hoplaaa, merci Janta.
Je te passe un topic que j'ai fait (avec l'aide de Grob) visant à rechercher des gens qui voudrait participer à ce projet:
http://forum.games-creators.org/showthread.php?t=2284
Si ça te dis... kinju59@gmail.com :)
Sinon rapidement, pour intégrer le moteur physique, j'ai regardé les exemple fournis avec le sdk, et j'ai fait pareil dans la conception. J'ai fait un Singleton qui donne accès à l'objet centrale du moteur. Ensuite, une class Entity, qui contient les données communes d'un l'entité et un acteur physique (avec biensûr en membre, les objet necessaire à la création de cette acteur). Ensuite, il y a des fonction communes pour charger un .X, et une fonction CreateActor qui cré l'acteur quoi. Puis des fonction virtuelles pures pour "remplir" les objets permetant la création de cet acteur, qui sont appelé dans l'ordre qui faut.
Comme ça, lorsque l'on veut faire une nouvelle entité, on la dérive, on rempli les fonctions de configuration de l'objet physique correspondant, et puis le reste, avec entre autre le comportement.
Façon j'ai rien a cacher, j'ai un tit serveur SVN, un mappage de port et tu récup mes sources ;)
Voili voilou :p
A bientôt :)
vBulletin® v.3.6.5, Copyright ©2000-2009, Jelsoft Enterprises Ltd. Tous droits réservés - Version française vbulletin-fr.org