Removed support for non-bevelled shapes (has not been used in years).

Fixed position of physical (raycast) wheels to be in (or on the edge)
of the collision body, not outside. Removed support for defining
kart-specific physical kart position (was never used).
This commit is contained in:
hiker 2014-08-10 21:54:18 +10:00
parent 18cb4f6d12
commit 4d1d4492b1
7 changed files with 122 additions and 85 deletions

View File

@ -411,10 +411,15 @@
(1-bevelY). A value of 0 for all bevel coordinates disables
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. -->
sharp 'arrow' like shape.
physical-wheel-position: Defines where the 'physical' (raycast)
wheel will be located. It's a weight factor with 0 = being
at the widest side of the bevel, 1 = at the front and
narrowest part of the kart. -->
<collision impulse-type="normal"
impulse="3000" impulse-time="0.1" terrain-impulse="8000"
restitution="1.0" bevel-factor="0.5 0.0 0.5" />
restitution="1.0" bevel-factor="0.5 0.0 0.5"
physical-wheel-position="0.5" />
<!-- If a kart starts within the specified time after 'go',
it receives the corresponding bonus from 'boost'. Those

View File

@ -583,39 +583,40 @@ void Kart::createPhysics()
btCollisionShape *shape;
const Vec3 &bevel = m_kart_properties->getBevelFactor();
if(bevel.getX() || bevel.getY() || bevel.getZ())
Vec3 wheel_pos[4];
assert(bevel.getX() || bevel.getY() || bevel.getZ());
Vec3 orig_factor(1, 1, 1 - bevel.getZ());
Vec3 bevel_factor(1.0f - bevel.getX(), 1.0f - bevel.getY(), 1.0f);
btConvexHullShape *hull = new btConvexHullShape();
for (int y = -1; y <= 1; y += 2)
{
Vec3 orig_factor(1, 1, 1-bevel.getZ());
Vec3 bevel_factor(1.0f-bevel.getX(),
1.0f-bevel.getY(),
1.0f );
btConvexHullShape *hull = new btConvexHullShape();
for(int x=-1; x<=1; x+=2)
for (int z = -1; z <= 1; z += 2)
{
for(int y=-1; y<=1; y+=2)
for (int x = -1; x <= 1; x += 2)
{
for(int z=-1; z<=1; z+=2)
Vec3 p(x*getKartModel()->getWidth() *0.5f,
y*getKartModel()->getHeight()*0.5f,
z*getKartModel()->getLength()*0.5f);
hull->addPoint(p*orig_factor);
hull->addPoint(p*bevel_factor);
// Store the x/z position for the wheels as a weighted average
// of the two bevelled points.
if (y == -1)
{
Vec3 p(x*getKartModel()->getWidth()*0.5f,
y*getKartModel()->getHeight()*0.5f,
z*getKartModel()->getLength()*0.5f);
int index = (x + 1) / 2 + 1 - z; // get index of wheel
float f = getKartProperties()->getPhysicalWheelPosition();
wheel_pos[index] = p*(orig_factor*(1.0f-f) + bevel_factor*f);
wheel_pos[index].setY(0);
} // if z==-1
} // for x
} // for z
} // for y
hull->addPoint(p*orig_factor);
hull->addPoint(p*bevel_factor);
} // for z
} // for y
} // for x
// This especially enables proper drawing of the point cloud
hull->initializePolyhedralFeatures();
shape = hull;
} // bevel.getX()!=0
else
{
shape = new btBoxShape(btVector3(0.5f*kart_width,
0.5f*kart_height,
0.5f*kart_length));
}
// This especially enables proper drawing of the point cloud
hull->initializePolyhedralFeatures();
shape = hull;
btTransform shiftCenterOfGravity;
shiftCenterOfGravity.setIdentity();
@ -672,7 +673,7 @@ void Kart::createPhysics()
{
bool is_front_wheel = i<2;
btWheelInfo& wheel = m_vehicle->addWheel(
m_kart_model->getWheelPhysicsPosition(i),
wheel_pos[i],
wheel_direction, wheel_axle, suspension_rest,
wheel_radius, tuning, is_front_wheel);
wheel.m_suspensionStiffness = m_kart_properties->getSuspensionStiffness();

View File

@ -107,7 +107,6 @@ KartModel::KartModel(bool is_master)
for(unsigned int i=0; i<4; i++)
{
m_wheel_graphics_position[i] = Vec3(UNDEFINED);
m_wheel_physics_position[i] = Vec3(UNDEFINED);
m_wheel_graphics_radius[i] = 0.0f; // for kart without separate wheels
m_wheel_model[i] = NULL;
m_wheel_node[i] = NULL;
@ -299,7 +298,6 @@ KartModel* KartModel::makeCopy()
assert(!m_wheel_node[i]);
km->m_wheel_filename[i] = m_wheel_filename[i];
km->m_wheel_graphics_position[i] = m_wheel_graphics_position[i];
km->m_wheel_physics_position[i] = m_wheel_physics_position[i];
km->m_wheel_graphics_radius[i] = m_wheel_graphics_radius[i];
km->m_min_suspension[i] = m_min_suspension[i];
km->m_max_suspension[i] = m_max_suspension[i];
@ -626,43 +624,10 @@ void KartModel::loadWheelInfo(const XMLNode &node,
}
wheel_node->get("model", &m_wheel_filename[index] );
wheel_node->get("position", &m_wheel_graphics_position[index]);
wheel_node->get("physics-position", &m_wheel_physics_position[index] );
wheel_node->get("min-suspension", &m_min_suspension[index] );
wheel_node->get("max-suspension", &m_max_suspension[index] );
} // loadWheelInfo
// ----------------------------------------------------------------------------
/** Sets the default position for the physical wheels if they are not defined
* in the data file. The default position is to have the wheels at the corner
* of the chassis. But since the position is relative to the center of mass,
* this must be specified.
* \param center_shift Amount the kart chassis is moved relative to the center
* of mass.
* \param wheel_radius Radius of the physics wheels.
*/
void KartModel::setDefaultPhysicsPosition(const Vec3 &center_shift,
float wheel_radius)
{
for(unsigned int i=0; i<4; i++)
{
if(m_wheel_physics_position[i].getX()==UNDEFINED)
{
m_wheel_physics_position[i].setX( ( i==1||i==3)
? -0.5f*m_kart_width
: 0.5f*m_kart_width
+center_shift.getX( ));
// Set the connection point so that a maximum compressed wheel
// (susp. length=0) will still poke a little bit out under the
// kart
m_wheel_physics_position[i].setY(wheel_radius-0.05f);
m_wheel_physics_position[i].setZ( (0.5f*m_kart_length-wheel_radius)
* ( (i<2) ? 1 : -1)
+center_shift.getZ());
} // if physics position is not defined
}
} // setDefaultPhysicsPosition
// ----------------------------------------------------------------------------
/** Resets the kart model. It stops animation from being played and resets
* the wheels to the correct position (i.e. no suspension).

View File

@ -157,10 +157,6 @@ private:
/** The position of all four wheels in the 3d model. */
Vec3 m_wheel_graphics_position[4];
/** The position of the wheels for the physics, which can be different
* from the graphical position. */
Vec3 m_wheel_physics_position[4];
/** Radius of the graphical wheels. */
float m_wheel_graphics_radius[4];
@ -233,8 +229,6 @@ public:
bool loadModels(const KartProperties &kart_properties);
void update(float dt, float rotation_dt, float steer,
const float height_abve_terrain[4], float speed);
void setDefaultPhysicsPosition(const Vec3 &center_shift,
float wheel_radius);
void finishedRace();
scene::ISceneNode*
attachModel(bool animatedModels, bool always_animated);
@ -263,14 +257,6 @@ public:
const Vec3* getWheelsGraphicsPosition() const
{return m_wheel_graphics_position;}
// ------------------------------------------------------------------------
/** Returns the position of a wheel relative to the kart for the physics.
* The physics wheels can be attached at a different place to make the
* karts more stable.
* \param i Index of the wheel: 0=front right, 1 = front left, 2 = rear
* right, 3 = rear left. */
const Vec3& getWheelPhysicsPosition(unsigned int i) const
{assert(i<4); return m_wheel_physics_position[i];}
// ------------------------------------------------------------------------
/** Returns the radius of the graphical wheels.
* \param i Index of the wheel: 0=front right, 1 = front left, 2 = rear
* right, 3 = rear left. */

View File

@ -92,7 +92,7 @@ KartProperties::KartProperties(const std::string &filename)
m_squash_duration = m_downward_impulse_factor =
m_bubblegum_fade_in_time = m_bubblegum_speed_fraction =
m_bubblegum_time = m_bubblegum_torque = m_jump_animation_time =
m_smooth_flying_impulse =
m_smooth_flying_impulse = m_physical_wheel_position =
UNDEFINED;
m_engine_power.resize(RaceManager::DIFFICULTY_COUNT, UNDEFINED);
@ -271,10 +271,9 @@ void KartProperties::load(const std::string &filename, const std::string &node)
m_gravity_center_shift.setY(m_kart_model->getHeight()*0.5f);
m_gravity_center_shift.setZ(0);
}
m_kart_model->setDefaultPhysicsPosition(m_gravity_center_shift,
m_wheel_radius );
m_wheel_base = fabsf( m_kart_model->getWheelPhysicsPosition(0).getZ()
-m_kart_model->getWheelPhysicsPosition(2).getZ());
//FIXME: magix 0.25 factor to keep it compatible with previous tourning
m_wheel_base = fabsf( m_kart_model->getLength()-0.25f);
// Now convert the turn radius into turn angle:
for(unsigned int i=0; i<m_turn_angle_at_speed.size(); i++)
@ -381,6 +380,7 @@ 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 );
collision_node->get("physical-wheel-position",&m_physical_wheel_position);
std::string s;
collision_node->get("impulse-type", &s );
s = StringUtils::toLowerCase(s);
@ -677,6 +677,7 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_bevel_factor.getX(), "collision bevel-factor" );
CHECK_NEG(m_bevel_factor.getY(), "collision bevel-factor" );
CHECK_NEG(m_bevel_factor.getZ(), "collision bevel-factor" );
CHECK_NEG(m_physical_wheel_position, "collision physical-wheel-position");
CHECK_NEG(m_rubber_band_max_length, "plunger band-max-length" );
CHECK_NEG(m_rubber_band_force, "plunger band-force" );
CHECK_NEG(m_rubber_band_duration, "plunger band-duration" );

View File

@ -150,6 +150,11 @@ private:
* collision shape. */
Vec3 m_bevel_factor;
/** The position of the physical wheel is a weighted average of the
* two ends of the beveled shape. This determines the weight: 0 =
* a the widest end, 1 = at the narrowest front end. */
float m_physical_wheel_position;
/** Time a kart is moved upwards after when it is rescued. */
float m_rescue_time;
@ -908,6 +913,14 @@ public:
// ------------------------------------------------------------------------
/** Returns the bevel factor (!=0 indicates to use a bevelled box). */
const Vec3 &getBevelFactor() const { return m_bevel_factor; }
// ------------------------------------------------------------------------
/** Returns position of the physical wheel is a weighted average of the
* two ends of the beveled shape. This determines the weight: 0 =
* a the widest end, 1 = at the narrowest, front end. */
const float getPhysicalWheelPosition() const
{
return m_physical_wheel_position;
} // getPhysicalWheelPosition
}; // KartProperties
#endif

66
src/patch Normal file
View File

@ -0,0 +1,66 @@
diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp
index f9d6cd9..f243d2a 100644
--- a/src/karts/kart.cpp
+++ b/src/karts/kart.cpp
@@ -1098,7 +1098,7 @@ void Kart::update(float dt)
// TODO: hiker said this probably will be moved to btKart or so when updating bullet engine.
// Neutralize any yaw change if the kart leaves the ground, so the kart falls more or less
- // straight after jumping, but still allowing some "boat shake" (roll and pitch).
+ // straight after jumping, but still allowing some "boat shake" (roIll and pitch).
// Otherwise many non perfect jumps end in a total roll over or a serious change of
// direction, sometimes 90 or even full U turn (real but less fun for a karting game).
// As side effect steering becames a bit less responsive (any wheel on air), but not too bad.
@@ -2023,30 +2023,6 @@ void Kart::updatePhysics(float dt)
m_max_speed->setMinSpeed(min_speed);
m_max_speed->update(dt);
- // If the kart is flying, keep its up-axis aligned to gravity (which in
- // turn typically means the kart is parallel to the ground). This avoids
- // that the kart rotates in mid-air and lands on its side.
- if(m_vehicle->getNumWheelsOnGround()==0)
- {
- btVector3 kart_up = getTrans().getBasis().getColumn(1); // up vector
- btVector3 terrain_up = m_body->getGravity();
- float g = World::getWorld()->getTrack()->getGravity();
- // Normalize the gravity, g is the length of the vector
- btVector3 new_up = 0.9f * kart_up + 0.1f * terrain_up/-g;
- // Get the rotation (hpr) based on current heading.
- Vec3 rotation(getHeading(), new_up);
- btMatrix3x3 m;
- m.setEulerZYX(rotation.getX(), rotation.getY(), rotation.getZ());
- // We can't use getXYZ() for the position here, since the position is
- // based on interpolation, while the actual center-of-mass-transform
- // is based on the actual value every 1/60 of a second (using getXYZ()
- // would result in the kart being pushed ahead a bit, making it jump
- // much further, depending on fps)
- btTransform new_trans(m, m_body->getCenterOfMassTransform().getOrigin());
- //setTrans(new_trans);
- m_body->setCenterOfMassTransform(new_trans);
- }
-
// To avoid tunneling (which can happen on long falls), clamp the
// velocity in Y direction. Tunneling can happen if the Y velocity
// is larger than the maximum suspension travel (per frame), since then
diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp
index bdb8f55..2aa0096 100644
--- a/src/physics/btKart.cpp
+++ b/src/physics/btKart.cpp
@@ -387,6 +387,17 @@ void btKart::updateVehicle( btScalar step )
if(m_wheelInfo[i].m_raycastInfo.m_isInContact)
m_num_wheels_on_ground++;
}
+
+ // If the kart is flying, try to keep it parallel to the ground.
+ if(m_num_wheels_on_ground==0)
+ {
+ btVector3 kart_up = getChassisWorldTransform().getBasis().getColumn(1);
+ btVector3 terrain_up(0,1,0);
+ btVector3 axis = kart_up.cross(terrain_up);
+ // Times 10 gives a nicely balanced feeling.
+ m_chassisBody->applyTorqueImpulse(axis * 10);
+ }
+
// Work around: make sure that either both wheels on one axis
// are on ground, or none of them. This avoids the problem of
// the kart suddenly getting additional angular velocity because