MultiInterpolationAnimationT.cc 4.85 KB
Newer Older
Dirk Wilden's avatar
Dirk Wilden committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#define MULTIINTERPOLATIONANIMATIONT_C

#include "AnimationT.hh"
#include <algorithm>

//-----------------------------------------------------------------------------------------------------

/**
 * @brief Copy constructor
 *
 * @param _other The animation to copy from
 */
template<typename Scalar>
MultiInterpolationAnimationT<Scalar>::MultiInterpolationAnimationT(const MultiInterpolationAnimationT<Scalar> &_other) :
        InterpolationAnimationT<Scalar>(NULL, NULL, NULL),
        interpolationAnimations_(_other.interpolationAnimations_)
{
        
}

//-----------------------------------------------------------------------------------------------------

template<typename Scalar>
AnimationT<Scalar>* MultiInterpolationAnimationT<Scalar>::copy() {
  return new MultiInterpolationAnimationT<Scalar>(*this);
}

//-----------------------------------------------------------------------------------------------------

template<typename Scalar>
bool MultiInterpolationAnimationT<Scalar>::getMinInput(Scalar& _result) {
  if (interpolationAnimations_.size() == 0)
    return false;
  else
    interpolationAnimations_[0]->getMinInput(_result);
  
  for (uint i=0;i<interpolationAnimations_.size();++i) {
    Scalar currentInput;
    interpolationAnimations_[i]->getMinInput(currentInput);
    
    if (currentInput < _result)
      _result = currentInput;
  }
  
  return true;
}

//-----------------------------------------------------------------------------------------------------

template<typename Scalar>
bool MultiInterpolationAnimationT<Scalar>::getMaxInput(Scalar& _result) {
  if (interpolationAnimations_.size() == 0)
    return false;
  else
    interpolationAnimations_[0]->getMaxInput(_result);
  
  for (uint i=0;i<interpolationAnimations_.size();++i) {
    Scalar currentInput;
    interpolationAnimations_[i]->getMaxInput(currentInput);
    
    if (currentInput > _result)
      _result = currentInput;;
  }
  
  return true;
}

//-----------------------------------------------------------------------------------------------------

/**
 * @brief Returns the number of frames that this animation can playback
 * Note that this is not simply the sum of all animations' frame counts, as they can (and most likely will) overlap.
 */
template<typename Scalar>
unsigned long MultiInterpolationAnimationT<Scalar>::getFrameCount()
{
  Scalar minInput=0, maxInput=0;
  if (getMinInput(minInput) && getMaxInput(maxInput)) {
    return ((maxInput - minInput) * FPS);
  }
  
  return 0;
}

//-----------------------------------------------------------------------------------------------------

template<typename Scalar>
PoseT<Scalar> * MultiInterpolationAnimationT<Scalar>::getPose(unsigned long _iFrame) {
  //Use the reference pose of the first (in terms of the input value, i.e. the time in most cases)
 
  if (interpolationAnimations_.size() == 0)
    return NULL;
 
  Scalar minValue=0; uint minInterpolationAnimationIndex = 0;
  for (uint i=0; i<interpolationAnimations_.size(); ++i) {
    Scalar currentValue;
    interpolationAnimations_[i]->getMinInput(currentValue);
    Scalar minValueTmp = std::min(minValue, currentValue);
    minInterpolationAnimationIndex = (minValueTmp < minValue) ? i : minInterpolationAnimationIndex;
  }

  return getPose(_iFrame, interpolationAnimations_[minValue]->getReference());
}

//-----------------------------------------------------------------------------------------------------

template<typename Scalar>
PoseT<Scalar> * MultiInterpolationAnimationT<Scalar>::getPose(unsigned long _iFrame, Pose* _reference) {
  if (_iFrame == 0)
    return _reference;
  
  Pose* newPose = NULL;
  Pose* referenceCopy = new Pose(*_reference);
  
  for (uint i=0; i<interpolationAnimations_.size(); ++i) {
    Scalar minInput, maxInput;
    interpolationAnimations_[i]->getMinInput(minInput); interpolationAnimations_[i]->getMaxInput(maxInput);
    
    unsigned long minFrame = (minInput * FPS);
    unsigned long maxFrame = (maxInput * FPS);
    
    //Check, if the current animation is responsible for displaying this frame
    if (_iFrame < minFrame || _iFrame > maxFrame)
      continue;
    
    if (interpolationAnimations_[i]) {
      if (newPose == NULL)
	newPose = interpolationAnimations_[i]->getPose(_iFrame - minFrame, referenceCopy);
      else
	newPose = interpolationAnimations_[i]->getPose(_iFrame - minFrame, newPose);
    }
  }
  
  delete referenceCopy;
  
  if (newPose == NULL)
    newPose = _reference;
  
  return newPose;
}

//-----------------------------------------------------------------------------------------------------

template<typename Scalar>
InterpolationAnimationT<Scalar>* MultiInterpolationAnimationT<Scalar>::getAnimation(unsigned int _index ) {
  if ( _index < interpolationAnimations_.size() )
    return interpolationAnimations_[ _index ];
  else 
    return 0;
}

//-----------------------------------------------------------------------------------------------------