Simplified maths.
This commit is contained in:
parent
2436161b05
commit
bedb565f24
@ -35,76 +35,66 @@ CannonAnimation::CannonAnimation(AbstractKart *kart, Ipo *ipo,
|
|||||||
m_curve = new AnimationBase(ipo);
|
m_curve = new AnimationBase(ipo);
|
||||||
m_timer = ipo->getEndTime();
|
m_timer = ipo->getEndTime();
|
||||||
|
|
||||||
float kw2 = m_kart->getKartModel()->getWidth()*0.5f;
|
|
||||||
|
|
||||||
// First make sure that left and right points are indeed correct
|
// First make sure that left and right points are indeed correct
|
||||||
|
// -------------------------------------------------------------
|
||||||
Vec3 my_start_left = start_left;
|
Vec3 my_start_left = start_left;
|
||||||
Vec3 my_start_right = start_right;
|
Vec3 my_start_right = start_right;
|
||||||
Vec3 p0, p1;
|
Vec3 p0, p1;
|
||||||
|
// Define a plane that goes through the middle of the start line
|
||||||
|
// (the curve's origin must be in the middle of the line.
|
||||||
m_curve->getAt(0, &p0);
|
m_curve->getAt(0, &p0);
|
||||||
m_curve->getAt(0.1f, &p1);
|
m_curve->getAt(0.1f, &p1);
|
||||||
Vec3 p2 = 0.5f*(p0 + p1) + m_kart->getNormal();
|
Vec3 p2 = 0.5f*(p0 + p1) + m_kart->getNormal();
|
||||||
if (start_left.sideofPlane(p0, p1, p2) < 0)
|
if (start_left.sideofPlane(p0, p1, p2) < 0)
|
||||||
{
|
{
|
||||||
|
// Left and right start line needs to be swapped
|
||||||
my_start_left = start_right;
|
my_start_left = start_right;
|
||||||
my_start_right = start_left;
|
my_start_right = start_left;
|
||||||
}
|
}
|
||||||
|
|
||||||
// First adjust start and end points to take on each side half the kart
|
// First adjust start and end points to take on each side half the kart
|
||||||
// width into account:
|
// width into account:
|
||||||
Vec3 direction = my_start_right - my_start_left;
|
Vec3 direction = my_start_right - my_start_left;
|
||||||
direction.normalize();
|
direction.normalize();
|
||||||
|
|
||||||
Vec3 adj_start_left = my_start_left + kw2 * direction;
|
float kw = m_kart->getKartModel()->getWidth();
|
||||||
Vec3 adj_start_right = my_start_right - kw2 * direction;
|
Vec3 adj_start_left = my_start_left + (0.5f*kw) * direction;
|
||||||
|
Vec3 adj_start_right = my_start_right - (0.5f*kw) * direction;
|
||||||
|
|
||||||
// Same adjustments for end points
|
// Store the length of the start and end line, which is used
|
||||||
float t = m_curve->getAnimationDuration();
|
// during update() to adjust the distance to center
|
||||||
Vec3 my_end_left = end_left;
|
m_start_line_length = (adj_start_left - adj_start_right).length();
|
||||||
Vec3 my_end_right = end_right;
|
m_end_line_length = (end_left - end_right).length() - kw;
|
||||||
m_curve->getAt(t-0.1f, &p0);
|
|
||||||
m_curve->getAt(t, &p1);
|
|
||||||
p2 = 0.5f*(p0 + p1) + m_kart->getNormal();
|
|
||||||
if (end_left.sideofPlane(p0, p1, p2) < 0)
|
|
||||||
{
|
|
||||||
my_end_left = end_right;
|
|
||||||
my_end_right = end_left;
|
|
||||||
}
|
|
||||||
// Left and right end points are sometimes swapped
|
|
||||||
direction = my_end_right - my_end_left;
|
|
||||||
direction.normalize();
|
|
||||||
|
|
||||||
Vec3 adj_end_left = my_end_left + kw2 * direction;
|
// The current kart position is divided into three components:
|
||||||
Vec3 adj_end_right = my_end_right - kw2 * direction;
|
// kart.xyz = curve.xyz + parallel_to_start_line_component + rest
|
||||||
|
// 1) curve.xyz: The point at the curve at t=0.
|
||||||
// The kart position is divided into three components:
|
// 2) parallel_to_start_line_component:
|
||||||
// 1) The point at the curve at t=0.
|
// A component parallel to the start line. This component is scaled
|
||||||
// 2) A component parallel to the start line. This component is scaled
|
// depending on time and length of start- and end-line (e.g. if the
|
||||||
// depending on time, length of start- and end-line (e.g. if the
|
|
||||||
// end line is twice as long as the start line, this will make sure
|
// end line is twice as long as the start line, this will make sure
|
||||||
// that a kart starting at the very left of the start line will end
|
// that a kart starting at the very left of the start line will end
|
||||||
// up at the very left of the end line. This component can also be
|
// up at the very left of the end line). This component can also be
|
||||||
// adjusted by steering while in the air. This is done by modifying
|
// adjusted by steering while in the air. This is done by modifying
|
||||||
// m_fraction_of_line, which is multiplied with the current width
|
// m_fraction_of_line, which is multiplied with the current width
|
||||||
// vector.
|
// vector.
|
||||||
// 3) The rest, i.e. the amoount that the kart is ahead and above the
|
// 3) rest: The amoount that the kart is ahead and above the
|
||||||
// start line. This is stored in m_delta.
|
// start line. This is stored in m_delta and will be added to the
|
||||||
|
// newly computed curve xyz coordinates.
|
||||||
//
|
//
|
||||||
// Compute the delta between the kart position and the start of the curve.
|
// Compute the delta between the kart position and the start of the curve.
|
||||||
// This delta is rotated with the kart and added to the interpolated curve
|
// This delta is rotated with the kart and added to the interpolated curve
|
||||||
// position to get the actual kart position during the animation.
|
// position to get the actual kart position during the animation.
|
||||||
|
|
||||||
Vec3 curve_xyz;
|
Vec3 curve_xyz;
|
||||||
m_curve->update(0, &curve_xyz);
|
m_curve->update(0, &curve_xyz);
|
||||||
m_delta = kart->getXYZ() - curve_xyz;
|
m_delta = kart->getXYZ() - curve_xyz;
|
||||||
|
|
||||||
m_start_line = 0.5f*(adj_start_right - adj_start_left);
|
// Compute on which fraction of the start line the kart is, to get the
|
||||||
m_end_line = 0.5f*(adj_end_right - adj_end_left );
|
// second component of the kart position: distance along start line
|
||||||
|
|
||||||
Vec3 v = adj_start_left - adj_start_right;
|
Vec3 v = adj_start_left - adj_start_right;
|
||||||
float l = v.length();
|
float l = v.length();
|
||||||
v /= l;
|
v /= l;
|
||||||
|
|
||||||
// Compute on which fraction of the start line the kart is
|
|
||||||
float f = v.dot(adj_start_left - kart->getXYZ());
|
float f = v.dot(adj_start_left - kart->getXYZ());
|
||||||
if (f <= 0)
|
if (f <= 0)
|
||||||
f = 0;
|
f = 0;
|
||||||
@ -112,11 +102,14 @@ CannonAnimation::CannonAnimation(AbstractKart *kart, Ipo *ipo,
|
|||||||
f = l;
|
f = l;
|
||||||
else
|
else
|
||||||
f = f / l;
|
f = f / l;
|
||||||
// Now f is in [0,1]. Convert it to [-1,1] assuming that the
|
// Now f is in [0,1] - 0 in case of left side, 1 if the kart is at the
|
||||||
// ipo for the cannon is in the middle of the start and end line
|
// very right. Convert this to [-1,1] assuming that the ipo for the
|
||||||
|
// cannon is in the middle of the start and end line
|
||||||
m_fraction_of_line = 2.0f*f - 1.0f;
|
m_fraction_of_line = 2.0f*f - 1.0f;
|
||||||
|
|
||||||
Vec3 delta = m_start_line * m_fraction_of_line;
|
Vec3 delta = 0.5f*m_fraction_of_line * (adj_start_right - adj_start_left);
|
||||||
|
// Subtract the horizontal difference, to get the constant offset the
|
||||||
|
// kart has from the curve.
|
||||||
m_delta = m_delta - delta;
|
m_delta = m_delta - delta;
|
||||||
|
|
||||||
// The previous call to m_curve->update will set the internal timer
|
// The previous call to m_curve->update will set the internal timer
|
||||||
@ -154,21 +147,14 @@ void CannonAnimation::update(float dt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the horizontal location based on steering
|
// First compute the current rotation
|
||||||
m_fraction_of_line += m_kart->getSteerPercent()*dt*2.0f;
|
// -----------------------------------
|
||||||
|
|
||||||
// The timer count backwards, so the fraction goes from 1 to 0
|
|
||||||
float f = m_timer / m_curve->getAnimationDuration();
|
|
||||||
|
|
||||||
btClamp(m_fraction_of_line, -1.0f, 1.0f);
|
|
||||||
Vec3 current_width = m_start_line * f + m_end_line * (1.0f - f);
|
|
||||||
|
|
||||||
// Get the tangent = derivative at the current point to compute the
|
// Get the tangent = derivative at the current point to compute the
|
||||||
// orientation of the kart
|
// new orientation of the kart
|
||||||
Vec3 tangent;
|
Vec3 tangent;
|
||||||
m_curve->getDerivativeAt(m_curve->getAnimationDuration() - m_timer,
|
m_curve->getDerivativeAt(m_curve->getAnimationDuration() - m_timer,
|
||||||
&tangent);
|
&tangent);
|
||||||
|
// Get the current kart orientation
|
||||||
Vec3 forward = m_kart->getTrans().getBasis().getColumn(2);
|
Vec3 forward = m_kart->getTrans().getBasis().getColumn(2);
|
||||||
forward.normalize();
|
forward.normalize();
|
||||||
|
|
||||||
@ -180,13 +166,26 @@ void CannonAnimation::update(float dt)
|
|||||||
|
|
||||||
m_kart->setRotation(q);
|
m_kart->setRotation(q);
|
||||||
|
|
||||||
Vec3 xyz;
|
// Then compute the new location of the kart
|
||||||
m_curve->update(dt, &xyz);
|
// -----------------------------------------
|
||||||
|
// The timer counts backwards, so the fraction goes from 1 to 0
|
||||||
|
float f = m_timer / m_curve->getAnimationDuration();
|
||||||
|
float f_current_width = m_start_line_length * f
|
||||||
|
+ m_end_line_length * (1.0f - f);
|
||||||
|
|
||||||
Vec3 rotated_delta = quatRotate(q, m_delta ) + current_width * m_fraction_of_line;
|
// Adjust the horizontal location based on steering
|
||||||
m_kart->setXYZ(xyz+rotated_delta);
|
m_fraction_of_line += m_kart->getSteerPercent()*dt*2.0f;
|
||||||
// m_kart->setXYZ(xyz);
|
btClamp(m_fraction_of_line, -1.0f, 1.0f);
|
||||||
|
|
||||||
|
// horiz_delta is in kart coordinates, the rotation by q will
|
||||||
|
// transform it to the global coordinate system
|
||||||
|
Vec3 horiz_delta = Vec3(0.5f*m_fraction_of_line * f_current_width, 0, 0);
|
||||||
|
|
||||||
|
Vec3 rotated_delta = quatRotate(q, m_delta + horiz_delta);
|
||||||
|
|
||||||
|
Vec3 curve_xyz;
|
||||||
|
m_curve->update(dt, &curve_xyz);
|
||||||
|
m_kart->setXYZ(curve_xyz+rotated_delta);
|
||||||
|
|
||||||
AbstractKartAnimation::update(dt);
|
AbstractKartAnimation::update(dt);
|
||||||
} // update
|
} // update
|
||||||
|
@ -46,11 +46,13 @@ protected:
|
|||||||
/** Stores the curve interpolation for the cannon. */
|
/** Stores the curve interpolation for the cannon. */
|
||||||
AnimationBase *m_curve;
|
AnimationBase *m_curve;
|
||||||
|
|
||||||
/** The original checkline at start. */
|
/** Length of the (adjusted, i.e. taking kart width into account)
|
||||||
Vec3 m_start_line;
|
* start line. */
|
||||||
|
float m_start_line_length;
|
||||||
|
|
||||||
/** The original checkline at end. */
|
/** Length of the (adjusted, i.e. taking kart width into account)
|
||||||
Vec3 m_end_line;
|
* end line. */
|
||||||
|
float m_end_line_length;
|
||||||
|
|
||||||
/** Stores the position of the kart relative to the line width
|
/** Stores the position of the kart relative to the line width
|
||||||
* at the current location. */
|
* at the current location. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user