#include "Animation3D.h" #include "Model3D.h" using namespace Framework; // löscht eine KnochenData Struktur void Animation3D::deleteKnochenData( KnochenData *d ) { if( d->next != 0 ) deleteKnochenData( d->next ); delete d; } // Inhalt der Animation3D Klasse aus Animation3D.h // Konstruktor Animation3D::Animation3D() : ReferenceCounter() { for( int i = 0; i < MAX_KNOCHEN_ANZ; i++ ) kd[ i ] = 0; maxTime = 0; } // Destructor Animation3D::~Animation3D() { for( int i = 0; i < MAX_KNOCHEN_ANZ; i++ ) deleteKnochenData( kd[ i ] ); } // Fügt für einen bestimmten Knochen ein Keyframe hinzu // kId: Die Id des Knochens // time: Die Zeit, die vergehen soll bis der Knochen die Position und die Rotation des Keyframes follständig erreicht hat // pos: Die Position des Knochens die erreicht werden soll in Modellkoordinaten // rot: Die Rotation des Knochens um seine Position die erreicht werden soll void Animation3D::addKeyFrame( int kId, double time, Vec3 pos, Vec3 rot ) { KnochenData *d = kd[ kId ]; if( !d ) { kd[ kId ] = new KnochenData(); kd[ kId ]->next = 0; kd[ kId ]->time = time; kd[ kId ]->pos = pos; kd[ kId ]->rot = rot; return; } while( d->next ) d = d->next; d->next = new KnochenData(); d->next->next = 0; d->next->time = time; d->next->pos = pos; d->next->rot = rot; } // Wendet die Animation auf ein bestimmtes Skelett an // zS: Das Skelett // timeOffset: zeit in sekunden, die diese Animation bereits auf dem Skelett angewendet wurde. Wird automatisch von der Animation aktualisiert. // sec: zeit in Sekunden, die vergangen ist seit dem diese Methode zuletzt für das Skelett aufgerufen wurde void Animation3D::apply( Skelett *zS, double &timeOffset, double sec ) const { if( zS->k ) apply( zS->k, timeOffset, sec ); timeOffset += sec; if( timeOffset > maxTime ) timeOffset -= maxTime; } // Wendet die Animation auf ein bestimmten Knochen an // zS: Der Knochen // timeOffset: zeit in sekunden, die diese Animation bereits auf dem Knochen angewendet wurde. // sec: zeit in Sekunden, die vergangen ist seit dem diese Methode zuletzt für dem Knochen aufgerufen wurde void Animation3D::apply( Knochen *zK, double timeOffset, double sec ) const { if( zK->geschwister ) apply( zK->geschwister, timeOffset, sec ); if( zK->kinder ) apply( zK->kinder, timeOffset, sec ); KnochenData *d = kd[ zK->id ]; if( d ) { while( timeOffset > d->time ) { timeOffset -= d->time; d = d->next; if( !d ) d = kd[ zK->id ]; } while( sec > 0 ) { double left = d->time - timeOffset; if( left > 0 ) { float proc = (float)MIN( sec / left, 1 ); zK->pos += ( d->pos - zK->pos ) * proc; zK->winkel += ( d->rot - zK->winkel ) * proc; sec -= left; } else { zK->pos = d->pos; zK->winkel = d->rot; sec -= d->time; } timeOffset = 0; d = d->next; if( !d ) d = kd[ zK->id ]; } } }