First proper working version of cannon.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11168 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
a4ba8d2162
commit
02dc97a021
@ -27,18 +27,37 @@
|
|||||||
|
|
||||||
#include "LinearMath/btTransform.h"
|
#include "LinearMath/btTransform.h"
|
||||||
|
|
||||||
CannonAnimation::CannonAnimation(AbstractKart *kart, Ipo *ipo,
|
CannonAnimation::CannonAnimation(AbstractKart *kart, Ipo *ipo)
|
||||||
const Vec3 &delta)
|
|
||||||
: AbstractKartAnimation(kart, "CannonAnimation")
|
: AbstractKartAnimation(kart, "CannonAnimation")
|
||||||
{
|
{
|
||||||
m_curve = new AnimationBase(ipo);
|
m_curve = new AnimationBase(ipo);
|
||||||
m_timer = ipo->getEndTime();
|
m_timer = ipo->getEndTime();
|
||||||
Vec3 xyz = m_kart->getXYZ();
|
|
||||||
Vec3 hpr, scale;
|
// Compute the delta between the kart position and the start of the curve.
|
||||||
// Get the curve position at t=0
|
// This delta is rotated with the kart and added to the interpolated curve
|
||||||
m_curve->update(0, &xyz, &hpr, &scale);
|
// position to get the actual kart position during the animation.
|
||||||
m_offset = m_kart->getXYZ() - xyz-delta;
|
m_curve->update(0, &m_previous_orig_xyz);
|
||||||
m_delta = delta;
|
m_delta = kart->getXYZ() - m_previous_orig_xyz;
|
||||||
|
|
||||||
|
// Now the delta vector needs to be rotated back, so that it will point
|
||||||
|
// in the right direction when it is (in update) rotated to be the same
|
||||||
|
// as the kart's heading. To estimate the angle at the start, use the
|
||||||
|
// interpolated value at t=dt:
|
||||||
|
const float dt = 0.1f;
|
||||||
|
Vec3 xyz1;
|
||||||
|
m_curve->update(dt, &xyz1);
|
||||||
|
core::vector3df rot1 = (xyz1-m_previous_orig_xyz).toIrrVector()
|
||||||
|
.getHorizontalAngle();
|
||||||
|
core::vector3df rot = (m_previous_orig_xyz-xyz1).toIrrVector()
|
||||||
|
.getHorizontalAngle();
|
||||||
|
btQuaternion q(Vec3(0,1,0),rot.Y*DEGREE_TO_RAD);
|
||||||
|
btMatrix3x3 m(q);
|
||||||
|
m_delta = m * m_delta;
|
||||||
|
|
||||||
|
// The previous call to m_curve->update will set the internal timer
|
||||||
|
// of the curve to dt. Reset it to 0 to make sure the timer is in
|
||||||
|
// synch with the timer of the CanonAnimation
|
||||||
|
m_curve->reset();
|
||||||
} // CannonAnimation
|
} // CannonAnimation
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -48,9 +67,10 @@ CannonAnimation::~CannonAnimation()
|
|||||||
float epsilon = 0.5f * m_kart->getKartHeight();
|
float epsilon = 0.5f * m_kart->getKartHeight();
|
||||||
|
|
||||||
btTransform pos;
|
btTransform pos;
|
||||||
pos.setOrigin(m_kart->getXYZ()+btVector3(0, m_kart->getKartHeight() + epsilon,
|
pos.setOrigin(m_kart->getXYZ()
|
||||||
0));
|
+btVector3(0, m_kart->getKartHeight() + epsilon, 0) );
|
||||||
pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f), m_kart->getHeading()));
|
pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f),
|
||||||
|
m_kart->getHeading() ));
|
||||||
|
|
||||||
m_kart->getBody()->setCenterOfMassTransform(pos);
|
m_kart->getBody()->setCenterOfMassTransform(pos);
|
||||||
Vec3 v(0, 0, m_kart->getKartProperties()->getMaxSpeed());
|
Vec3 v(0, 0, m_kart->getKartProperties()->getMaxSpeed());
|
||||||
@ -69,18 +89,26 @@ void CannonAnimation::update(float dt)
|
|||||||
AbstractKartAnimation::update(dt);
|
AbstractKartAnimation::update(dt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Vec3 xyz = m_kart->getXYZ();
|
|
||||||
core::vector3df old_xyz = xyz.toIrrVector();
|
Vec3 xyz;
|
||||||
Vec3 hpr, scale;
|
m_curve->update(dt, &xyz);
|
||||||
m_curve->update(dt, &xyz, &hpr, &scale);
|
|
||||||
|
// It can happen that the same position is returned, e.g. if the end of
|
||||||
|
// the curve is reached, but due to floating point differences the
|
||||||
|
// end is not detected in the above test. To avoid that the kart then
|
||||||
|
// rotates to a heading of 0, do not rotate in this case at all, i.e.
|
||||||
|
// the previous rotation is kept.
|
||||||
|
if(xyz!=m_previous_orig_xyz)
|
||||||
|
{
|
||||||
|
core::vector3df rot = (xyz-m_previous_orig_xyz).toIrrVector()
|
||||||
|
.getHorizontalAngle();
|
||||||
|
btQuaternion q(Vec3(0,1,0),rot.Y*DEGREE_TO_RAD);
|
||||||
|
m_kart->setRotation(q);
|
||||||
|
}
|
||||||
|
m_previous_orig_xyz = xyz;
|
||||||
|
|
||||||
Vec3 rotated_delta = m_kart->getTrans().getBasis()*m_delta;
|
Vec3 rotated_delta = m_kart->getTrans().getBasis()*m_delta;
|
||||||
rotated_delta = Vec3(0,0,0);
|
m_kart->setXYZ(xyz + rotated_delta);
|
||||||
Vec3 new_xyz = xyz+rotated_delta+m_offset;
|
|
||||||
m_kart->setXYZ(new_xyz);
|
|
||||||
|
|
||||||
core::vector3df rot = (new_xyz.toIrrVector()-old_xyz).getHorizontalAngle();
|
|
||||||
btQuaternion q(Vec3(0,1,0),rot.Y*DEGREE_TO_RAD);
|
|
||||||
m_kart->setRotation(q);
|
|
||||||
AbstractKartAnimation::update(dt);
|
AbstractKartAnimation::update(dt);
|
||||||
} // update
|
} // update
|
||||||
|
@ -34,21 +34,21 @@ class Ipo;
|
|||||||
class CannonAnimation: public AbstractKartAnimation
|
class CannonAnimation: public AbstractKartAnimation
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/** The offset between the origin of the curve (relative to which
|
/** This is the difference between the position of the kart when the
|
||||||
* all points are interpolated) and the position of the kart. */
|
* cannon line is crossed and the curve interpolation at t=0. This
|
||||||
Vec3 m_offset;
|
* is added to each interpolated curve value to give the final
|
||||||
|
* kart position (so the kart moves relative to the curve). */
|
||||||
/** An offset that is rotated with the kart and is added to the
|
|
||||||
* interpolated point. This basically shifts the curve (usually)
|
|
||||||
* to the left/right to be aligned with the crossing point of the
|
|
||||||
* kart. */
|
|
||||||
Vec3 m_delta;
|
Vec3 m_delta;
|
||||||
|
|
||||||
/** Stores the curve interpolation for the cannon. */
|
/** Stores the curve interpolation for the cannon. */
|
||||||
AnimationBase *m_curve;
|
AnimationBase *m_curve;
|
||||||
|
|
||||||
|
/** This stores the original (unmodified) interpolated curve value. THis
|
||||||
|
* is used to determine the orientation of the kart. */
|
||||||
|
Vec3 m_previous_orig_xyz;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CannonAnimation(AbstractKart *kart, Ipo *ipo, const Vec3 &delta);
|
CannonAnimation(AbstractKart *kart, Ipo *ipo);
|
||||||
virtual ~CannonAnimation();
|
virtual ~CannonAnimation();
|
||||||
virtual void update(float dt);
|
virtual void update(float dt);
|
||||||
|
|
||||||
|
@ -26,20 +26,6 @@
|
|||||||
#include "modes/world.hpp"
|
#include "modes/world.hpp"
|
||||||
|
|
||||||
|
|
||||||
CheckCannon::CannonCurve::CannonCurve(const XMLNode &node)
|
|
||||||
: AnimationBase(node)
|
|
||||||
{
|
|
||||||
m_speed = -1;
|
|
||||||
node.get("speed", &m_speed);
|
|
||||||
} // CannonCurve
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
void CheckCannon::CannonCurve::update(float dt)
|
|
||||||
{
|
|
||||||
} // update
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
/** Constructor for a check cannon.
|
/** Constructor for a check cannon.
|
||||||
* \param node XML node containing the parameters for this checkline.
|
* \param node XML node containing the parameters for this checkline.
|
||||||
* \param index Index of this check structure in the check manager.
|
* \param index Index of this check structure in the check manager.
|
||||||
@ -49,30 +35,34 @@ CheckCannon::CheckCannon(const XMLNode &node, unsigned int index)
|
|||||||
{
|
{
|
||||||
core::vector3df p1, p2;
|
core::vector3df p1, p2;
|
||||||
if(!node.get("target-p1", &p1) ||
|
if(!node.get("target-p1", &p1) ||
|
||||||
!node.get("target-p2", &p2) )
|
!node.get("target-p2", &p2) )
|
||||||
{
|
{
|
||||||
printf("CheckCannon has no target line specified.\n");
|
printf("CheckCannon has no target line specified.\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
m_target.setLine(p1, p2);
|
m_target.setLine(p1, p2);
|
||||||
m_curve = new Ipo(*(node.getNode("curve")));
|
m_curve = new Ipo(*(node.getNode("curve")));
|
||||||
} // CheckCannon
|
} // CheckCannon
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Destructor, frees the curve data (which the cannon animation objects only
|
||||||
|
* have a read-only copy of).
|
||||||
|
*/
|
||||||
CheckCannon::~CheckCannon()
|
CheckCannon::~CheckCannon()
|
||||||
{
|
{
|
||||||
delete m_curve;
|
delete m_curve;
|
||||||
} // ~CheckCannon
|
} // ~CheckCannon
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Called when the check line is triggered. This function creates a cannon
|
||||||
|
* animation object and attaches it to the kart.
|
||||||
|
* \param kart_index The index of the kart that triggered the check line.
|
||||||
|
*/
|
||||||
void CheckCannon::trigger(unsigned int kart_index)
|
void CheckCannon::trigger(unsigned int kart_index)
|
||||||
{
|
{
|
||||||
Vec3 target(m_target.getMiddle());
|
Vec3 target(m_target.getMiddle());
|
||||||
AbstractKart *kart = World::getWorld()->getKart(kart_index);
|
AbstractKart *kart = World::getWorld()->getKart(kart_index);
|
||||||
if(kart->getKartAnimation()) return;
|
if(kart->getKartAnimation()) return;
|
||||||
|
|
||||||
const core::vector2df &cross = getCrossPoint();
|
new CannonAnimation(kart, m_curve->clone());
|
||||||
const core::line2df &line = getLine2D();
|
|
||||||
Vec3 delta = Vec3(1,0,0) * (line.start-cross).getLength();
|
|
||||||
new CannonAnimation(kart, m_curve->clone(), delta);
|
|
||||||
} // CheckCannon
|
} // CheckCannon
|
||||||
|
@ -38,20 +38,6 @@ private:
|
|||||||
/** The target point the kart will fly to. */
|
/** The target point the kart will fly to. */
|
||||||
core::line3df m_target;
|
core::line3df m_target;
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
protected:
|
|
||||||
class CannonCurve : public AnimationBase
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/** The speed with which the kart moves. */
|
|
||||||
float m_speed;
|
|
||||||
public:
|
|
||||||
CannonCurve(const XMLNode &node);
|
|
||||||
void update(float dt);
|
|
||||||
}; // CannonCurve
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
/** Stores the cannon curve data. */
|
/** Stores the cannon curve data. */
|
||||||
Ipo *m_curve;
|
Ipo *m_curve;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user