Quelle est la façon la plus simple d'implémenter une caméra à la troisième personne en C ++ / DirectX9

8

Je suis assez nouveau sur C ++ et DirectX9 et je veux implémenter une caméra à la troisième personne. Après quelques lectures sur les caméras basées sur Quaternion, j'ai décidé d'essayer de l'implémenter. Mais cela me fait vraiment peur, alors je demande ici quelle est la façon la plus simple de mettre en œuvre une caméra TP?

Voici ce que la caméra doit faire:

  • Suivez les coordonnées stockées dans un 3DVector (x, y, z)

  • Faire pivoter autour de l'objet (lisse)

  • Peut-être un certain type de «ressort» = revenir lentement à la position normale derrière l'objet après avoir pivoté

Excusez-moi pour mon mauvais anglais: je suis allemand et toujours à l'école!

Merci d'avance!

ÉDITER:

Après quelques essais, je l'ai.

Le plus gros problème que j'ai considéré était l'extraction correcte du vecteur "direction" de la World-Matrix.

Au cours de mes recherches, j'ai trouvé principalement quelque chose comme ça:

D3DXVECTOR3 direction;
direction.x = worldMatrix->_13;
direction.y = worldMatrix->_23;
direction.z = worldMatrix->_33;
D3DXVec3Normalize(&direction, &direction);

Cela ne fonctionne PAS pour moi! Au lieu de cela, j'ai fait ceci:

D3DXVECTOR3 direction;
direction.x = worldMatrix->_13;
// Consider the .y after the .z!
direction.z = worldMatrix->_23;
direction.y = worldMatrix->_33;
D3DXVec3Normalize(&direction, &direction);

Pour la mise à l'échelle:

// The tenfold of the average distance
D3DXVec3Scale(&direction, &direction, 10.0f);

Fixer les positions:

cameraPos = targetPos - direction;
// For a top-view
cameraPos.y = targetPos.y + 5;

Pour les rotations, vous devez créer une matrice mondiale temporaire (à partir de la position de la cible) et la faire pivoter comme vous le souhaitez et extraire la direction.

Le lissage de la rotation dépend vraiment de VOTRE jeu!

Ce type de caméra à la troisième personne est vraiment facile à faire et il fait son travail!

VRAIMENT GRAND merci à "jheriko" qui m'a donné la bonne réponse!

Anonyme Anonyme
la source
+1 pour décrire réellement ce dont vous avez besoin, c'est rare (même si cela pourrait être plus détaillé, par exemple, le 3ème point prête à confusion - ne vouliez-vous pas dire qu'il tourne librement?).
Wondra
Oui, il doit tourner librement mais je veux qu'il revienne lentement au point à l'arrière du lecteur après la rotation!
Anonymous Anonymous

Réponses:

1

Ce qui vous aidera, c'est d'avoir la matrice de transformation pour l'objet que vous souhaitez suivre. Vous pouvez extraire le vecteur suivant de cette matrice - en fonction de votre système de coordonnées et de la neutralité de la matrice, ce sera l'une des lignes ou des colonnes avec le 4ème composant supprimé (en supposant que vous utilisez des matrices de transformation 4x4, sans facteur d'échelle - les facteurs d'échelle sont horribles pour de nombreuses raisons ... mais si vous avez des facteurs d'échelle, vous pouvez normaliser la ligne / colonne après avoir supprimé le 4ème composant.)

Une fois que vous l'avez, vous pouvez positionner la caméra directement derrière l'objet en la soustrayant de la position de l'objet. Pour déplacer la caméra vers l'intérieur et vers l'extérieur, vous pouvez mettre le vecteur à l'échelle et faire pivoter autour de l'objet, vous pouvez effectuer une rotation x et y (ou xz / zy, etc. selon la main, etc.) que vous appliquez à une copie de la matrice d'objet. avant d'extraire la direction avant.

Enfin, pour lisser le mouvement, la solution la plus simple consiste à suivre le décalage et les angles précédents et à les lerper selon une quantité dépendante du débit d'images décrite par a ^ (b.dt) où dt est le temps delta et a, b sont les paramètres que vous choisissez. a = 0,9 et b = 30 vous donne l'effet de vous déplacer de 90% vers la position comme si vous le faisiez à chaque image à 30 ips. c'est ce qu'on appelle un filtre de «réponse impulsionnelle infinie» et c'est un hack classique pour ce type de lissage.

cela peut ne pas être idéal, vous pouvez choisir une distance minimale et contraindre les angles également, sinon la caméra risque de traverser l'objet. si vous êtes à l'intérieur d'un monde dense, l'écrêtage ou la décoloration des objets intermédiaires deviendront également importants.

désolé c'est long, mais ce n'est pas un problème trivial, comme vous semblez l'avoir découvert.

J'espère que cela t'aides. je peux fournir plus de détails si nécessaire.

(ps aucun quaternion nécessaire - ils n'aident vraiment pas à ce problème)

jheriko
la source
Merci beaucoup! Vous m'avez donné quelques idées sur la façon de procéder. Mais j'apprécierais quelques exemples de code, si cela ne vous dérange pas. Et pourquoi ne pas utiliser des quaternions? J'ai lu qu'ils sont couramment utilisés pour faire ce genre de choses ( en.wikipedia.org/wiki/Quaternion ).
Anonyme Anonyme
J'ai essayé de le faire comme vous l'avez décrit, mais vous avez toujours des problèmes. La caméra n'est pas à l'arrière du Player, mais au moins quelque part sur le côté de lui! Je ne comprends pas la partie avec les rotations X et Y: que faut-il faire pivoter? La matrice mondiale, le vecteur direction ou une copie du vecteur position du joueur? Et comment faire pivoter? J'espère que tu peux m'aider!
Anonyme Anonyme
vous faites pivoter le vecteur de direction, ou la matrice à partir de laquelle vous l'extrayez (la matrice de transformation de l'objet, pas la matrice du monde ou de la vue) pour faire pivoter vous construisez des matrices de rotation d'angle d'axe et les multipliez, ou utilisez la trigonométrie ...
jheriko