Added support for bezier interpolation.

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3684 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2009-07-01 12:04:26 +00:00
parent 0fffe4c97f
commit d9e90576c7
4 changed files with 46 additions and 36 deletions

View File

@@ -57,22 +57,22 @@ Ipo::Ipo(const XMLNode &curve, float fps)
for(unsigned int i=0; i<curve.getNumNodes(); i++)
{
const XMLNode *node = curve.getNode(i);
Vec3 xy;
node->get2("c", &xy);
core::vector2df xy;
node->get("c", &xy);
// Convert blender's frame number (1 ...) into time (0 ...)
float t = (xy.getX()-1)/fps;
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.setX(t);
xy.X = t;
m_points.push_back(xy);
if(m_interpolation==IP_BEZIER)
{
Vec3 handle;
node->get2("h1", &handle);
handle.setX((xy.getX()-1)/fps);
core::vector2df handle;
node->get("h1", &handle);
handle.X = (xy.X-1)/fps;
m_handle1.push_back(handle);
node->get2("h2", &handle);
handle.setX((xy.getX()-1)/fps);
node->get("h2", &handle);
handle.X = (xy.X-1)/fps;
m_handle2.push_back(handle);
}
} // for i<getNumNodes()
@@ -139,19 +139,29 @@ float Ipo::get() const
// Search for the first point in the (sorted) array which is greater or equal
// to the current time.
// FIXME: we should store the last point to speed this up!
while(n<m_points.size()-1 && m_time >=m_points[n].getX())
while(n<m_points.size()-1 && m_time >=m_points[n].X)
n++;
n--;
switch(m_interpolation)
{
case IP_CONST : return m_points[n].getY();
case IP_CONST : return m_points[n].Y;
case IP_LINEAR : {
float t = m_time-m_points[n].getX();
return m_points[n].getY() + t*(m_points[n+1].getY()-m_points[n].getY()) /
(m_points[n+1].getX()-m_points[n].getX());
float t = m_time-m_points[n].X;
return m_points[n].Y + t*(m_points[n+1].Y-m_points[n].Y) /
(m_points[n+1].X-m_points[n].X);
}
case IP_BEZIER: { // FIXME: for now only:
return m_points[n].getY();
case IP_BEZIER: {
if(n==m_points.size()-1)
{
// FIXME: only const implemented atm.
return m_points[n].Y;
}
core::vector2df c = 3*(m_handle2[n]-m_points[n]);
core::vector2df b = 3*(m_handle1[n+1]-m_handle2[n])-c;
core::vector2df a = m_points[n+1] - m_points[n] - c - b;
float t = (m_time-m_points[n].X)/(m_points[n+1].X-m_points[n].X);
core::vector2df r = ((a*t+b)*t+c)*t+m_points[n];
return r.Y;
}
} // switch
// Keep the compiler happy:

View File

@@ -23,6 +23,9 @@
#include <string>
#include <vector>
#include "irrlicht.h"
using namespace irr;
#include "utils/vec3.hpp"
class XMLNode;
@@ -45,11 +48,10 @@ private:
/** The four extend types. */
enum {ET_CONST, ET_EXTRAP, ET_CYCLIC_EXTRAP, ET_CYCLIC} m_extend;
/** The actual control points. Using Vec3 is a bit of an overkill since
* the IPs are only 2d, but the amount of memory is small anyway. */
std::vector<Vec3> m_points;
/** The actual control points. */
std::vector<core::vector2df> m_points;
/** Only used for bezier curves: the two handles. */
std::vector<Vec3> m_handle1, m_handle2;
std::vector<core::vector2df> m_handle1, m_handle2;
/** Current time in cycle. */
float m_time;

View File

@@ -161,6 +161,19 @@ int XMLNode::get(const std::string &attribute, std::string *value) const
return 1;
} // get
// ----------------------------------------------------------------------------
int XMLNode::get(const std::string &attribute, core::vector2df *value) const
{
std::string s = "";
if(!get(attribute, &s)) return 0;
std::vector<std::string> v = StringUtils::split(s,' ');
if(v.size()!=2) return 0;
value->X = (float)atof(v[0].c_str());
value->Y = (float)atof(v[1].c_str());
return 1;
} // get(vector2df)
// ----------------------------------------------------------------------------
int XMLNode::get(const std::string &attribute, core::vector3df *value) const
{
@@ -189,21 +202,6 @@ int XMLNode::get(const std::string &attribute, Vec3 *value) const
return 1;
} // get(Vec3)
// ----------------------------------------------------------------------------
/** Only reads in a tuple and sets only x and y coordinates. Z is unchanges.
* This is used in reading blender's IPO data. */
int XMLNode::get2(const std::string &attribute, Vec3 *value) const
{
std::string s = "";
if(!get(attribute, &s)) return 0;
std::vector<std::string> v = StringUtils::split(s,' ');
if(v.size()!=2) return 0;
value->setX((float)atof(v[0].c_str()));
value->setY((float)atof(v[1].c_str()));
return 1;
} // get2(Vec3)
// ----------------------------------------------------------------------------
int XMLNode::get(const std::string &attribute, video::SColorf *color) const
{

View File

@@ -53,7 +53,7 @@ public:
int get(const std::string &attribute, float *value) const;
int get(const std::string &attribute, bool *value) const;
int get(const std::string &attribute, Vec3 *value) const;
int get2(const std::string &attribute,Vec3 *value) const;
int get(const std::string &attribute, core::vector2df *value) const;
int get(const std::string &attribute, core::vector3df *value) const;
int get(const std::string &attribute, video::SColorf *value) const;
int get(const std::string &attribute, std::vector<std::string> *value) const;