Merge branch 'no_floating'

This commit is contained in:
hiker 2014-08-22 12:46:10 +10:00
commit 3ef30dfd48
13 changed files with 157 additions and 91 deletions

View File

@ -155,12 +155,13 @@
otherwise obstricts too much of the view. -->
<camera distance="1.5" forward-up-angle="15"
backward-up-angle="30"/>
<!-- Additional offset to move graphical chassis with regards to the physics. -->
<graphics y-offset="0.0"/>
<!-- Jump animation related values:
animation-time: only if the estimated time for a jump is larger
than this value will the jump animation being
shown. -->
<jump animation-time="0.5" />
<!-- Jump animation related values:
animation-time: only if the estimated time for a jump is larger
than this value will the jump animation being shown. -->
<jump animation-time="0.5" />
<!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
decrease: multiplicative decrease of skidding factor in each frame.
@ -420,7 +421,7 @@
outside of the chassis and results in more stable physical
behaviour of the karts. -->
<collision impulse-type="normal"
impulse="3000" impulse-time="0.1" terrain-impulse="8000"
impulse="3000" impulse-time="0.1" terrain-impulse="1600"
restitution="1.0" bevel-factor="0.5 0.0 0.7"
physical-wheel-position="-1" />

View File

@ -23,7 +23,9 @@
#include <IMeshSceneNode.h>
#include <ISceneNode.h>
Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node, float scale = 1.0, float xOffset = 0.0, float yOffset = 0.0)
Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node,
float scale = 1.0, float x_offset = 0.0, float y_offset = 0.0,
float z_offset = 0.0)
{
video::SMaterial m;
m.setTexture(0, texture);
@ -33,10 +35,10 @@ Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node, float scale =
m_mesh = irr_driver->createQuadMesh(&m, /*create_one_quad*/true);
scene::IMeshBuffer *buffer = m_mesh->getMeshBuffer(0);
irr::video::S3DVertex* v=(video::S3DVertex*)buffer->getVertices();
v[0].Pos.X = -scale+xOffset; v[0].Pos.Z = scale+yOffset; v[0].Pos.Y = 0.01f;
v[1].Pos.X = scale+xOffset; v[1].Pos.Z = scale+yOffset; v[1].Pos.Y = 0.01f;
v[2].Pos.X = scale+xOffset; v[2].Pos.Z = -scale+yOffset; v[2].Pos.Y = 0.01f;
v[3].Pos.X = -scale+xOffset; v[3].Pos.Z = -scale+yOffset; v[3].Pos.Y = 0.01f;
v[0].Pos.X = -scale+x_offset; v[0].Pos.Z = scale+z_offset; v[0].Pos.Y = 0.01f-y_offset;
v[1].Pos.X = scale+x_offset; v[1].Pos.Z = scale+z_offset; v[1].Pos.Y = 0.01f-y_offset;
v[2].Pos.X = scale+x_offset; v[2].Pos.Z = -scale+z_offset; v[2].Pos.Y = 0.01f-y_offset;
v[3].Pos.X = -scale+x_offset; v[3].Pos.Z = -scale+z_offset; v[3].Pos.Y = 0.01f-y_offset;
v[0].TCoords = core::vector2df(0,0);
v[1].TCoords = core::vector2df(1,0);
v[2].TCoords = core::vector2df(1,1);

View File

@ -46,9 +46,8 @@ private:
/** The scene node of the kart to which this shadow belongs. */
scene::ISceneNode *m_parent_kart_node;
public:
Shadow(video::ITexture *texture,
scene::ISceneNode *node,
float scale, float xOffset, float yOffset);
Shadow(video::ITexture *texture, scene::ISceneNode *node,
float scale, float x_offset, float y_offset,float z_offset);
~Shadow();
void enableShadow();
void disableShadow();

View File

@ -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

View File

@ -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;
// ------------------------------------------------------------------------

View File

@ -611,15 +611,20 @@ void Kart::createPhysics()
// to place the wheels outside of the chassis
if(f<0)
{
const Vec3 cs = getKartProperties()->getGravityCenterShift();
wheel_pos[index].setX(x*0.5f*getKartWidth()+cs.getX());
// All wheel positions are relative to the center of
// the collision shape.
wheel_pos[index].setX(x*0.5f*getKartWidth());
float radius = getKartProperties()->getWheelRadius();
// Set the connection point so that a maximum compressed wheel
// (susp. length=0) will still poke a little bit out under the
// kart
wheel_pos[index].setY(radius - 0.05f);
wheel_pos[index].setZ((0.5f*getKartLength() - radius)* z
+ cs.getZ());
// The y position of the wheels (i.e. the points where
// the suspension is attached to) is just at the
// bottom of the kart. That is half the kart height
// down. The wheel radius is added to the suspension
// length in the physics, so we move the connection
// point 'radius' up. That means that if the suspension
// is fully compressed (0), the wheel will just be at
// the bottom of the kart chassis and touch the ground
wheel_pos[index].setY(- 0.5f*getKartHeight() + radius);
wheel_pos[index].setZ((0.5f*getKartLength() - radius)* z);
}
else
@ -687,11 +692,12 @@ void Kart::createPhysics()
tuning.m_maxSuspensionForce =
m_kart_properties->getMaxSuspensionForce();
const Vec3 &cs = getKartProperties()->getGravityCenterShift();
for(unsigned int i=0; i<4; i++)
{
bool is_front_wheel = i<2;
btWheelInfo& wheel = m_vehicle->addWheel(
wheel_pos[i],
wheel_pos[i]+cs,
wheel_direction, wheel_axle, suspension_rest,
wheel_radius, tuning, is_front_wheel);
wheel.m_suspensionStiffness = m_kart_properties->getSuspensionStiffness();
@ -1759,9 +1765,9 @@ void Kart::crashed(const Material *m, const Vec3 &normal)
impulse.normalize();
else
impulse = Vec3(0, 0, -1); // Arbitrary
// impulse depends of kart speed
impulse *= 0.2f * m_body->getLinearVelocity().length();
impulse *= m_kart_properties->getCollisionTerrainImpulse();
// impulse depends of kart speed - and speed can be negative
impulse *= sqrt(fabsf(getSpeed()))
* m_kart_properties->getCollisionTerrainImpulse();
m_bounce_back_time = 0.2f;
m_vehicle->setTimedCentralImpulse(0.1f, impulse);
}
@ -2373,7 +2379,8 @@ void Kart::loadData(RaceManager::KartType type, bool is_animated_model)
m_node,
m_kart_properties->getShadowScale(),
m_kart_properties->getShadowXOffset(),
m_kart_properties->getShadowYOffset());
m_kart_properties->getGraphicalYOffset(),
m_kart_properties->getShadowZOffset());
World::getWorld()->kartAdded(this, m_node);
} // loadData
@ -2404,6 +2411,31 @@ 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()
+ getKartProperties()->getGraphicalYOffset();
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
@ -2504,42 +2536,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,

View File

@ -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 ();

View File

@ -113,8 +113,8 @@ KartModel::KartModel(bool is_master)
// default value for kart suspensions. move to config file later
// if we find each kart needs custom values
m_min_suspension[i] = -0.59f;
m_max_suspension[i] = 0.59f;
m_min_suspension[i] = -0.07;
m_max_suspension[i] = 0.20f;
m_dampen_suspension_amplitude[i] = 2.5f;
}
m_wheel_filename[0] = "";
@ -541,6 +541,14 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
}
}
float y_off = kart_properties.getGraphicalYOffset();
if(y_off!=0)
{
for (unsigned int i = 0; i < 4; i++)
m_wheel_graphics_position[i].setY(
m_wheel_graphics_position[i].getY() - y_off);
}
// Load the wheel models. This can't be done early, since the default
// values for the graphical position must be defined, which in turn
// depend on the size of the model.
@ -634,9 +642,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 +747,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 +764,35 @@ 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 = wi.m_raycastInfo.m_suspensionLength
- m_default_physics_suspension[i];
// If the suspension is too compressed
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

View File

@ -169,12 +169,16 @@ private:
/** The speed weighted objects. */
SpeedWeightedObjectList m_speed_weighted_objects;
/** Minimum suspension length. If the displayed suspension is
* shorter than this, the wheel would look wrong. */
/** Length of the physics suspension when the kart is at rest. */
float m_default_physics_suspension[4];
/** Minimum suspension length (i.e. most compressed). If the displayed
* suspension is shorter than this, the wheel would look wrong. */
float m_min_suspension[4];
/** Maximum suspension length. If the displayed suspension is
* any longer, the wheel would look too far away from the chassis. */
/** Maximum suspension length (i.e. most extended). If the displayed
* suspension is any longer, the wheel would look too far away from the
* chassis. */
float m_max_suspension[4];
/** value used to divide the visual movement of wheels (because the actual movement
@ -227,8 +231,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);

View File

@ -57,7 +57,7 @@ KartProperties::KartProperties(const std::string &filename)
m_shadow_file = "";
m_shadow_scale = 1.0f;
m_shadow_x_offset = 0.0f;
m_shadow_y_offset = 0.0f;
m_shadow_z_offset = 0.0f;
m_groups.clear();
m_custom_sfx_id.resize(SFXManager::NUM_CUSTOMS);
@ -92,7 +92,8 @@ 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_physical_wheel_position =
m_smooth_flying_impulse = m_physical_wheel_position =
m_graphical_y_offset =
UNDEFINED;
m_engine_power.resize(RaceManager::DIFFICULTY_COUNT, UNDEFINED);
@ -322,7 +323,7 @@ void KartProperties::getAllData(const XMLNode * root)
root->get("shadow-scale", &m_shadow_scale );
root->get("shadow-x-offset", &m_shadow_x_offset );
root->get("shadow-y-offset", &m_shadow_y_offset );
root->get("shadow-z-offset", &m_shadow_z_offset );
root->get("type", &m_kart_type );
@ -615,6 +616,11 @@ void KartProperties::getAllData(const XMLNode * root)
startup_node->get("boost", &m_startup_boost);
}
if(const XMLNode *graphics_node = root->getNode("graphics"))
{
graphics_node->get("y-offset", &m_graphical_y_offset);
}
if(m_kart_model)
m_kart_model->loadInfo(*root);
} // getAllData
@ -735,7 +741,7 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_explosion_invulnerability_time,
"explosion invulnerability-time");
CHECK_NEG(m_explosion_radius, "explosion radius" );
CHECK_NEG(m_graphical_y_offset, "graphics y-offset" );
for(unsigned int i=RaceManager::DIFFICULTY_FIRST;
i<=RaceManager::DIFFICULTY_LAST; i++)
{

View File

@ -112,7 +112,7 @@ private:
* for this kart.*/
float m_shadow_x_offset; /**< X offset of the shadow plane
* for this kart.*/
float m_shadow_y_offset; /**< Y offset of the shadow plane
float m_shadow_z_offset; /**< Z offset of the shadow plane
* for this kart.*/
video::ITexture *m_shadow_texture;/**< The texture with the shadow. */
video::SColor m_color; /**< Color the represents the kart in the
@ -204,6 +204,10 @@ private:
std::string m_wheel_filename[4];
/** Radius of the graphical wheels. */
float m_wheel_graphics_radius[4];
/** An additional Y offset added to the y position of the graphical
* chassis. Useful for karts that don't have enough space for suspension
* compression. */
float m_graphical_y_offset;
/** If the kart is supposed to have random wheel rotation at start. */
bool m_has_rand_wheels;
/** Max. length of plunger rubber band. */
@ -568,6 +572,11 @@ public:
/** Returns wheel radius. */
float getWheelRadius () const {return m_wheel_radius; }
// ------------------------------------------------------------------------
/** Return the additional Y offset added to the y position of the graphical
* chassis. Useful for karts that don't have enough space for suspension
* compression. */
float getGraphicalYOffset() const {return m_graphical_y_offset; }
// ------------------------------------------------------------------------
/** Returns parameters for the speed-weighted objects */
const SpeedWeightedObject::Properties& getSpeedWeightedObjectProperties() const
@ -831,7 +840,7 @@ public:
// ------------------------------------------------------------------------
/** Returns the scale factor by which the shadow plane
* had to be set. */
float getShadowYOffset () const {return m_shadow_y_offset; }
float getShadowZOffset () const {return m_shadow_z_offset; }
// ------------------------------------------------------------------------
/** Returns a pointer to the skidding properties. */

View File

@ -679,9 +679,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
@ -801,6 +799,7 @@ void World::updateWorld(float dt)
}
catch (AbortWorldUpdateException& e)
{
(void)e; // avoid compiler warning
return;
}

View File

@ -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");