Set the graphical suspension depending on physical suspension (capped).
Adjusted graphical chassis to be 0.1 higher to have similar look at previously and avoid graphical chassis going into terrain,
This commit is contained in:
parent
e95536c265
commit
210a8e7ae9
@ -122,3 +122,13 @@ void AbstractKart::setKartAnimation(AbstractKartAnimation *ka)
|
||||
assert( (ka!=NULL) ^ (m_kart_animation!=NULL) );
|
||||
m_kart_animation = ka;
|
||||
} // setKartAnimation
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Moves the current physical transform into this kart's position.
|
||||
*/
|
||||
void AbstractKart::kartIsInRestNow()
|
||||
{
|
||||
// Update the kart transforms with the newly computed position
|
||||
// after all karts are reset
|
||||
setTrans(getBody()->getWorldTransform());
|
||||
} // kartIsInRest
|
@ -154,6 +154,12 @@ public:
|
||||
/** Returns the highest point of the kart (coordinate on up axis) */
|
||||
float getHighestPoint() const { return m_kart_highest_point; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called after the kart comes to rest. It can be used to e.g. compute
|
||||
* differences between graphical and physical chassis. Note that
|
||||
* overwriting this function is possible, but this implementation must
|
||||
* be called. */
|
||||
virtual void kartIsInRestNow();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if this kart has no wheels. */
|
||||
bool isWheeless() const;
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -2410,6 +2410,30 @@ void Kart::applyEngineForce(float force)
|
||||
}
|
||||
} // applyEngineForce
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Computes the transform of the graphical kart chasses with regards to the
|
||||
* physical chassis. This function is called once the kart comes to rest
|
||||
* before the race starts. Based on the current physical kart position, it
|
||||
* computes an (at this stage Y-only) offset by which the graphical chassis
|
||||
* is moved so that it appears the way it is designed in blender. This means
|
||||
* that the distance of the wheels from the chassis (i.e. suspension) appears
|
||||
* as in blender when karts are in rest.
|
||||
*/
|
||||
void Kart::kartIsInRestNow()
|
||||
{
|
||||
AbstractKart::kartIsInRestNow();
|
||||
float f = 0;
|
||||
for(int i=0; i<m_vehicle->getNumWheels(); i++)
|
||||
{
|
||||
const btWheelInfo &wi = m_vehicle->getWheelInfo(i);
|
||||
f += wi.m_chassisConnectionPointCS.getY()
|
||||
- wi.m_raycastInfo.m_suspensionLength - wi.m_wheelsRadius;
|
||||
}
|
||||
m_graphical_y_offset = f/m_vehicle->getNumWheels() + 0.1f;
|
||||
|
||||
m_kart_model->setDefaultSuspension();
|
||||
} // kartIsInRestNow
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates the graphics model. Mainly set the graphical position to be the
|
||||
* same as the physics position, but uses offsets to position and rotation
|
||||
@ -2510,42 +2534,15 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
|
||||
}
|
||||
}
|
||||
|
||||
// Now determine graphical chassis and wheel position depending on
|
||||
// the physics result. The center of gravity of the chassis is at the
|
||||
// bottom of the chassis, but the position of the graphical chassis is at
|
||||
// the bottom of the wheels (i.e. in blender the kart is positioned on
|
||||
// the horizonal plane through (0,0,0)). So first determine how far
|
||||
// above the terrain is the center of the physics body. If the minimum
|
||||
// of those values is larger than the lowest point of the chassis model
|
||||
// the kart chassis would be too high (and look odd), so in this case
|
||||
// move the chassis down so that the wheels (when touching the ground)
|
||||
// look close enough to the chassis.
|
||||
float height_above_terrain[4];
|
||||
float min_hat = 9999.9f;
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
// Set the suspension length
|
||||
const btWheelInfo &wi = m_vehicle->getWheelInfo(i);
|
||||
height_above_terrain[i] = wi.m_raycastInfo.m_suspensionLength;
|
||||
if(height_above_terrain[i] < min_hat) min_hat = height_above_terrain[i];
|
||||
}
|
||||
float kart_hat = m_kart_model->getLowestPoint();
|
||||
|
||||
if(min_hat >= kart_hat)
|
||||
{
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
height_above_terrain[i] = kart_hat;
|
||||
}
|
||||
m_kart_model->update(dt, m_wheel_rotation_dt, getSteerPercent(),
|
||||
height_above_terrain, m_speed);
|
||||
m_kart_model->update(dt, m_wheel_rotation_dt, getSteerPercent(), m_speed);
|
||||
|
||||
// If the kart is leaning, part of the kart might end up 'in' the track.
|
||||
// To avoid this, raise the kart enough to offset the leaning.
|
||||
float lean_height = tan(fabsf(m_current_lean)) * getKartWidth()*0.5f;
|
||||
|
||||
float heading = m_skidding->getVisualSkidRotation();
|
||||
Vec3 center_shift = Vec3(0, m_skidding->getGraphicalJumpOffset() - kart_hat
|
||||
+ lean_height-m_kart_model->getLowestPoint(), 0);
|
||||
Vec3 center_shift = Vec3(0, m_skidding->getGraphicalJumpOffset()
|
||||
+ lean_height +m_graphical_y_offset, 0);
|
||||
center_shift = getTrans().getBasis() * center_shift;
|
||||
|
||||
Moveable::updateGraphics(dt, center_shift,
|
||||
|
@ -66,13 +66,13 @@ class Kart : public AbstractKart
|
||||
friend class Skidding;
|
||||
private:
|
||||
/** Handles speed increase and capping due to powerup, terrain, ... */
|
||||
MaxSpeed *m_max_speed;
|
||||
MaxSpeed *m_max_speed;
|
||||
|
||||
/** Stores information about the terrain the kart is on. */
|
||||
TerrainInfo *m_terrain_info;
|
||||
TerrainInfo *m_terrain_info;
|
||||
|
||||
/** Handles the powerup of a kart. */
|
||||
Powerup *m_powerup;
|
||||
Powerup *m_powerup;
|
||||
|
||||
/** True if kart is flying (for debug purposes only). */
|
||||
bool m_flying;
|
||||
@ -106,6 +106,9 @@ private:
|
||||
* new lap is triggered. */
|
||||
Vec3 m_xyz_front;
|
||||
|
||||
/** Offset of the graphical kart chassis from the physical chassis. */
|
||||
float m_graphical_y_offset;
|
||||
|
||||
/** True if the kart is eliminated. */
|
||||
bool m_eliminated;
|
||||
|
||||
@ -234,6 +237,7 @@ public:
|
||||
int position, const btTransform& init_transform);
|
||||
virtual ~Kart();
|
||||
virtual void init(RaceManager::KartType type);
|
||||
virtual void kartIsInRestNow();
|
||||
virtual void updateGraphics(float dt, const Vec3& off_xyz,
|
||||
const btQuaternion& off_rotation);
|
||||
virtual void createPhysics ();
|
||||
|
@ -540,6 +540,8 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
|
||||
: -0.5f*m_kart_length);
|
||||
}
|
||||
}
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
m_wheel_graphics_position[i].setY(m_wheel_graphics_position[i].getY()-0.1f);
|
||||
|
||||
// Load the wheel models. This can't be done early, since the default
|
||||
// values for the graphical position must be defined, which in turn
|
||||
@ -634,9 +636,7 @@ void KartModel::loadWheelInfo(const XMLNode &node,
|
||||
*/
|
||||
void KartModel::reset()
|
||||
{
|
||||
// Reset the wheels
|
||||
const float suspension[4]={0,0,0,0};
|
||||
update(0.0f, 0.0f, 0.0f, suspension, 0.0f);
|
||||
update(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
// Stop any animations currently being played.
|
||||
setAnimation(KartModel::AF_DEFAULT);
|
||||
@ -741,6 +741,16 @@ void KartModel::OnAnimationEnd(scene::IAnimatedMeshSceneNode *node)
|
||||
m_animated_node->setAnimationEndCallback(NULL);
|
||||
} // OnAnimationEnd
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void KartModel::setDefaultSuspension()
|
||||
{
|
||||
for(int i=0; i<m_kart->getVehicle()->getNumWheels(); i++)
|
||||
{
|
||||
const btWheelInfo &wi = m_kart->getVehicle()->getWheelInfo(i);
|
||||
m_default_physics_suspension[i] = wi.m_raycastInfo.m_suspensionLength;
|
||||
}
|
||||
} // setDefaultSuspension
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Rotates and turns the wheels appropriately, and adjust for suspension
|
||||
+ updates the speed-weighted objects' animations.
|
||||
@ -748,30 +758,34 @@ void KartModel::OnAnimationEnd(scene::IAnimatedMeshSceneNode *node)
|
||||
* \param rotation_dt How far the wheels have rotated since last time.
|
||||
* \param steer The actual steer settings.
|
||||
* \param suspension Suspension height for all four wheels.
|
||||
* \param speed The speed of the kart in meters/sec, used for the speed-weighted objects' animations
|
||||
* \param speed The speed of the kart in meters/sec, used for the
|
||||
* speed-weighted objects' animations
|
||||
*/
|
||||
void KartModel::update(float dt, float rotation_dt, float steer,
|
||||
const float height_above_terrain[4], float speed)
|
||||
void KartModel::update(float dt, float rotation_dt, float steer, float speed)
|
||||
{
|
||||
core::vector3df wheel_steer(0, steer*30.0f, 0);
|
||||
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
if(!m_wheel_node[i]) continue;
|
||||
const btWheelInfo &wi = m_kart->getVehicle()->getWheelInfo(i);
|
||||
#ifdef DEBUG
|
||||
if(UserConfigParams::m_physics_debug && m_kart)
|
||||
{
|
||||
// Make wheels that are not touching the ground invisible
|
||||
bool wheel_has_contact =
|
||||
m_kart->getVehicle()->getWheelInfo(i).m_raycastInfo
|
||||
.m_isInContact;
|
||||
m_wheel_node[i]->setVisible(wheel_has_contact);
|
||||
m_wheel_node[i]->setVisible(wi.m_raycastInfo.m_isInContact);
|
||||
}
|
||||
#endif
|
||||
float rel_suspension = m_default_physics_suspension[i]
|
||||
- wi.m_raycastInfo.m_suspensionLength;
|
||||
if(rel_suspension< m_min_suspension[i])
|
||||
rel_suspension = m_min_suspension[i];
|
||||
else if(rel_suspension > m_max_suspension[i])
|
||||
rel_suspension = m_max_suspension[i];
|
||||
|
||||
core::vector3df pos = m_wheel_graphics_position[i].toIrrVector();
|
||||
//
|
||||
pos.Y = - height_above_terrain[i] + m_kart_lowest_point
|
||||
+ m_wheel_graphics_radius[i];
|
||||
pos.Y += rel_suspension;
|
||||
|
||||
m_wheel_node[i]->setPosition(pos);
|
||||
|
||||
// Now calculate the new rotation: (old + change) mod 360
|
||||
|
@ -169,6 +169,9 @@ private:
|
||||
/** The speed weighted objects. */
|
||||
SpeedWeightedObjectList m_speed_weighted_objects;
|
||||
|
||||
/** Length of the physics suspension when the kart is at rest. */
|
||||
float m_default_physics_suspension[4];
|
||||
|
||||
/** Minimum suspension length. If the displayed suspension is
|
||||
* shorter than this, the wheel would look wrong. */
|
||||
float m_min_suspension[4];
|
||||
@ -227,8 +230,9 @@ public:
|
||||
void reset();
|
||||
void loadInfo(const XMLNode &node);
|
||||
bool loadModels(const KartProperties &kart_properties);
|
||||
void setDefaultSuspension();
|
||||
void update(float dt, float rotation_dt, float steer,
|
||||
const float height_abve_terrain[4], float speed);
|
||||
float speed);
|
||||
void finishedRace();
|
||||
scene::ISceneNode*
|
||||
attachModel(bool animatedModels, bool always_animated);
|
||||
|
@ -677,9 +677,7 @@ void World::resetAllKarts()
|
||||
|
||||
for ( KartList::iterator i=m_karts.begin(); i!=m_karts.end(); i++)
|
||||
{
|
||||
// Update the kart transforms with the newly computed position
|
||||
// after all karts are reset
|
||||
(*i)->setTrans((*i)->getBody()->getWorldTransform());
|
||||
(*i)->kartIsInRestNow();
|
||||
}
|
||||
|
||||
// Initialise the cameras, now that the correct kart positions are set
|
||||
@ -799,6 +797,7 @@ void World::updateWorld(float dt)
|
||||
}
|
||||
catch (AbortWorldUpdateException& e)
|
||||
{
|
||||
(void)e; // avoid compiler warning
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -297,8 +297,7 @@ void FeatureUnlockedCutScene::init()
|
||||
m_unlocked_stuff[n].m_root_gift_node = kart_model->attachModel(true, false);
|
||||
m_unlocked_stuff[n].m_scale = 5.0f;
|
||||
kart_model->setAnimation(KartModel::AF_DEFAULT);
|
||||
float susp[4]={0,0,0,0};
|
||||
kart_model->update(0.0f, 0.0f, 0.0f, susp, 0.0f);
|
||||
kart_model->update(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
#ifdef DEBUG
|
||||
m_unlocked_stuff[n].m_root_gift_node->setName("unlocked kart");
|
||||
|
Loading…
Reference in New Issue
Block a user