1) Added an additional impulse to push karts away in case of a collision (unused atm)
2) Saved one collision point for each collision pair so that a frontal detection can be detected (atm unused). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10407 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
6a9b401d6e
commit
8ab469d4d8
@ -277,7 +277,10 @@
|
|||||||
<!-- Parameters for the upright constraint, which keeps karts upright. -->
|
<!-- Parameters for the upright constraint, which keeps karts upright. -->
|
||||||
<upright tolerance="0.2" max-force="30"/>
|
<upright tolerance="0.2" max-force="30"/>
|
||||||
|
|
||||||
<!-- collision-side-impulse is an additional (artificial) impulse that
|
<!-- collision
|
||||||
|
impulse: an additional impulse to be applied in a non-frontal
|
||||||
|
collision to push two karts away from each other.
|
||||||
|
side-impulse is an additional (artificial) impulse that
|
||||||
pushes the slower kart out of the way of the faster karts (i.e.
|
pushes the slower kart out of the way of the faster karts (i.e.
|
||||||
sideways to the faster kart) when a collision happens. This is
|
sideways to the faster kart) when a collision happens. This is
|
||||||
for now disabled since it needs tuning and additionally has the
|
for now disabled since it needs tuning and additionally has the
|
||||||
@ -285,7 +288,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 side-impulse="0"/>
|
<collision impulse="0" side-impulse="0"/>
|
||||||
|
|
||||||
<!-- 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
|
||||||
|
@ -72,7 +72,8 @@ KartProperties::KartProperties(const std::string &filename)
|
|||||||
m_wheel_radius = m_chassis_linear_damping = m_max_suspension_force =
|
m_wheel_radius = m_chassis_linear_damping = m_max_suspension_force =
|
||||||
m_chassis_angular_damping = m_suspension_rest =
|
m_chassis_angular_damping = m_suspension_rest =
|
||||||
m_max_speed_reverse_ratio =
|
m_max_speed_reverse_ratio =
|
||||||
m_rescue_vert_offset = m_upright_tolerance = m_collision_side_impulse =
|
m_rescue_vert_offset = m_upright_tolerance =
|
||||||
|
m_collision_side_impulse = m_collision_impulse =
|
||||||
m_upright_max_force = m_suspension_travel_cm =
|
m_upright_max_force = m_suspension_travel_cm =
|
||||||
m_track_connection_accel =
|
m_track_connection_accel =
|
||||||
m_rubber_band_max_length = m_rubber_band_force =
|
m_rubber_band_max_length = m_rubber_band_force =
|
||||||
@ -425,7 +426,10 @@ void KartProperties::getAllData(const XMLNode * root)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(const XMLNode *collision_node = root->getNode("collision"))
|
if(const XMLNode *collision_node = root->getNode("collision"))
|
||||||
|
{
|
||||||
|
collision_node->get("impulse", &m_collision_impulse );
|
||||||
collision_node->get("side-impulse", &m_collision_side_impulse);
|
collision_node->get("side-impulse", &m_collision_side_impulse);
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: wheel front right and wheel front left is not loaded, yet is listed as an attribute in the xml file after wheel-radius
|
//TODO: wheel front right and wheel front left is not loaded, yet is listed as an attribute in the xml file after wheel-radius
|
||||||
//TODO: same goes for their rear equivalents
|
//TODO: same goes for their rear equivalents
|
||||||
@ -589,6 +593,7 @@ void KartProperties::checkAllSet(const std::string &filename)
|
|||||||
CHECK_NEG(m_suspension_rest, "suspension rest" );
|
CHECK_NEG(m_suspension_rest, "suspension rest" );
|
||||||
CHECK_NEG(m_suspension_travel_cm, "suspension travel-cm" );
|
CHECK_NEG(m_suspension_travel_cm, "suspension travel-cm" );
|
||||||
CHECK_NEG(m_max_suspension_force, "suspension max-force" );
|
CHECK_NEG(m_max_suspension_force, "suspension max-force" );
|
||||||
|
CHECK_NEG(m_collision_impulse, "collision impulse" );
|
||||||
CHECK_NEG(m_collision_side_impulse, "collision side-impulse" );
|
CHECK_NEG(m_collision_side_impulse, "collision side-impulse" );
|
||||||
CHECK_NEG(m_upright_tolerance, "upright tolerance" );
|
CHECK_NEG(m_upright_tolerance, "upright tolerance" );
|
||||||
CHECK_NEG(m_upright_max_force, "upright max-force" );
|
CHECK_NEG(m_upright_max_force, "upright max-force" );
|
||||||
|
@ -248,10 +248,15 @@ private:
|
|||||||
|
|
||||||
float m_suspension_rest;
|
float m_suspension_rest;
|
||||||
float m_suspension_travel_cm;
|
float m_suspension_travel_cm;
|
||||||
|
|
||||||
/** An additional artifical side-impulse that pushes the slower kart
|
/** An additional artifical side-impulse that pushes the slower kart
|
||||||
* out of the way of the faster kart in case of a collision. */
|
* out of the way of the faster kart in case of a frontal collision. */
|
||||||
float m_collision_side_impulse;
|
float m_collision_side_impulse;
|
||||||
|
|
||||||
|
/** An additiojnal artificial impulse that pushes two karts in a
|
||||||
|
* side-side collision away from each other. */
|
||||||
|
float m_collision_impulse;
|
||||||
|
|
||||||
float m_upright_tolerance;
|
float m_upright_tolerance;
|
||||||
float m_upright_max_force;
|
float m_upright_max_force;
|
||||||
|
|
||||||
@ -499,6 +504,10 @@ public:
|
|||||||
* to a slower kart in case of a collision. */
|
* to a slower kart in case of a collision. */
|
||||||
float getCollisionSideImpulse () const {return m_collision_side_impulse;}
|
float getCollisionSideImpulse () const {return m_collision_side_impulse;}
|
||||||
|
|
||||||
|
/** Returns the (artificial) collision impulse this kart will apply
|
||||||
|
* to another kart in case of a non-frontal collision. */
|
||||||
|
float getCollisionImpulse () const {return m_collision_impulse;}
|
||||||
|
|
||||||
/** Returns the vertical offset when rescuing karts to avoid karts being
|
/** Returns the vertical offset when rescuing karts to avoid karts being
|
||||||
* rescued in (or under) the track. */
|
* rescued in (or under) the track. */
|
||||||
float getVertRescueOffset () const {return m_rescue_vert_offset; }
|
float getVertRescueOffset () const {return m_rescue_vert_offset; }
|
||||||
|
@ -89,6 +89,26 @@ btWheelInfo& btKart::addWheel(const btVector3& connectionPointCS,
|
|||||||
|
|
||||||
updateWheelTransformsWS( wheel , false );
|
updateWheelTransformsWS( wheel , false );
|
||||||
updateWheelTransform(getNumWheels()-1,false);
|
updateWheelTransform(getNumWheels()-1,false);
|
||||||
|
|
||||||
|
m_forwardWS.resize(m_wheelInfo.size());
|
||||||
|
m_axle.resize(m_wheelInfo.size());
|
||||||
|
m_forwardImpulse.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
|
||||||
|
|
||||||
@ -586,28 +606,10 @@ btScalar btKart::calcRollingFriction(btWheelContactPoint& contactPoint)
|
|||||||
|
|
||||||
void btKart::updateFriction(btScalar timeStep)
|
void btKart::updateFriction(btScalar timeStep)
|
||||||
{
|
{
|
||||||
|
|
||||||
//calculate the impulse, so that the wheels don't move sidewards
|
//calculate the impulse, so that the wheels don't move sidewards
|
||||||
int numWheel = getNumWheels();
|
|
||||||
if (!numWheel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_forwardWS.resize(numWheel);
|
|
||||||
m_axle.resize(numWheel);
|
|
||||||
m_forwardImpulse.resize(numWheel);
|
|
||||||
m_sideImpulse.resize(numWheel);
|
|
||||||
|
|
||||||
|
|
||||||
//collapse all those loops into one!
|
|
||||||
for (int i=0;i<getNumWheels();i++)
|
for (int i=0;i<getNumWheels();i++)
|
||||||
{
|
{
|
||||||
m_sideImpulse[i] = btScalar(0.);
|
m_sideImpulse[i] = btScalar(0.);
|
||||||
m_forwardImpulse[i] = btScalar(0.);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (int i=0;i<getNumWheels();i++)
|
|
||||||
{
|
|
||||||
btWheelInfo& wheelInfo = m_wheelInfo[i];
|
btWheelInfo& wheelInfo = m_wheelInfo[i];
|
||||||
|
|
||||||
btRigidBody* groundObject =
|
btRigidBody* groundObject =
|
||||||
|
@ -89,6 +89,9 @@ 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;
|
||||||
@ -256,6 +259,13 @@ 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;}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** 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
|
||||||
|
@ -127,7 +127,8 @@ void Physics::update(float dt)
|
|||||||
Kart *b=p->b->getPointerKart();
|
Kart *b=p->b->getPointerKart();
|
||||||
race_state->addCollision(a->getWorldKartId(),
|
race_state->addCollision(a->getWorldKartId(),
|
||||||
b->getWorldKartId());
|
b->getWorldKartId());
|
||||||
KartKartCollision(p->a->getPointerKart(), p->b->getPointerKart());
|
KartKartCollision(p->a->getPointerKart(), p->b->getPointerKart(),
|
||||||
|
p->getContactPoint());
|
||||||
continue;
|
continue;
|
||||||
} // if kart-kart collision
|
} // if kart-kart collision
|
||||||
|
|
||||||
@ -211,15 +212,16 @@ bool Physics::projectKartDownwards(const Kart *k)
|
|||||||
* explode immediately. This function is called from physics::update() on the
|
* explode immediately. This function is called from physics::update() on the
|
||||||
* server and if no networking is used, and from race_state on the client to
|
* server and if no networking is used, and from race_state on the client to
|
||||||
* replay what happened on the server.
|
* replay what happened on the server.
|
||||||
* \param kartA First kart involved in the collision.
|
* \param kart_a First kart involved in the collision.
|
||||||
* \param kartB Second kart involved in the collision.
|
* \param kart_b Second kart involved in the collision.
|
||||||
*/
|
*/
|
||||||
void Physics::KartKartCollision(Kart *kartA, Kart *kartB)
|
void Physics::KartKartCollision(Kart *kart_a, Kart *kart_b,
|
||||||
|
const Vec3 &contact_point)
|
||||||
{
|
{
|
||||||
kartA->crashed(kartB); // will play crash sound for player karts
|
kart_a->crashed(kart_b); // will play crash sound for player karts
|
||||||
kartB->crashed(kartA);
|
kart_b->crashed(kart_a);
|
||||||
Attachment *attachmentA=kartA->getAttachment();
|
Attachment *attachmentA=kart_a->getAttachment();
|
||||||
Attachment *attachmentB=kartB->getAttachment();
|
Attachment *attachmentB=kart_b->getAttachment();
|
||||||
|
|
||||||
if(attachmentA->getType()==Attachment::ATTACH_BOMB)
|
if(attachmentA->getType()==Attachment::ATTACH_BOMB)
|
||||||
{
|
{
|
||||||
@ -231,41 +233,63 @@ void Physics::KartKartCollision(Kart *kartA, Kart *kartB)
|
|||||||
}
|
}
|
||||||
else // only A has a bomb, move it to B (unless it was from B)
|
else // only A has a bomb, move it to B (unless it was from B)
|
||||||
{
|
{
|
||||||
if(attachmentA->getPreviousOwner()!=kartB)
|
if(attachmentA->getPreviousOwner()!=kart_b)
|
||||||
{
|
{
|
||||||
attachmentA->moveBombFromTo(kartA, kartB);
|
attachmentA->moveBombFromTo(kart_a, kart_b);
|
||||||
// Play appropriate SFX
|
// Play appropriate SFX
|
||||||
kartB->playCustomSFX(SFXManager::CUSTOM_ATTACH);
|
kart_b->playCustomSFX(SFXManager::CUSTOM_ATTACH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(attachmentB->getType()==Attachment::ATTACH_BOMB &&
|
else if(attachmentB->getType()==Attachment::ATTACH_BOMB &&
|
||||||
attachmentB->getPreviousOwner()!=kartA)
|
attachmentB->getPreviousOwner()!=kart_a)
|
||||||
{
|
{
|
||||||
attachmentB->moveBombFromTo(kartB, kartA);
|
attachmentB->moveBombFromTo(kart_b, kart_a);
|
||||||
kartA->playCustomSFX(SFXManager::CUSTOM_ATTACH);
|
kart_a->playCustomSFX(SFXManager::CUSTOM_ATTACH);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
kartA->playCustomSFX(SFXManager::CUSTOM_CRASH);
|
kart_a->playCustomSFX(SFXManager::CUSTOM_CRASH);
|
||||||
kartB->playCustomSFX(SFXManager::CUSTOM_CRASH);
|
kart_b->playCustomSFX(SFXManager::CUSTOM_CRASH);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
||||||
if(kartA->getSpeed()>=kartB->getSpeed())
|
if(kart_a->getSpeed()>=kart_b->getSpeed())
|
||||||
{
|
{
|
||||||
faster_kart = kartA;
|
faster_kart = kart_a;
|
||||||
slower_kart = kartB;
|
slower_kart = kart_b;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
faster_kart = kartB;
|
faster_kart = kart_b;
|
||||||
slower_kart = kartA;
|
slower_kart = kart_a;
|
||||||
}
|
}
|
||||||
float side_impulse = faster_kart->getKartProperties()->getCollisionSideImpulse();
|
|
||||||
if(side_impulse>0)
|
Vec3 front_center = faster_kart->getVehicle()->getFrontCenterPointWS();
|
||||||
|
float radius = 0.5f*faster_kart->getKartWidth();
|
||||||
|
bool frontal_collision =
|
||||||
|
(contact_point-front_center).length2_2d() < radius*radius;
|
||||||
|
|
||||||
|
float side_impulse =
|
||||||
|
faster_kart->getKartProperties()->getCollisionSideImpulse();
|
||||||
|
if(!frontal_collision)
|
||||||
|
{
|
||||||
|
Vec3 diff = faster_kart->getXYZ() - slower_kart->getXYZ();
|
||||||
|
// Remove any y component to reduce the chance of karts
|
||||||
|
// toppling over
|
||||||
|
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_ws(0, 1, 0);
|
||||||
Vec3 forwards = faster_kart->getTrans()*forwards_ws;
|
Vec3 forwards = faster_kart->getTrans()*forwards_ws;
|
||||||
@ -340,7 +364,8 @@ 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(upB, upA,
|
||||||
|
contactManifold->getContactPoint(0).getPositionWorldOnA());
|
||||||
else if(upB->is(UserPointer::UP_KART))
|
else if(upB->is(UserPointer::UP_KART))
|
||||||
{
|
{
|
||||||
Kart *kart=upB->getPointerKart();
|
Kart *kart=upB->getPointerKart();
|
||||||
@ -368,15 +393,19 @@ 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(upB, upA,
|
||||||
|
contactManifold->getContactPoint(0).getPositionWorldOnA());
|
||||||
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(upA, upB,
|
||||||
|
contactManifold->getContactPoint(0).getPositionWorldOnA());
|
||||||
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(upB, upA,
|
||||||
|
contactManifold->getContactPoint(0).getPositionWorldOnA());
|
||||||
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(upB, upA,
|
||||||
|
contactManifold->getContactPoint(0).getPositionWorldOnA());
|
||||||
}
|
}
|
||||||
// 3) object is a projectile
|
// 3) object is a projectile
|
||||||
// =========================
|
// =========================
|
||||||
@ -391,7 +420,8 @@ 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(upA, upB,
|
||||||
|
contactManifold->getContactPoint(0).getPositionWorldOnA());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Object is a physical object
|
// Object is a physical object
|
||||||
@ -399,14 +429,17 @@ 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(upB, upA,
|
||||||
|
contactManifold->getContactPoint(0).getPositionWorldOnA());
|
||||||
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(upA, upB,
|
||||||
|
contactManifold->getContactPoint(0).getPositionWorldOnA());
|
||||||
}
|
}
|
||||||
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(upA, upB,
|
||||||
|
contactManifold->getContactPoint(0).getPositionWorldOnA());
|
||||||
}
|
}
|
||||||
else assert("Unknown user pointer"); // 4) Should never happen
|
else assert("Unknown user pointer"); // 4) Should never happen
|
||||||
} // for i<numManifolds
|
} // for i<numManifolds
|
||||||
|
@ -44,38 +44,53 @@ class Physics : public btSequentialImpulseConstraintSolver
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// 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
|
||||||
// substep might be taken, resulting in potentially even more
|
* substep might be taken, resulting in potentially even more
|
||||||
// duplicates. To handle this, all collisions (i.e. pair of objects)
|
* duplicates. To handle this, all collisions (i.e. pair of objects)
|
||||||
// are stored in a vector, but only one entry per collision pair
|
* are stored in a vector, but only one entry per collision pair
|
||||||
// of objects.
|
* of objects.
|
||||||
// While this is a natural application of std::set, the set has some
|
* While this is a natural application of std::set, the set has some
|
||||||
// overhead (since it will likely use a tree to sort the entries).
|
* overhead (since it will likely use a tree to sort the entries).
|
||||||
// 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:
|
public:
|
||||||
|
/** The user pointer of the objects involved in this collision. */
|
||||||
const UserPointer *a, *b;
|
const UserPointer *a, *b;
|
||||||
|
|
||||||
// The entries in Collision Pairs are sorted: if a projectile
|
/** A contact point of the collision. For now only one of the two
|
||||||
// is included, it's always 'a'. If only two karts are reported
|
* contact points is needed (since they are close). */
|
||||||
// the first kart pointer is the smaller one
|
Vec3 m_contact_point;
|
||||||
CollisionPair(const UserPointer *a1, const UserPointer *b1) {
|
|
||||||
|
/** The entries in Collision Pairs are sorted: if a projectile
|
||||||
|
* is included, it's always 'a'. If only two karts are reported
|
||||||
|
* the first kart pointer is the smaller one. */
|
||||||
|
CollisionPair(const UserPointer *a1, const UserPointer *b1,
|
||||||
|
const btVector3 &contact_point) {
|
||||||
if(a1->is(UserPointer::UP_KART) &&
|
if(a1->is(UserPointer::UP_KART) &&
|
||||||
b1->is(UserPointer::UP_KART) && a1>b1) {
|
b1->is(UserPointer::UP_KART) && a1>b1) {
|
||||||
a=b1;b=a1;
|
a=b1;b=a1;
|
||||||
} else {
|
} else {
|
||||||
a=a1; b=b1;
|
a=a1; b=b1;
|
||||||
}
|
}
|
||||||
|
m_contact_point = contact_point;
|
||||||
}; // CollisionPair
|
}; // CollisionPair
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
/** 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
|
||||||
|
* elements are sorted. */
|
||||||
bool operator==(const CollisionPair p) {return (p.a==a && p.b==b);}
|
bool operator==(const CollisionPair p) {return (p.a==a && p.b==b);}
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
/** Returns the contact point of the collision. */
|
||||||
|
const Vec3 &getContactPoint() const { return m_contact_point; }
|
||||||
}; // CollisionPair
|
}; // CollisionPair
|
||||||
|
|
||||||
|
// ========================================================================
|
||||||
// This class is the list of collision objects, where each collision
|
// This class is the list of collision objects, where each collision
|
||||||
// pair is stored as most once.
|
// pair is stored as most once.
|
||||||
class CollisionList : public std::vector<CollisionPair> {
|
class CollisionList : public std::vector<CollisionPair>
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
void push_back(CollisionPair p) {
|
void push_back(CollisionPair p) {
|
||||||
// only add a pair if it's not already in there
|
// only add a pair if it's not already in there
|
||||||
@ -85,10 +100,14 @@ private:
|
|||||||
std::vector<CollisionPair>::push_back(p);
|
std::vector<CollisionPair>::push_back(p);
|
||||||
}; // push_back
|
}; // push_back
|
||||||
public:
|
public:
|
||||||
void push_back(const UserPointer* a, const UserPointer*b) {
|
/** Adds information about a collision to this vector. */
|
||||||
push_back(CollisionPair(a, b));
|
void push_back(const UserPointer* a, const UserPointer*b,
|
||||||
|
const btVector3 &contact_point)
|
||||||
|
{
|
||||||
|
push_back(CollisionPair(a, b, contact_point));
|
||||||
}
|
}
|
||||||
}; // CollisionList
|
}; // CollisionList
|
||||||
|
// ========================================================================
|
||||||
|
|
||||||
/** Pointer to the physics dynamics world. */
|
/** Pointer to the physics dynamics world. */
|
||||||
STKDynamicsWorld *m_dynamics_world;
|
STKDynamicsWorld *m_dynamics_world;
|
||||||
@ -108,7 +127,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, Kart *kb,
|
||||||
|
const Vec3 &contact_point);
|
||||||
void update (float dt);
|
void update (float dt);
|
||||||
void draw ();
|
void draw ();
|
||||||
STKDynamicsWorld*
|
STKDynamicsWorld*
|
||||||
|
Loading…
Reference in New Issue
Block a user