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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user