Fixed bug 393, channels in IPO animation get out of sync

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9587 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria
2011-08-21 17:27:05 +00:00
parent d40416f6a8
commit da87d76f1c
4 changed files with 78 additions and 21 deletions

View File

@@ -24,6 +24,8 @@
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
#include <algorithm>
AnimationBase::AnimationBase(const XMLNode &node)
: TrackObject(node)
{
@@ -33,19 +35,38 @@ AnimationBase::AnimationBase(const XMLNode &node)
{
Ipo *ipo = new Ipo(*node.getNode(i), fps);
m_all_ipos.push_back(ipo);
} // for i<getNumNodes()
}
// extend all IPOs to add at the same point
float last_x = -1;
Ipo* curr;
for_in (curr, m_all_ipos)
{
const std::vector<core::vector2df>& points = curr->getPoints();
last_x = std::max(last_x, points[points.size() - 1].X);
}
if (last_x > -1)
{
for_in (curr, m_all_ipos)
{
const std::vector<core::vector2df>& points = curr->getPoints();
if (points[points.size() - 1].X < last_x)
{
curr->extendTo(last_x);
}
}
}
m_playing = true;
} // AnimationBase
// ----------------------------------------------------------------------------
/** Removes all IPOs.
*/
AnimationBase::~AnimationBase()
{
std::vector<Ipo*>::iterator i;
for(i=m_all_ipos.begin(); i<m_all_ipos.end(); i++)
delete *i;
m_all_ipos.clear();
} // ~AnimationBase
// ----------------------------------------------------------------------------
@@ -57,11 +78,11 @@ AnimationBase::~AnimationBase()
void AnimationBase::setInitialTransform(const core::vector3df &xyz,
const core::vector3df &hpr)
{
std::vector<Ipo*>::iterator i;
for(i=m_all_ipos.begin(); i<m_all_ipos.end(); i++)
Ipo* curr;
for_in (curr, m_all_ipos)
{
(*i)->setInitialTransform(xyz, hpr);
} // for i in m_all_ipos
curr->setInitialTransform(xyz, hpr);
}
} // setTransform
// ----------------------------------------------------------------------------
@@ -69,11 +90,11 @@ void AnimationBase::setInitialTransform(const core::vector3df &xyz,
*/
void AnimationBase::reset()
{
std::vector<Ipo*>::iterator i;
for(i=m_all_ipos.begin(); i<m_all_ipos.end(); i++)
Ipo* curr;
for_in (curr, m_all_ipos)
{
(*i)->reset();
} // for i in m_all_ipos
curr->reset();
}
} // reset
// ----------------------------------------------------------------------------
@@ -85,10 +106,9 @@ void AnimationBase::reset()
void AnimationBase::update(float dt, core::vector3df *xyz,
core::vector3df *hpr, core::vector3df *scale)
{
std::vector<Ipo*>::iterator i;
for(i=m_all_ipos.begin(); i<m_all_ipos.end(); i++)
Ipo* curr;
for_in (curr, m_all_ipos)
{
(*i)->update(dt, xyz, hpr, scale);
} // for i in m_all_ipos
curr->update(dt, xyz, hpr, scale);
}
} // float dt

View File

@@ -30,6 +30,7 @@
using namespace irr;
#include "tracks/track_object.hpp"
#include "utils/ptr_vector.hpp"
class XMLNode;
class Ipo;
@@ -64,7 +65,7 @@ private:
core::vector3df m_initial_hpr;
protected:
/** All IPOs for this animation. */
std::vector<Ipo*> m_all_ipos;
PtrVector<Ipo> m_all_ipos;
public:
AnimationBase(const XMLNode &node);

View File

@@ -62,6 +62,7 @@ Ipo::Ipo(const XMLNode &curve, float fps)
node->get("c", &xy);
// Convert blender's frame number (1 ...) into time (0 ...)
float t = (xy.X-1)/fps;
if(t<m_min_time) m_min_time = t;
if(t>m_max_time) m_max_time = t;
xy.X = t;
@@ -180,4 +181,33 @@ float Ipo::get() const
// Keep the compiler happy:
return 0;
} // get
// ----------------------------------------------------------------------------
/** Extends the IPO to end at the given x time coordinate */
void Ipo::extendTo(float x)
{
switch (m_interpolation)
{
case IP_CONST:
{
m_points.push_back( core::vector2df(x, m_points[m_points.size()-1].Y) );
break;
}
case IP_LINEAR:
{
m_points.push_back( core::vector2df(x, m_points[m_points.size()-1].Y) );
break;
}
case IP_BEZIER:
{
// FIXME: I'm somewhat dubious this is the correct way to extend handles
m_handle1.push_back( m_handle1[m_handle1.size() - 1] + core::vector2df(x - m_points[m_points.size()-1].X ,0) );
m_handle2.push_back( m_handle2[m_handle2.size() - 1] + core::vector2df(x - m_points[m_points.size()-1].X ,0) );
m_points.push_back( core::vector2df(x, m_points[m_points.size()-1].Y) );
break;
}
}
m_max_time = x;
}

View File

@@ -82,6 +82,12 @@ public:
void setInitialTransform(const core::vector3df &xyz,
const core::vector3df &hpr);
void reset();
void extendTo(float x);
const std::vector<core::vector2df>& getPoints() const { return m_points; }
}; // Ipo
#endif