TD9 : Trajectoire de caméra
L'objectif de ce TD est de mettre en place un système d'animation de la caméra par positions clés. Il devra permettre à l'utilisateur de positionner la caméra à un nombre arbitraire de positions et d'orientations clés dans l'espace 3D en leur associant un temps de passage. Une fois ces clés enregistrées, il devra calculer un chemin de caméra les interpolant au cours du temps de façon linéaire puis par une spline d'Hermite.
Téléchargez et compilez cette nouvelle base de code : pghp_td9.zip.
1. Clés
Dans la classe Camera
définissez une nouvelle structure Key
qui servira à enregistrer la position et l'orientation (sous forme d'un quaternion) de la caméra. La première est obtenue par l'appel de la fonction scnCamera
, et la seconde correspond à l'attribut _scnOrientation
. Déclarez également une table de hachage ordonnée (std::map) qui associera à un temps $t$ une clé $k$.
Implémentez la fonction Camera::setKey(int t)
qui ajoutera dans la table une nouvelle clé au temps $t$ (si elle existe déjà, elle la remplacera) avec la position et l'orientation courante de la caméra. Dans le Viewer
, associez la touche 'k' à l'appel de cette fonction. Vous pouvez pour l'instant utiliser un temps arbitraire à chaque appel (par exemple un compteur régulier).
Implémentez la fonction Camera::goToKey(int t)
qui rétablira la position et l'orientation de la caméra à la clé la plus proche du temps $t$ dans la table. Écrivez le résultat dans les attributs _scnCamera
et _scnOrientation
, mettez également l'attribut _interp
à true
pour que le résultat soit utilisé dans la méthode computeViewMatrix()
. Testez votre code en associant une autre touche du clavier ('g', par exemple) à cette fonction.
2. Interpolation linéaire
Il est certes utile de pouvoir revenir instantanément à une clé enregistrée, mais les bonds produits sont assez perturbants pour l'utilisateur. On souhaiterait plutôt qu'une transition spatio-temporelle douce s'effectue entre les clés. Pour cela, il est nécessaire d'interpoler progressivement les paramètres stockés dans les deux clés entourant le temps courant.
Modifiez la fonction goToKey
afin qu'elle calcule la position et l'orientation au temps $t$ par interpolation linéaire de ces paramètres aux deux clés adjacentes. Eigen définie la méthode slerp pour effectuer l'interpolation linéaire sphérique des orientations.
Pour tester votre implémentation, définissez plusieurs clés (espacées d'une cinquantaine d'images) puis appelez la fonction goToKey
dans Viewer::display
avec un compteur incrémenté à chaque image.
3. Interpolation d'Hermite
Le chemin de caméra est désormais continu, mais ce n'est pas encore le cas de la vitesse, ce qui peut être désirable pour une navigation plus fluide. Pour obtenir une continuité $C^1$ de la trajectoire, vous implémenterez l'interpolation des positions clés par un polynôme d'Hermite (conservez l'interpolation linéaire sphérique des orientations).
Vous aurez besoin de la vitesse aux positions clés ; vous utiliserez pour cela la formulation des splines de Catmull-Rom pour lesquelles les tangentes sont fixées à l'aide des positions clés adjacentes. Pour éviter de les re-calculer à chaque interpolation, vous pouvez les stocker dans la structure Key
.
Bonus : L'interpolation cubique d'une séquence de quaternions est possible mais coûteuse ; non seulement le calcul des tangentes est complexe, mais en outre l'interpolation (dénotée squad) nécessite trois interpolations sphériques (slerp). Référez-vous aux Geometric Tools' notes pour plus de détails.