class AnimTrack{ // only the relevant code is shown here now public: // these could also be pure virtual, depending on whether you allow just AnimTracks virtual int GetInterpolatedPosition(float CurrentTime, Vector3 &v) { return 0; } virtual int GetInterpolatedRotation(float CurrentTime, Quaternion &q) { return 0; }};class PosTrack : public AnimTrack{ // only the relevant code is shown here now public: int GetInterpolatedPosition(float CurrentTime, Vector3 &v) { // Interpolate between positions, depending on CurrentTime // v = output parameter // ... return 1; }};class RotTrack : public AnimTrack{ // only the relevant code is shown here now public: int GetInterpolatedRotation(float CurrentTime, Quaternion &q) { // Interpolate between rotations, depending on CurrentTime // q = output parameter // ... return 1; }};void SkeletonAnimation::Update(float FrameDeltaTime){ /* Call the base class update function */ Animation::Update(FrameDeltaTime); /* Perform specific code for skeleton animation */ // Temporary variables Vector3 TempPos; Quaternion TempRot; // Iterate over all the tracks and let them contribute to the overall pose for(AnimTrackIter It = m_Tracks.begin(); It < m_Tracks.end(); ++It) { int BoneID = It->GetResourceID(); Bone &CurrentBone = m_pSkeleton->GetBone(BoneID); // SkeletalAnimation::m_pSkeleton (this could also be a list of affected skeletons) if(It->GetInterpolatedPosition(m_CurrentTime, TempPos)) // found a position track CurrentBone.SetPosition(TempPos); if(It->GetInterpolatedRotation(m_CurrentTime, TempRot)) // found a rotation track CurrentBone.SetRotation(TempRot); } // Rest of the code // ...}
Other possible solutions are:
- using RTTI to identify which type of track we are iterating over and then contribute the result as necessary
- store an enumeration-ID in the AnimTrack which we fill in during construction, so we can query for the type of track (I don't think this will work if you derive further from e.g. PosTrack
- it should be possible to solve this using the Visitor Pattern, but it seems overkill for a situation like this
@everyone: let me know what you think about this solution