1) Added an (additional) impulse to push karts away from each other.

This impulse does not cause any rotation of the kart, it just pushes
the kart orthogonal to its velocity.
2) The rotational velocity is set to 0 in case of a collision, hopefully
avoiding the problem that karts will rotate as result of a collision.
3) A collision pair now stores the exact collision point for both bodies
(which is then used to determine the side in which the impulse to be
applied).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10422 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2011-12-14 21:02:15 +00:00
parent 411fffa55b
commit d06acf1f7b
6 changed files with 210 additions and 131 deletions

View File

@ -289,7 +289,7 @@
the orientation - if a kart is pushed in the direction it is the orientation - if a kart is pushed in the direction it is
driving, it will be more (no friction from tires), while when driving, it will be more (no friction from tires), while when
pushed to the side, hardly anything happens. --> pushed to the side, hardly anything happens. -->
<collision impulse="0" restitution="0.5" side-impulse="0"/> <collision impulse="1500" restitution="0.5" side-impulse="4500"/>
<!-- Kart-specific plunger and rubber band handling: max-length is <!-- Kart-specific plunger and rubber band handling: max-length is
the maximum length of rubber band before it snaps. force is the maximum length of rubber band before it snaps. force is

View File

@ -173,12 +173,12 @@ void RaceState::receive(ENetPacket *pkt)
else else
{ {
// FIXME: KartKartCollision now takes information about the // FIXME: KartKartCollision now takes information about the
// collision point. This either needs to be added as the third // collision points. This either needs to be added as the third
// parameter, or perhaps the outcome of the collision (the // parameter, or perhaps the outcome of the collision (the
// impulse) could be added. // impulse) could be added.
world->getPhysics()->KartKartCollision(world->getKart(kart_id1), world->getPhysics()->KartKartCollision(
world->getKart(kart_id2), world->getKart(kart_id1), Vec3(0,0,0),
btVector3(0,0,0)); world->getKart(kart_id2), Vec3(0,0,0));
} }
} // for(i=0; i<num_collisions; i+=2) } // for(i=0; i<num_collisions; i+=2)
clear(); // free message buffer clear(); // free message buffer

View File

@ -95,20 +95,6 @@ btWheelInfo& btKart::addWheel(const btVector3& connectionPointCS,
m_forwardImpulse.resize(m_wheelInfo.size()); m_forwardImpulse.resize(m_wheelInfo.size());
m_sideImpulse.resize(m_wheelInfo.size()); m_sideImpulse.resize(m_wheelInfo.size());
// The average of all front wheel chassis points define the
// front center. This is always adjusted after adding a wheel
// to avoid calling a separate function just for that.
m_front_center_pointCS = btVector3(0,0,0);
unsigned int count=0;
for(int i=0; i<m_wheelInfo.size(); i++)
{
if(m_wheelInfo[i].m_chassisConnectionPointCS.getZ()>0)
{
m_front_center_pointCS += m_wheelInfo[i].m_chassisConnectionPointCS;
count ++;
}
}
m_front_center_pointCS *= 1.0f/count;
return wheel; return wheel;
} // addWheel } // addWheel

View File

@ -89,9 +89,6 @@ protected:
*/ */
bool m_allow_sliding; bool m_allow_sliding;
/** The center point of the front (in car coordinates). */
btVector3 m_front_center_pointCS;
btRigidBody* m_chassisBody; btRigidBody* m_chassisBody;
int m_num_wheels_on_ground; int m_num_wheels_on_ground;
@ -259,14 +256,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the number of wheels on the ground. */ /** Returns the number of wheels on the ground. */
unsigned int getNumWheelsOnGround() const {return m_num_wheels_on_ground;} unsigned int getNumWheelsOnGround() const {return m_num_wheels_on_ground;}
// ------------------------------------------------------------------------ }; // class btKart
/** Returns the middle point of the front wheel connection points in
* world coordinates. */
btVector3 getFrontCenterPointWS() const
{
return m_chassisBody->getWorldTransform()(m_front_center_pointCS);
} // getFrontCenterPointWS
};
#endif //BT_RAYCASTVEHICLE_H #endif //BT_RAYCASTVEHICLE_H

View File

@ -121,37 +121,39 @@ void Physics::update(float dt)
{ {
// Kart-kart collision // Kart-kart collision
// -------------------- // --------------------
if(p->a->is(UserPointer::UP_KART)) if(p->getUserPointer(0)->is(UserPointer::UP_KART))
{ {
Kart *a=p->a->getPointerKart(); Kart *a=p->getUserPointer(0)->getPointerKart();
Kart *b=p->b->getPointerKart(); Kart *b=p->getUserPointer(1)->getPointerKart();
race_state->addCollision(a->getWorldKartId(), race_state->addCollision(a->getWorldKartId(),
b->getWorldKartId()); b->getWorldKartId());
KartKartCollision(p->a->getPointerKart(), p->b->getPointerKart(), KartKartCollision(p->getUserPointer(0)->getPointerKart(),
p->getContactPoint()); p->getContactPointCS(0),
p->getUserPointer(1)->getPointerKart(),
p->getContactPointCS(1) );
continue; continue;
} // if kart-kart collision } // if kart-kart collision
if(p->a->is(UserPointer::UP_PHYSICAL_OBJECT)) if(p->getUserPointer(0)->is(UserPointer::UP_PHYSICAL_OBJECT))
{ {
// Kart hits physical object // Kart hits physical object
// ------------------------- // -------------------------
PhysicalObject *obj = p->a->getPointerPhysicalObject(); PhysicalObject *obj = p->getUserPointer(0)->getPointerPhysicalObject();
if(obj->isCrashReset()) if(obj->isCrashReset())
{ {
Kart *kart = p->b->getPointerKart(); Kart *kart = p->getUserPointer(1)->getPointerKart();
kart->forceRescue(); kart->forceRescue();
} }
continue; continue;
} }
if(p->a->is(UserPointer::UP_ANIMATION)) if(p->getUserPointer(0)->is(UserPointer::UP_ANIMATION))
{ {
// Kart hits animation // Kart hits animation
ThreeDAnimation *anim=p->a->getPointerAnimation(); ThreeDAnimation *anim=p->getUserPointer(0)->getPointerAnimation();
if(anim->isCrashReset()) if(anim->isCrashReset())
{ {
Kart *kart = p->b->getPointerKart(); Kart *kart = p->getUserPointer(1)->getPointerKart();
kart->forceRescue(); kart->forceRescue();
} }
continue; continue;
@ -159,37 +161,38 @@ void Physics::update(float dt)
} }
// now the first object must be a projectile // now the first object must be a projectile
// ========================================= // =========================================
if(p->b->is(UserPointer::UP_TRACK)) if(p->getUserPointer(1)->is(UserPointer::UP_TRACK))
{ {
// Projectile hits track // Projectile hits track
// --------------------- // ---------------------
p->a->getPointerFlyable()->hitTrack(); p->getUserPointer(0)->getPointerFlyable()->hitTrack();
} }
else if(p->b->is(UserPointer::UP_PHYSICAL_OBJECT)) else if(p->getUserPointer(1)->is(UserPointer::UP_PHYSICAL_OBJECT))
{ {
// Projectile hits physical object // Projectile hits physical object
// ------------------------------- // -------------------------------
p->a->getPointerFlyable() p->getUserPointer(0)->getPointerFlyable()
->hit(NULL, p->b->getPointerPhysicalObject()); ->hit(NULL, p->getUserPointer(1)->getPointerPhysicalObject());
} }
else if(p->b->is(UserPointer::UP_KART)) else if(p->getUserPointer(1)->is(UserPointer::UP_KART))
{ {
// Projectile hits kart // Projectile hits kart
// -------------------- // --------------------
// Only explode a bowling ball if the target is // Only explode a bowling ball if the target is
// not invulnerable // not invulnerable
if(p->a->getPointerFlyable()->getType() if(p->getUserPointer(0)->getPointerFlyable()->getType()
!=PowerupManager::POWERUP_BOWLING || !=PowerupManager::POWERUP_BOWLING ||
!p->b->getPointerKart()->isInvulnerable() ) !p->getUserPointer(1)->getPointerKart()->isInvulnerable() )
p->a->getPointerFlyable()->hit(p->b->getPointerKart()); p->getUserPointer(0)->getPointerFlyable()
->hit(p->getUserPointer(1)->getPointerKart());
} }
else else
{ {
// Projectile hits projectile // Projectile hits projectile
// -------------------------- // --------------------------
p->a->getPointerFlyable()->hit(NULL); p->getUserPointer(0)->getPointerFlyable()->hit(NULL);
p->b->getPointerFlyable()->hit(NULL); p->getUserPointer(1)->getPointerFlyable()->hit(NULL);
} }
} // for all p in m_all_collisions } // for all p in m_all_collisions
} // update } // update
@ -206,6 +209,56 @@ bool Physics::projectKartDownwards(const Kart *k)
/*allow translation*/true); /*allow translation*/true);
} //projectKartsDownwards } //projectKartsDownwards
//-----------------------------------------------------------------------------
/** Determines the side (left, front, ...) of a rigid body with a box
* collision shape that has a given contact point.
* \param body The rigid body (box shape).
* \param contact_point The contact point (in local coordinates) of the
* contact point.
*/
Physics::CollisionSide Physics::getCollisionSide(const btRigidBody *body,
const Vec3 &contact_point)
{
btVector3 aabb_min, aabb_max;
static btTransform zero_trans(btQuaternion(0, 0, 0));
body->getCollisionShape()->getAabb(zero_trans, aabb_min, aabb_max);
btVector3 extend = 0.5f*(aabb_max - aabb_min);
CollisionSide result = COL_LEFT;
if(contact_point.getX()>0) // --> right side
{
if(contact_point.getZ()>0) // --> front or right side
{
result = fabsf(extend.getX() - contact_point.getX()) <
fabsf(extend.getZ() - contact_point.getZ()) ? COL_RIGHT
: COL_FRONT;
}
else // getZ()<0 --> back or right side
{
result = fabsf( extend.getX() - contact_point.getX()) <
fabsf( extend.getZ() + contact_point.getZ()) ? COL_RIGHT
: COL_BACK;
}
}
else // getX() < 0 --> left side
{
if(contact_point.getZ()>0) // --> front or left side
{
result = fabsf(extend.getX() + contact_point.getX()) <
fabsf(extend.getZ() - contact_point.getZ()) ? COL_LEFT
: COL_FRONT;
}
else // --> back or left side
{
result = fabsf(extend.getX() + contact_point.getX()) <
fabsf(extend.getZ() + contact_point.getZ()) ? COL_LEFT
: COL_BACK;
}
}
return result;
} // getCollisionSide
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Handles the special case of two karts colliding with each other, which /** Handles the special case of two karts colliding with each other, which
* means that bombs must be passed on. If both karts have a bomb, they'll * means that bombs must be passed on. If both karts have a bomb, they'll
@ -215,8 +268,8 @@ bool Physics::projectKartDownwards(const Kart *k)
* \param kart_a First kart involved in the collision. * \param kart_a First kart involved in the collision.
* \param kart_b Second kart involved in the collision. * \param kart_b Second kart involved in the collision.
*/ */
void Physics::KartKartCollision(Kart *kart_a, Kart *kart_b, void Physics::KartKartCollision(Kart *kart_a, const Vec3 &contact_point_a,
const Vec3 &contact_point) Kart *kart_b, const Vec3 &contact_point_b)
{ {
kart_a->crashed(kart_b); // will play crash sound for player karts kart_a->crashed(kart_b); // will play crash sound for player karts
kart_b->crashed(kart_a); kart_b->crashed(kart_a);
@ -256,60 +309,80 @@ void Physics::KartKartCollision(Kart *kart_a, Kart *kart_b,
// If bouncing crashes is enabled, add an additional force to the // If bouncing crashes is enabled, add an additional force to the
// slower kart // slower kart
Kart *faster_kart, *slower_kart; Kart *faster_kart, *slower_kart;
Vec3 faster_cp, slower_cp;
if(kart_a->getSpeed()>=kart_b->getSpeed()) if(kart_a->getSpeed()>=kart_b->getSpeed())
{ {
faster_kart = kart_a; faster_kart = kart_a;
faster_cp = contact_point_a;
slower_kart = kart_b; slower_kart = kart_b;
slower_cp = contact_point_b;
} }
else else
{ {
faster_kart = kart_b; faster_kart = kart_b;
faster_cp = contact_point_b;
slower_kart = kart_a; slower_kart = kart_a;
slower_cp = contact_point_a;
} }
Vec3 front_center = faster_kart->getVehicle()->getFrontCenterPointWS(); CollisionSide faster_side = getCollisionSide(faster_kart->getBody(),
float radius = 0.5f*faster_kart->getKartWidth(); faster_cp);
bool frontal_collision = CollisionSide slower_side = getCollisionSide(slower_kart->getBody(),
(contact_point-front_center).length2_2d() < radius*radius; slower_cp);
float side_impulse = // This probably needs adjusting once we have different kart properties.
faster_kart->getKartProperties()->getCollisionSideImpulse(); // E.g. besides speed we might also want to take mass into account(?)
if(!frontal_collision) if(faster_side==COL_FRONT)
{ {
Vec3 diff = faster_kart->getXYZ() - slower_kart->getXYZ(); // Special case: the faster kart hits a kart front on. In this case
// Remove any y component to reduce the chance of karts // the slower kart will be pushed out of the faster kart's way
// toppling over Vec3 dir = faster_kart->getVelocity();
diff.setY(0);
diff = diff.normalize();
float impulse_base = 10.0f;
Vec3 impulse_fast =
slower_kart->getKartProperties()->getCollisionImpulse()*diff;
faster_kart->getBody()->applyCentralImpulse(impulse_fast);
Vec3 impulse_slow =
(-faster_kart->getKartProperties()->getCollisionImpulse())*diff;
slower_kart->getBody()->applyCentralImpulse(impulse_slow);
}
else if(side_impulse>0) // and frontal collision
{
Vec3 forwards_ws(0, 1, 0);
Vec3 forwards = faster_kart->getTrans()*forwards_ws;
core::line2df f(faster_kart->getXYZ().getX(),
faster_kart->getXYZ().getY(),
forwards.getX(), forwards.getY());
core::vector2df p(slower_kart->getXYZ().getX(),
slower_kart->getXYZ().getY());
float orientation=f.getPointOrientation(p); // The direction in which the impulse will be applied depends on
// Now compute the vector to the side (right or left depending // which side of the faster kart was hitting it: if the hit is
// on where the kart was hit). // on the right side of the faster kart, it will push the slower
Vec3 side((orientation>=0) ? -1.0f : 1.0f, 0, 0); // kart to the right and vice versa. This is based on the
float speed_frac = faster_kart->getSpeed()/faster_kart->getCurrentMaxSpeed(); // assumption that a hit to the right indicates that it's
Vec3 impulse = // shorter to push the slower kart to the right.
faster_kart->getTrans().getBasis()*side*side_impulse*speed_frac; Vec3 impulse;
printf("orientation is %f impulse is %f %f %f\n", if(faster_cp.getX()>0)
orientation, impulse.getX(),impulse.getY(),impulse.getZ()); impulse = Vec3( dir.getZ(), 0, -dir.getX());
else
impulse = Vec3(-dir.getZ(), 0, dir.getX());
impulse.normalize();
impulse *= faster_kart->getKartProperties()->getCollisionImpulse();
slower_kart->getBody()->applyCentralImpulse(impulse); slower_kart->getBody()->applyCentralImpulse(impulse);
slower_kart->getBody()->setAngularVelocity(btVector3(0,0,0));
// Apply some impulse to the slower kart as well?
} }
else
{
// Non-frontal collision, push the two karts away from each other
// First the faster kart
Vec3 dir = faster_kart->getVelocity();
Vec3 impulse;
if(faster_cp.getX()>0)
impulse = Vec3(-dir.getZ(), 0, dir.getX());
else
impulse = Vec3( dir.getZ(), 0, -dir.getX());
impulse.normalize();
impulse *= slower_kart->getKartProperties()->getCollisionImpulse();
faster_kart->getBody()->applyCentralImpulse(impulse);
faster_kart->getBody()->setAngularVelocity(btVector3(0,0,0));
// Then the slower kart
dir = slower_kart->getVelocity();
if(slower_cp.getX()>0)
impulse = Vec3(-dir.getZ(), 0, dir.getX());
else
impulse = Vec3( dir.getZ(), 0, -dir.getX());
impulse.normalize();
impulse *= faster_kart->getKartProperties()->getCollisionImpulse();
slower_kart->getBody()->applyCentralImpulse(impulse);
slower_kart->getBody()->setAngularVelocity(btVector3(0,0,0));
}
} // KartKartCollision } // KartKartCollision
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -364,8 +437,9 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
if(upA->is(UserPointer::UP_TRACK)) if(upA->is(UserPointer::UP_TRACK))
{ {
if(upB->is(UserPointer::UP_FLYABLE)) // 1.1 projectile hits track if(upB->is(UserPointer::UP_FLYABLE)) // 1.1 projectile hits track
m_all_collisions.push_back(upB, upA, m_all_collisions.push_back(
contactManifold->getContactPoint(0).getPositionWorldOnA()); upB, contactManifold->getContactPoint(0).m_localPointB,
upA, contactManifold->getContactPoint(0).m_localPointA);
else if(upB->is(UserPointer::UP_KART)) else if(upB->is(UserPointer::UP_KART))
{ {
Kart *kart=upB->getPointerKart(); Kart *kart=upB->getPointerKart();
@ -393,19 +467,23 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
} }
else if(upB->is(UserPointer::UP_FLYABLE)) else if(upB->is(UserPointer::UP_FLYABLE))
// 2.1 projectile hits kart // 2.1 projectile hits kart
m_all_collisions.push_back(upB, upA, m_all_collisions.push_back(
contactManifold->getContactPoint(0).getPositionWorldOnA()); upB, contactManifold->getContactPoint(0).m_localPointB,
upA, contactManifold->getContactPoint(0).m_localPointA);
else if(upB->is(UserPointer::UP_KART)) else if(upB->is(UserPointer::UP_KART))
// 2.2 kart hits kart // 2.2 kart hits kart
m_all_collisions.push_back(upA, upB, m_all_collisions.push_back(
contactManifold->getContactPoint(0).getPositionWorldOnA()); upA, contactManifold->getContactPoint(0).m_localPointA,
upB, contactManifold->getContactPoint(0).m_localPointB);
else if(upB->is(UserPointer::UP_PHYSICAL_OBJECT)) else if(upB->is(UserPointer::UP_PHYSICAL_OBJECT))
// 2.3 kart hits physical object // 2.3 kart hits physical object
m_all_collisions.push_back(upB, upA, m_all_collisions.push_back(
contactManifold->getContactPoint(0).getPositionWorldOnA()); upB, contactManifold->getContactPoint(0).m_localPointB,
upA, contactManifold->getContactPoint(0).m_localPointA);
else if(upB->is(UserPointer::UP_ANIMATION)) else if(upB->is(UserPointer::UP_ANIMATION))
m_all_collisions.push_back(upB, upA, m_all_collisions.push_back(
contactManifold->getContactPoint(0).getPositionWorldOnA()); upB, contactManifold->getContactPoint(0).m_localPointB,
upA, contactManifold->getContactPoint(0).m_localPointA);
} }
// 3) object is a projectile // 3) object is a projectile
// ========================= // =========================
@ -420,8 +498,9 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
upB->is(UserPointer::UP_PHYSICAL_OBJECT) || upB->is(UserPointer::UP_PHYSICAL_OBJECT) ||
upB->is(UserPointer::UP_KART ) ) upB->is(UserPointer::UP_KART ) )
{ {
m_all_collisions.push_back(upA, upB, m_all_collisions.push_back(
contactManifold->getContactPoint(0).getPositionWorldOnA()); upA, contactManifold->getContactPoint(0).m_localPointA,
upB, contactManifold->getContactPoint(0).m_localPointB);
} }
} }
// Object is a physical object // Object is a physical object
@ -429,17 +508,20 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
else if(upA->is(UserPointer::UP_PHYSICAL_OBJECT)) else if(upA->is(UserPointer::UP_PHYSICAL_OBJECT))
{ {
if(upB->is(UserPointer::UP_FLYABLE)) if(upB->is(UserPointer::UP_FLYABLE))
m_all_collisions.push_back(upB, upA, m_all_collisions.push_back(
contactManifold->getContactPoint(0).getPositionWorldOnA()); upB, contactManifold->getContactPoint(0).m_localPointB,
upA, contactManifold->getContactPoint(0).m_localPointA);
else if(upB->is(UserPointer::UP_KART)) else if(upB->is(UserPointer::UP_KART))
m_all_collisions.push_back(upA, upB, m_all_collisions.push_back(
contactManifold->getContactPoint(0).getPositionWorldOnA()); upA, contactManifold->getContactPoint(0).m_localPointA,
upB, contactManifold->getContactPoint(0).m_localPointB);
} }
else if (upA->is(UserPointer::UP_ANIMATION)) else if (upA->is(UserPointer::UP_ANIMATION))
{ {
if(upB->is(UserPointer::UP_KART)) if(upB->is(UserPointer::UP_KART))
m_all_collisions.push_back(upA, upB, m_all_collisions.push_back(
contactManifold->getContactPoint(0).getPositionWorldOnA()); upA, contactManifold->getContactPoint(0).m_localPointA,
upB, contactManifold->getContactPoint(0).m_localPointB);
} }
else assert("Unknown user pointer"); // 4) Should never happen else assert("Unknown user pointer"); // 4) Should never happen
} // for i<numManifolds } // for i<numManifolds

View File

@ -43,6 +43,11 @@ class Vec3;
class Physics : public btSequentialImpulseConstraintSolver class Physics : public btSequentialImpulseConstraintSolver
{ {
private: private:
/** Which side of a rigid body has a collision. */
enum CollisionSide {COL_LEFT, COL_FRONT, COL_RIGHT, COL_BACK};
CollisionSide getCollisionSide(const btRigidBody *body,
const Vec3 &contact_point);
/** Bullet can report the same collision more than once (up to 4 /** Bullet can report the same collision more than once (up to 4
* contact points per collision. Additionally, more than one internal * contact points per collision. Additionally, more than one internal
@ -55,35 +60,51 @@ private:
* Considering that the number of collisions is usually rather small * Considering that the number of collisions is usually rather small
* a simple list and linear search is faster is is being used here. */ * a simple list and linear search is faster is is being used here. */
class CollisionPair { class CollisionPair {
public: private:
/** The user pointer of the objects involved in this collision. */ /** The user pointer of the objects involved in this collision. */
const UserPointer *a, *b; const UserPointer *m_up[2];
/** A contact point of the collision. For now only one of the two /** The contact point for each object (in local coordincates). */
* contact points is needed (since they are close). */ Vec3 m_contact_point[2];
Vec3 m_contact_point;
public:
/** The entries in Collision Pairs are sorted: if a projectile /** The entries in Collision Pairs are sorted: if a projectile
* is included, it's always 'a'. If only two karts are reported * is included, it's always 'a'. If only two karts are reported
* the first kart pointer is the smaller one. */ * the first kart pointer is the smaller one. */
CollisionPair(const UserPointer *a1, const UserPointer *b1, CollisionPair(const UserPointer *a, const btVector3 &contact_point_a,
const btVector3 &contact_point) { const UserPointer *b, const btVector3 &contact_point_b)
if(a1->is(UserPointer::UP_KART) && {
b1->is(UserPointer::UP_KART) && a1>b1) { if(a->is(UserPointer::UP_KART) &&
a=b1;b=a1; b->is(UserPointer::UP_KART) && a>b) {
m_up[0]=b; m_contact_point[0] = contact_point_b;
m_up[1]=a; m_contact_point[1] = contact_point_a;
} else { } else {
a=a1; b=b1; m_up[0]=a; m_contact_point[0] = contact_point_a;
m_up[1]=b; m_contact_point[1] = contact_point_b;
} }
m_contact_point = contact_point;
}; // CollisionPair }; // CollisionPair
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Tests if two collision pairs involve the same objects. This test /** Tests if two collision pairs involve the same objects. This test
* is simplified (i.e. no test if p.b==a and p.a==b) since the * is simplified (i.e. no test if p.b==a and p.a==b) since the
* elements are sorted. */ * elements are sorted. */
bool operator==(const CollisionPair p) {return (p.a==a && p.b==b);} bool operator==(const CollisionPair p)
{
return (p.m_up[0]==m_up[0] && p.m_up[1]==m_up[1]);
} // operator==
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Returns the contact point of the collision. */ const UserPointer *getUserPointer(unsigned int n) const
const Vec3 &getContactPoint() const { return m_contact_point; } {
assert(n>=0 && n<=1);
return m_up[n];
} // getUserPointer
// --------------------------------------------------------------------
/** Returns the contact point of the collision in
* car (local) coordinates. */
const Vec3 &getContactPointCS(unsigned int n) const
{
assert(n>=0 && n<=1);
return m_contact_point[n];
} // getContactPointCS
}; // CollisionPair }; // CollisionPair
// ======================================================================== // ========================================================================
@ -101,10 +122,10 @@ private:
}; // push_back }; // push_back
public: public:
/** Adds information about a collision to this vector. */ /** Adds information about a collision to this vector. */
void push_back(const UserPointer* a, const UserPointer*b, void push_back(const UserPointer *a, const btVector3 &contact_point_a,
const btVector3 &contact_point) const UserPointer *b, const btVector3 &contact_point_b)
{ {
push_back(CollisionPair(a, b, contact_point)); push_back(CollisionPair(a, contact_point_a, b, contact_point_b));
} }
}; // CollisionList }; // CollisionList
// ======================================================================== // ========================================================================
@ -127,8 +148,8 @@ public:
void addBody (btRigidBody* b) {m_dynamics_world->addRigidBody(b);} void addBody (btRigidBody* b) {m_dynamics_world->addRigidBody(b);}
void removeKart (const Kart *k); void removeKart (const Kart *k);
void removeBody (btRigidBody* b) {m_dynamics_world->removeRigidBody(b);} void removeBody (btRigidBody* b) {m_dynamics_world->removeRigidBody(b);}
void KartKartCollision(Kart *ka, Kart *kb, void KartKartCollision(Kart *ka, const Vec3 &contact_point_a,
const Vec3 &contact_point); Kart *kb, const Vec3 &contact_point_b);
void update (float dt); void update (float dt);
void draw (); void draw ();
STKDynamicsWorld* STKDynamicsWorld*