Developer Documentation
InterpolationAnimationT.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 #define INTERPOLATIONANIMATIONT_C
51 
52 #include "AnimationT.hh"
53 
54 #include <vector>
55 #include <cassert>
56 #include <cmath>
57 //-----------------------------------------------------------------------------------------------------
58 
67 template<class PointT>
69  AnimationT<PointT>(_other.name_),
70  skeleton_(_other.skeleton_),
71  matrixManipulator_(_other.matrixManipulator_),
72  frames_(0)
73 {
74 
75 }
76 
77 //-----------------------------------------------------------------------------------------------------
78 
85 template<class PointT>
87  skeleton_(_skeleton),
88  matrixManipulator_(_matrixManipulator),
89  frames_(0)
90 {
91 
92 }
93 
94 //-----------------------------------------------------------------------------------------------------
95 
96 template<class PointT>
98 {
99  clearPoseCache();
100 }
101 
102 //-----------------------------------------------------------------------------------------------------
103 
104 template<class PointT>
106  return new InterpolationAnimationT<PointT>(*this);
107 }
108 
109 //-----------------------------------------------------------------------------------------------------
110 
111 template<class PointT>
113 {
114  return pose(_iFrame, skeleton_->referencePose());
115 }
116 
117 //-----------------------------------------------------------------------------------------------------
118 
119 template<class PointT>
120 PoseT<PointT>* InterpolationAnimationT<PointT>::pose(unsigned int _iFrame, Pose* _reference)
121 {
122 // std::cerr << "Frame " << _iFrame << ": ";
123 
124  if (interpolatedPoses_.find(_iFrame) != interpolatedPoses_.end()) {
125 // std::cerr << "(from cache)" << std::endl;
126  return (interpolatedPoses_[_iFrame]);
127  } else {
128 
129  if (_iFrame == 0) {
130  interpolatedPoses_.insert( std::make_pair(0, new Pose(*_reference)) );
131 // std::cerr << "Insert reference to posecache. &_reference: " << _reference << ", &cacheref: " << getPose(_iFrame, _reference) << std::endl;
132  return pose(_iFrame, _reference);
133  } else {
134  //Find the correct interpolator
135  Interpolator* interpolator = NULL;
136  unsigned long min = 0;
137 
138  uint i;
139  for (i=0; i<interpolators_.size(); ++i) {
140  min = (i==0 ? 0.0 : calcAbsoluteMaxForInterpolator(i-1) + 1);
141  const unsigned long max = calcAbsoluteMaxForInterpolator(i);
142  if (_iFrame >= min && _iFrame <= max) {
143  interpolator = interpolators_[i];
144  break;
145  }
146  }
147 
148  if (interpolator == NULL) {
149 // std::cerr << "No appropriate interpolator found for this frame!" << std::endl;
150  return _reference;
151  }
152 
153 // std::cerr << "Using interpolator " << i << " - ";
154 
155  //Create a new pose that is a copy of the reference and apply the interpolated transformations to it
156  Pose *generatedPose = new Pose(*_reference);
157 
158  for (uint i=0; i<influencedJoints_.size(); ++i) {
159  ACG::GLMatrixT<Scalar> transformation(generatedPose->globalMatrix(influencedJoints_[i]).raw());
160  //The frames for each interpolator are stored from 0..max, i.e. in "interpolator local time space".
161  // So, they have to be mapped to the global space here.
162  TargetType precalcVal = precalculations_[interpolator][_iFrame - min];
163 
164  matrixManipulator_->doManipulation(transformation, precalcVal);
165  generatedPose->setGlobalMatrix(influencedJoints_[i], transformation, false);
166  }
167 
168 // std::cerr << std::endl;
169 
170  interpolatedPoses_.insert(std::pair<unsigned long, Pose*>(_iFrame, generatedPose));
171  return (interpolatedPoses_.find(_iFrame)->second);
172  }
173 
174 
175  }
176 }
177 
178 //-----------------------------------------------------------------------------------------------------
179 
180 template<class PointT>
182 {
183  return frames_;
184 }
185 
186 //-----------------------------------------------------------------------------------------------------
187 
188 template<class PointT>
190 {
191  //NOOP
192 }
193 
194 //-----------------------------------------------------------------------------------------------------
195 
196 
197 template<class PointT>
199 {
200  //NOOP
201 }
202 
203 //-----------------------------------------------------------------------------------------------------
204 
213 template<class PointT>
215 {
216  //NOOP
217 }
218 
219 //-----------------------------------------------------------------------------------------------------
220 
221 template<class PointT>
223  if (_interpolator == NULL)
224  return;
225 
226  interpolators_.push_back(_interpolator);
227 // std::cerr << "Precalc for interpolator " << interpolators_.size()-1 << ":" << std::endl;
228 
229  std::vector < TargetType > valueVector;
230 
231  //Precalc values for this interpolator
232  uint i=0;
233  for (i=_interpolator->getMinInput()*FPS;i<=(_interpolator->getMaxInput()) * FPS;++i) {
234  TargetType precalcValue;
235  double input = ((double)i) / ((double)FPS);
236  precalcValue = _interpolator->getValue(input);
237  valueVector.push_back(precalcValue);
238 
239 // std::cerr << "Frame " << i << "(t=" << input << "): " << precalcValue[0] << std::endl;
240  }
241 
242 // std::cerr << std::endl;
243 
244  precalculations_.insert( std::pair< Interpolator*, std::vector < TargetType > >(_interpolator, valueVector) );
245 
246  frames_ = std::max<long unsigned int>(frames_, i+1);
247 }
248 
249 //-----------------------------------------------------------------------------------------------------
250 
251 template<class PointT>
254 {
255  if ( _index < interpolators_.size() )
256  return interpolators_[ _index ];
257  else
258  return 0;
259 }
260 
261 //-----------------------------------------------------------------------------------------------------
262 
263 template<class PointT>
265 {
266  return interpolators_.size();
267 }
268 
269 //-----------------------------------------------------------------------------------------------------
270 
274 template<class PointT>
276  assert (_index < interpolators_.size());
277 
278  if (_index == 0) {
279  return precalculations_[interpolators_[_index]].size() - 1;
280  } else {
281  return precalculations_[interpolators_[_index]].size() + calcAbsoluteMaxForInterpolator(_index - 1);
282  }
283 }
284 
285 //-----------------------------------------------------------------------------------------------------
286 
287 template<class PointT>
288 bool InterpolationAnimationT<PointT>::getMinInput(Scalar& _result) {
289  if (interpolators_.size() == 0)
290  return false;
291  else
292  _result = interpolators_[0]->getMinInput();
293 
294  for (uint i=0;i<interpolators_.size();++i) {
295  if (interpolators_[i]->getMinInput() < _result)
296  _result = interpolators_[i]->getMinInput();
297  }
298 
299  return true;
300 }
301 
302 //-----------------------------------------------------------------------------------------------------
303 
304 template<class PointT>
305 bool InterpolationAnimationT<PointT>::getMaxInput(Scalar& _result) {
306  if (interpolators_.size() == 0)
307  return false;
308  else
309  _result = interpolators_[0]->getMaxInput();
310 
311  for (uint i=0;i<interpolators_.size();++i) {
312  if (interpolators_[i]->getMaxInput() > _result)
313  _result = interpolators_[i]->getMaxInput();
314  }
315 
316  return true;
317 }
318 
319 //-----------------------------------------------------------------------------------------------------
320 
321 template<class PointT>
323  for (uint i=0; i<influencedJoints_.size(); ++i)
324  if ( influencedJoints_[i] == _joint )
325  return true;
326 
327  return false;
328 }
329 
330 //-----------------------------------------------------------------------------------------------------
331 
332 template<class PointT>
334  return influencedJoints_;
335 }
336 
337 //-----------------------------------------------------------------------------------------------------
338 
virtual void doManipulation(GLMatrixT &_matrix, std::vector< Scalar > _value)=0
Interpolator * interpolator(unsigned int _index)
Get the i-th interpolator.
unsigned int interpolatorCount()
Get the number of interpolators.
virtual void removeJointAt(unsigned int _index)
Called by the skeleton as a joint is deleted.
const Matrix & globalMatrix(unsigned int _joint) const
Returns the global matrix for the given joint.
Definition: PoseT.cc:199
unsigned int frameCount()
Returns the number of frames stored in this pose.
A general pose, used to store the frames of the animation.
Definition: PoseT.hh:68
Knows how to apply the values generated by an interpolator to a matrix. When playing back an Interpol...
virtual void insertJointAt(unsigned int _index)
Called by the skeleton as a new joint is inserted.
virtual void updateFromGlobal(unsigned int _index)
Updates the local matrix using the global matrix.
void addInterpolator(InterpolationT< double > *_interpolator)
Add an interpolator.
4x4 matrix implementing OpenGL commands.
Definition: GLMatrixT.hh:85
unsigned int calcAbsoluteMaxForInterpolator(uint _index)
Calculates the last frame that interpolator _index is responsible for.
Stores a single animation.
Definition: AnimationT.hh:67
InterpolationAnimationT(const InterpolationAnimationT< PointT > &_other)
Copy constructor.
virtual Pose * pose(unsigned int _iFrame)
Returns a pointer to the pose calculated for the given frame.
void setGlobalMatrix(unsigned int _joint, const Matrix &_global, bool _keepGlobalChildPositions=true)
Sets the global coordinate system.
Definition: PoseT.cc:217
Pose * referencePose()
Returns a pointer to the reference pose.
Definition: SkeletonT.cc:761