Les vecteurs sous quake 3

Écrit le 03/07/2003 par douanier007
Dernière mise à jour : 06/02/2006

Qu'est-ce qu'un vecteur ?

Bon je vais pas vous faire une définition complète. Vous êtes tous allé à l'école et savez tous ce que c'est. Sachez juste que sous Quake (et tout les jeux trois D), les vecteurs sont en (tous avec moi) trois D. Jusque là rien d'extraordinaire. On stocke un vecteur 3D dans une structure vec3_t. Allez faire un tour dans q_shared.h et vous trouverez la définition de vec3_t mais aussi vec2_t ou vec4_t qui comme leur nom l'indique permettent de stocker 2 ou 4 valeurs, mais je m'éloigne du sujet. Un vec3_t est composé de trois float qui correspondent aux 3 repère (ordonnée, abscisse et disons « profondeur »). Il permet donc de définir (et je cite mon cours de maths) un trièdre direct.

Les différents type de vecteurs

Dans un jeu 3D en général, un vecteur va vous permettre de stocker plusieurs type d'information. En règle générale on l'utilise pour mémoriser une direction, un position ou un mouvement. Voyons pour commencer la position qui est la notion la plus simple.

vec3_t Position;
Position[0] = 10;
Position[1] = 20;
Position[2] = 30; 

Rien de bien compliqué ici, on a définit un vecteur de position et on lui donne une valeur qui représente un endroit précis de la carte.
Position[0] et Position[1] sont sur un plan parallèle à la carte alors que Position[2] représente « l'altitude ».

ent->s.pos.trBase

Ca ça représente la position de l'entité et c'est bon à savoir !

On va passer au vecteur de direction, il indique une heu... direction. La longueur d'un vecteur direction est toujours 1. C'est à dire qu'il représente une unité de déplacement. Par exemple si j'ai un vecteur direction :

vec3_t Direction;
Position[0] = 0.707;
Position[1] = 0.707;
Position[2] = 0; 

Ca signifie que le déplacement sera en diagonale parallèlement à la map.
Pourquoi 0.707 ?
Tout simplement pasque l'on veut un vecteur unitaire donc la longueur soit 1. Or, comme vous le savez tous (si si), la dimension d'un vecteur est égale à la somme des carrés de ses coordonnées. Je vous laisse faire le calcul ! 0.707² + 0.707² ça fait ? hmm ? et oui 1
On doit donc toujours avoir :
Position[0]² + Position[1]² + Position[2]² = 1
Bon c'est pas bien compliqué et ça aussi c'est bon à savoir.

Bon, pour ceux qui restent, on va passer aux vecteurs de déplacement, les autres, appliquez-vous un sac avec des glaçons sur le front.

Le meilleur moyen de vous expliquer serait de vous donner un exemple mais comme j'ai pas encore vu les fonctions sur les vecteurs ont va s'arranger en explication foireuses :p. Les vecteurs de déplacement indiquent donc un mouvement.

pm->ps->velocity

Là par exemple on a le déplacement du joueur.

pm->ps->velocity[2] += 30

Ca, ça va lui faire faire un bon en l'air avant de retomber lamentablement comme une merde !
Bon je reviendrai là dessus dans l'exemple.

Les oppérations sur les vecteurs

On ne peut pas utiliser les opérateurs habituels sur les vecteurs (+ ou - par exemple).
Si vous allez faire un tour dans q_shared.h vous verrez les définitions de toutes ces fonctions :
VectorSubtract(a,b,c) <=> c = a - b
VectorAdd(a,b,c) <=> c = a + b
VectorCopy(a,b) <=> b = a
VectorScale(v,s,o) <=> o = v * s où v est un nombre et o et s des vecteurs
VectorMA(v,s,b,o) <=> o = v + b * s avec o,v et s des vecteurs
VectorClear(a) <=> Ramène le vecteur a à la l'origin (0,0,0) je crois
VectorNegate(a,b) <=> Inverse a et sauvegarde le résultat dans b (jamais essayé)
VectorSet(v,x,y,z) <=> Initialise le vecteur v avec les coordonnées x,y,z
SnapVector(v) <=> Arrondie les coordonnées du vecteur v pour sauvegarder quelque chose de propre

Un pti exemple en vitesse

Voilà le code d'un jetpack. Il est pas terrible mais on fera avec.

Voilà la fonction que je place dans le fichier bg_pmove.c, il vous restera plus qu'a la lancer au bon moment !

void JetPack ()
{
    vec3_t forward ; //on définit le vecteur direction
    AngleVectors( pm->ps->viewangles, forward, NULL, NULL ); //on copie la valeur de l'angle de vue du joueur dans le vecteur direction
    forward[2] = 0; //on ne garde que la trajectoire parallèle à la base de la map
    pm->ps->velocity[2] += 40; //pouf on saute !
    VectorMA( pm->ps->velocity, 30, forward, pm->ps->velocity ); //pouf on part en avant ! 30 représente la distance/vitesse
}

Bon c'est basique ! Il faudrait prévoire la chute, etc. ! De plus ce n'est pas très rigoureux vu que le vecteur forward n'a plus une longueur de 1 ! Mais faites ce que je dis pas ce que je fais et tout se passera bien.

Bon j'ai conscience que ce tut n'est ni très complet ni très explicite alors je suis à votre disposition douanier007 -- free.fr

Merci au site : http://www.planetquake.com/code3arena/ qui m'a fait découvrir la joie des vecteurs !