Enable cannons to be used in reverse mode.

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11177 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2012-04-29 23:08:50 +00:00
parent e3a1d40588
commit 15ad3f845d
4 changed files with 47 additions and 23 deletions

View File

@@ -32,8 +32,10 @@ const std::string Ipo::m_all_channel_names[IPO_MAX] =
* \param curve The XML node with the IPO data.
* \param fps Frames per second value, necessary to convert frame values
* into time.
* \param reverse If this is set to true, the ipo data will be reverse. This
* is used by the cannon if the track is driven in reverse.
*/
Ipo::IpoData::IpoData(const XMLNode &curve, float fps)
Ipo::IpoData::IpoData(const XMLNode &curve, float fps, bool reverse)
{
if(curve.getName()!="curve")
{
@@ -79,9 +81,9 @@ Ipo::IpoData::IpoData(const XMLNode &curve, float fps)
}
if(m_channel==IPO_LOCXYZ)
readCurve(curve);
readCurve(curve, reverse);
else
readIPO(curve, fps);
readIPO(curve, fps, reverse);
} // IpoData
@@ -89,14 +91,19 @@ Ipo::IpoData::IpoData(const XMLNode &curve, float fps)
/** Reads a blender IPO curve, which constists of a frame number and a control
* point. This only handles a single axis.
* \param node The root node with all curve data points.
* \param fps Frames per second value, necessary to convert the frame based
* data from blender into times.
* \param reverse If this is set, the data are read in reverse. This is used
* for a cannon in reverse mode.
*/
void Ipo::IpoData::readIPO(const XMLNode &curve, float fps)
void Ipo::IpoData::readIPO(const XMLNode &curve, float fps, bool reverse)
{
m_start_time = 999999.9f;
m_end_time = -999999.9f;
for(unsigned int i=0; i<curve.getNumNodes(); i++)
{
const XMLNode *node = curve.getNode(i);
int node_index = reverse ? curve.getNumNodes()-i-1 : i;
const XMLNode *node = curve.getNode(node_index);
core::vector2df xy;
node->get("c", &xy);
// Convert blender's frame number (1 ...) into time (0 ...)
@@ -109,10 +116,10 @@ void Ipo::IpoData::readIPO(const XMLNode &curve, float fps)
{
Vec3 handle1, handle2;
core::vector2df handle;
node->get("h1", &handle);
node->get(reverse ? "h2" : "h1", &handle);
handle1.setW((xy.X-1)/fps);
handle1.setX(handle.Y);
node->get("h2", &handle);
node->get(reverse ? "h1" : "h2", &handle);
handle2.setW((xy.X-1)/fps);
handle2.setX(handle.Y);
m_handle1.push_back(handle1);
@@ -131,8 +138,10 @@ void Ipo::IpoData::readIPO(const XMLNode &curve, float fps)
* which is the deviation of this function is a 2nd degree polynomial, and
* therefore not constant!
* \param node The root node with all curve data points.
* \param reverse If this is set, the data are read in reverse. This is used
* for a cannon in reverse mode.
*/
void Ipo::IpoData::readCurve(const XMLNode &curve)
void Ipo::IpoData::readCurve(const XMLNode &curve, bool reverse)
{
m_start_time = 0;
m_end_time = -999999.9f;
@@ -141,16 +150,17 @@ void Ipo::IpoData::readCurve(const XMLNode &curve)
for(unsigned int i=0; i<curve.getNumNodes(); i++)
{
const XMLNode *node = curve.getNode(i);
int node_index = reverse ? curve.getNumNodes()-i-1 : i;
const XMLNode *node = curve.getNode(node_index);
Vec3 point;
node->get("c", &point);
if(m_interpolation==IP_BEZIER)
{
Vec3 handle;
node->get("h1", &handle);
node->get(reverse ? "h2" : "h1", &handle);
m_handle1.push_back(handle);
node->get("h2", &handle);
node->get(reverse ? "h1" : "h2", &handle);
m_handle2.push_back(handle);
if(i>0)
{
@@ -359,10 +369,12 @@ float Ipo::IpoData::getCubicBezier(float t, float p0, float p1,
* \param curve The XML data for this curve.
* \param fps Frames per second, used to convert all frame based value
* in the xml file into seconds.
* \param reverse If this is set to true, the ipo data will be reverse. This
* is used by the cannon if the track is driven in reverse.
*/
Ipo::Ipo(const XMLNode &curve, float fps)
Ipo::Ipo(const XMLNode &curve, float fps, bool reverse)
{
m_ipo_data = new IpoData(curve, fps);
m_ipo_data = new IpoData(curve, fps, reverse);
m_own_ipo_data = true;
reset();
} // Ipo

View File

@@ -86,9 +86,9 @@ private:
const Vec3 &h0, const Vec3 &h2,
unsigned int rec_level = 0);
public:
IpoData(const XMLNode &curve, float fps);
void readCurve(const XMLNode &node);
void readIPO(const XMLNode &node, float fps);
IpoData(const XMLNode &curve, float fps, bool reverse);
void readCurve(const XMLNode &node, bool reverse);
void readIPO(const XMLNode &node, float fps, bool reverse);
float approximateLength(float t0, float t1,
const Vec3 &p0, const Vec3 &p1,
const Vec3 &h1, const Vec3 &h2);
@@ -115,7 +115,7 @@ private:
Ipo(const Ipo *ipo);
public:
Ipo(const XMLNode &curve, float fps=25);
Ipo(const XMLNode &curve, float fps=25, bool reverse=false);
virtual ~Ipo();
Ipo *clone();
void update(float time, Vec3 *xyz=NULL, Vec3 *hpr=NULL,

View File

@@ -31,7 +31,7 @@
* \param index Index of this check structure in the check manager.
*/
CheckCannon::CheckCannon(const XMLNode &node, unsigned int index)
: CheckLine(node, index)
: CheckLine(node, index)
{
core::vector3df p1, p2;
if(!node.get("target-p1", &p1) ||
@@ -41,7 +41,9 @@ CheckCannon::CheckCannon(const XMLNode &node, unsigned int index)
exit(-1);
}
m_target.setLine(p1, p2);
m_curve = new Ipo(*(node.getNode("curve")));
m_curve = new Ipo(*(node.getNode("curve")),
/*fps*/25,
/*reverse*/race_manager->getReverseTrack());
} // CheckCannon
// ----------------------------------------------------------------------------

View File

@@ -38,9 +38,19 @@ CheckLine::CheckLine(const XMLNode &node, unsigned int index)
// Note that when this is called the karts have not been allocated
// in world, so we can't call world->getNumKarts()
m_previous_sign.resize(race_manager->getNumberOfKarts());
std::string p1_string("p1");
std::string p2_string("p2");
// In case of a cannon in a reverse track, we have to use the target line
// as check line
if(getType()==CT_CANNON && race_manager->getReverseTrack())
{
p1_string = "target-p1";
p2_string = "target-p2";
}
core::vector2df p1, p2;
if(node.get("p1", &p1) &&
node.get("p2", &p2) &&
if(node.get(p1_string, &p1) &&
node.get(p2_string, &p2) &&
node.get("min-height", &m_min_height))
{
m_left_point = Vec3(p1.X, m_min_height, p1.Y);
@@ -48,9 +58,9 @@ CheckLine::CheckLine(const XMLNode &node, unsigned int index)
}
else
{
node.get("p1", &m_left_point);
node.get(p1_string, &m_left_point);
p1 = core::vector2df(m_left_point.getX(), m_left_point.getZ());
node.get("p2", &m_right_point);
node.get(p2_string, &m_right_point);
p2 = core::vector2df(m_right_point.getX(), m_right_point.getZ());
m_min_height = std::min(m_left_point.getY(), m_right_point.getY());
}