Added different impulse in case of a kart-track collision
(just acting along the normal). This solves some of the odd behaviour with the previous implementation if the kart is off track. The new way is now the default, but the 'push towards driveline' can be set in stk_config.xml. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11923 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
23dc272d0b
commit
49f54f2aee
@ -436,6 +436,18 @@
|
||||
<upright tolerance="0.2" max-force="30"/>
|
||||
|
||||
<!-- collision
|
||||
impulse-type: STK can apply an additional impulse in case of
|
||||
kart-track collision:
|
||||
'none' : no additional impulse
|
||||
'normal': impulse along the normal
|
||||
'driveline': impulse towards the nearest driveline.
|
||||
An impulse towards the driveline works nice when the kart is
|
||||
driving more or less correctly on the track - it pushes the
|
||||
kart in the right direction. But if the kart is significanlty
|
||||
off track, it has severe problems (since an incorrect
|
||||
driveline point can be selected, pusing the kart in the
|
||||
wrong direction, sometimes even causing a 'zip-along-obstacle'
|
||||
effect.
|
||||
impulse: an additional impulse to be applied in a non-frontal
|
||||
collision to push two karts away from each other.
|
||||
impulse-time: The impulse will be applied over a certain time
|
||||
@ -452,7 +464,8 @@
|
||||
bevelling, and uses a simple box shape.
|
||||
As an example, a value of 1 for x and z will result in a
|
||||
sharp 'arrow' like shape. -->
|
||||
<collision impulse="3000" impulse-time="0.1" terrain-impulse="8000"
|
||||
<collision impulse-type="normal"
|
||||
impulse="3000" impulse-time="0.1" terrain-impulse="8000"
|
||||
restitution="1.0" bevel-factor="0.5 0.0 0.5" />
|
||||
|
||||
<!-- Kart-specific plunger and rubber band handling: max-length is
|
||||
|
@ -379,7 +379,7 @@ public:
|
||||
* other kart hit will be updated (e.g. bombs will be moved). */
|
||||
virtual void crashed(AbstractKart *k, bool update_attachments) = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void crashed(const Material *m) = 0;
|
||||
virtual void crashed(const Material *m, const Vec3 &normal) = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the height of the terrain. we're currently above */
|
||||
virtual float getHoT() const = 0;
|
||||
|
@ -1549,7 +1549,7 @@ void Kart::crashed(AbstractKart *k, bool update_attachments)
|
||||
/** Kart hits the track with a given material.
|
||||
* \param m Material hit, can be NULL if no specific material exists.
|
||||
*/
|
||||
void Kart::crashed(const Material *m)
|
||||
void Kart::crashed(const Material *m, const Vec3 &normal)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Simple debug output for people playing without sound.
|
||||
@ -1563,19 +1563,32 @@ void Kart::crashed(const Material *m)
|
||||
static int counter=0;
|
||||
printf("Kart %s hit track: %d material %s.\n",
|
||||
getIdent().c_str(), counter++,
|
||||
m->getTexFname().c_str());
|
||||
m ? m->getTexFname().c_str() : "None");
|
||||
}
|
||||
#endif
|
||||
|
||||
const LinearWorld *lw = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
if(getKartProperties()->getTerrainImpulseType()
|
||||
==KartProperties::IMPULSE_NORMAL &&
|
||||
m_vehicle->getCentralImpulseTime()<=0 )
|
||||
{
|
||||
Vec3 impulse = normal;
|
||||
if(impulse.getX() || impulse.getZ())
|
||||
impulse.normalize();
|
||||
else
|
||||
impulse = Vec3(0, 0, -1); // Arbitrary
|
||||
impulse *= m_kart_properties->getCollisionTerrainImpulse();
|
||||
m_bounce_back_time = 0.2f;
|
||||
m_vehicle->setTimedCentralImpulse(0.1f, impulse);
|
||||
}
|
||||
// If there is a quad graph, push the kart towards the previous
|
||||
// graph node center (we have to use the previous point since the
|
||||
// kart might have only now reached the new quad, meaning the kart
|
||||
// would be pushed forward).
|
||||
// FIXME: or should we try to add a 'proper' reflection, i.e. an
|
||||
// impulse depending on the vector and normal at the hit point?
|
||||
const LinearWorld *lw = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
if(lw && m_vehicle->getCentralImpulseTime()<=0 &&
|
||||
World::getWorld()->getTrack()->isPushBackEnabled())
|
||||
else if(getKartProperties()->getTerrainImpulseType()
|
||||
==KartProperties::IMPULSE_TO_DRIVELINE &&
|
||||
lw && m_vehicle->getCentralImpulseTime()<=0 &&
|
||||
World::getWorld()->getTrack()->isPushBackEnabled())
|
||||
{
|
||||
int sector = lw->getSectorForKart(this);
|
||||
if(sector!=QuadGraph::UNKNOWN_SECTOR)
|
||||
|
@ -257,7 +257,7 @@ public:
|
||||
virtual void setSquash (float time, float slowdown);
|
||||
|
||||
virtual void crashed (AbstractKart *k, bool update_attachments);
|
||||
virtual void crashed (const Material *m);
|
||||
virtual void crashed (const Material *m, const Vec3 &normal);
|
||||
virtual float getHoT () const;
|
||||
virtual void update (float dt);
|
||||
virtual void finishedRace(float time);
|
||||
|
@ -93,6 +93,7 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
m_swatter_distance2 = m_swatter_duration = m_squash_slowdown =
|
||||
m_squash_duration = m_downward_impulse_factor = UNDEFINED;
|
||||
|
||||
m_terrain_impulse_type = IMPULSE_NONE;
|
||||
m_gravity_center_shift = Vec3(UNDEFINED);
|
||||
m_bevel_factor = Vec3(UNDEFINED);
|
||||
m_exp_spring_response = false;
|
||||
@ -443,6 +444,21 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
collision_node->get("terrain-impulse", &m_collision_terrain_impulse);
|
||||
collision_node->get("restitution", &m_restitution );
|
||||
collision_node->get("bevel-factor", &m_bevel_factor );
|
||||
std::string s;
|
||||
collision_node->get("impulse-type", &s );
|
||||
s = StringUtils::toLowerCase(s);
|
||||
if(s=="none")
|
||||
m_terrain_impulse_type = IMPULSE_NONE;
|
||||
else if(s=="normal")
|
||||
m_terrain_impulse_type = IMPULSE_NORMAL;
|
||||
else if(s=="driveline")
|
||||
m_terrain_impulse_type = IMPULSE_TO_DRIVELINE;
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Missing or incorrect value for impulse-type: '%s'.\n",
|
||||
s.c_str());
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: wheel front right and wheel front left is not loaded, yet is
|
||||
|
@ -262,6 +262,18 @@ private:
|
||||
float m_suspension_rest;
|
||||
float m_suspension_travel_cm;
|
||||
|
||||
public:
|
||||
/** STK can add an impulse to push karts away from the track in case
|
||||
* of a kart-track collision. This can be done in two ways: either
|
||||
* apply the impulse in the direction of the normal, or towards the
|
||||
* driveline. The later works nice as long as the kart is driving
|
||||
* on the main track, but can work very bad if the kart is drivling
|
||||
* off-track (and a wrong driveline is selected). */
|
||||
enum TerrainImpulseType {IMPULSE_NONE, IMPULSE_NORMAL,
|
||||
IMPULSE_TO_DRIVELINE};
|
||||
private:
|
||||
TerrainImpulseType m_terrain_impulse_type;
|
||||
|
||||
/** An additional impulse to push a kart away if it hits terrain */
|
||||
float m_collision_terrain_impulse;
|
||||
|
||||
@ -513,6 +525,10 @@ public:
|
||||
float getCollisionTerrainImpulse() const
|
||||
{return m_collision_terrain_impulse;}
|
||||
|
||||
/** Returns what kind of impulse STK should use in case of a kart-track
|
||||
* collision. */
|
||||
TerrainImpulseType getTerrainImpulseType() const
|
||||
{ return m_terrain_impulse_type; }
|
||||
/** 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;}
|
||||
|
@ -175,8 +175,9 @@ void RaceState::receive(ENetPacket *pkt)
|
||||
signed char kart_id2 = getChar();
|
||||
if(kart_id2==-1)
|
||||
{ // kart - track collision
|
||||
world->getKart(kart_id1)->crashed(NULL);
|
||||
}
|
||||
Vec3 normal(0, 1, 0); // need to be fixed for online
|
||||
world->getKart(kart_id1)->crashed(NULL, normal);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: KartKartCollision now takes information about the
|
||||
|
@ -456,7 +456,12 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
|
||||
const Material *m
|
||||
= n>=0 ? upA->getPointerTriangleMesh()->getMaterial(n)
|
||||
: NULL;
|
||||
kart->crashed(m);
|
||||
// I assume that the normal needs to be flipped in this case,
|
||||
// but I can't verify this since it appears that bullet
|
||||
// always has the kart as object A, not B.
|
||||
const btVector3 &normal = -contact_manifold->getContactPoint(0)
|
||||
.m_normalWorldOnB;
|
||||
kart->crashed(m, normal);
|
||||
}
|
||||
}
|
||||
// 2) object a is a kart
|
||||
@ -471,7 +476,9 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
|
||||
const Material *m
|
||||
= n>=0 ? upB->getPointerTriangleMesh()->getMaterial(n)
|
||||
: NULL;
|
||||
kart->crashed(m); // Kart hit track
|
||||
const btVector3 &normal = contact_manifold->getContactPoint(0)
|
||||
.m_normalWorldOnB;
|
||||
kart->crashed(m, normal); // Kart hit track
|
||||
}
|
||||
else if(upB->is(UserPointer::UP_FLYABLE))
|
||||
// 2.1 projectile hits kart
|
||||
|
Loading…
Reference in New Issue
Block a user