Finalmente sono riuscito a dedicarmi un po a DirectX (mi piace giocare a BS4) leggendo la prima parte del capitolo 2 del libro sulle animazioni: Animazioni basate sui KeyFrames, molto interessante: ve ne spiego un pa`² il funzionamento.
Supponiamo di avere questa struttura
typedef struct _kf
{
DWORD Time;
D3DMATRIX matTransformation;
} sKeyFrame;
Questo e` un keyframe: ossia un fotogramma-chiave. Cio e` una struttura che contiene il tempo, in millisecondi, in cui iniziera` l’animazione, e una matrice 4×4 che contiene il movimento da fare.
Per animare correttamente, nella nostra funzione di rendering calcoleremo una matrice che setteremo all’oggetto da disegnare, in questo modo.
Per prima cosa calcoliamo il tempo in cui ci troviamo tramite questa righetta di codice
static DWORD StartTime = timeGetTime();
DWORD Time = timeGetTime() - StartTime;
Con il tempo trascorso nelle nostre mani, e` possibile ora capire a quale keyframe ci troviamo.
Ad esempio, se il tempo trascorso e` 60 millisecondi, vuol dire che l’animazione e` da qualche parte tra il keyframe 0 (0 millisecondi) ed il key frame #1 (che arriva a 400 millisecondi).In questo piccolo ciclo capiamo in quale keyframe ci troviamo attualmente, e salviamo il risultato nella variable KeyFrame.
DWORD KeyFrame = 0;
for (int i = 0; i < 4; i++)
{
if ( Time >= Keyframes[i].Time )
KeyFrame = i;
}
Dopo aver messo in KeyFrame la nostra variabile i, dobbiamo ora settare una nuova variabile KeyFrame2 in cui metteremo il frame successivo a quello in cui siamo.Se invece KeyFrame e` uguale all’ultimo, allora lo rimaniamo tale (non ho ancora capito il perche`)
DWORD Keyframe2 = (KeyFrame==3) ? KeyFrame : KeyFrame + 1;
Ora dobbiamo prendere la differenza tra i relativi tempi dei KeyFrame e calcolare un valore scalare per la nostra matrice.
DWORD TimeDiff = Keyframes[Keyframe2].Time -
Keyframes[KeyFrame].Time;
if(!TimeDiff)
TimeDiff=1;
float Scalar = (float)(Time - Keyframes[KeyFrame].Time) / (float)TimeDiff;
Ora che abbiamo il nostro valore scalare (che va da 0 a 1), possiamo calcolare la nostra matrice usando questo valore per interpolare le 2 matrici dei keyframe.
D3DXMATRIX matInt = D3DXMATRIX(Keyframes[Keyframe2].matTransformation) -
D3DXMATRIX(Keyframes[KeyFrame].matTransformation);
matInt *= Scalar;
matInt += D3DXMATRIX(Keyframes[KeyFrame].matTransformation);
Mettendo questa MatInt come worldmatrix del nostro oggetto,avremo un loop di animazione basato su keyframe.
Devo ancora mettere a punto delle cosette (l’animazione viene conclusa solo una volta…non e` continua e non so perche`), ma il grosso e` fatto.