From e95536c2653e134c89217939d82dc4401c3d2e5e Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 20 Aug 2014 21:35:22 +1000 Subject: [PATCH 1/7] Fixed height computation. Moved adding of gravity center shift, which probably fixed the problems we had with 'wheels inside kart chassis' tests earlier. --- src/karts/kart.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 577f75b8e..127cc565e 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -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()); - 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()); + // All wheel positions are relative to the center of + // the collision shape. + wheel_pos[index].setX(x*0.5f*getKartWidth()); + float radius = getKartProperties()->getWheelRadius(); + // 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(); From 210a8e7ae9ba5d9678d0ec5c3eb4e03d07617b0c Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 20 Aug 2014 22:19:26 +1000 Subject: [PATCH 2/7] 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, --- src/karts/abstract_kart.cpp | 10 +++++ src/karts/abstract_kart.hpp | 6 +++ src/karts/kart.cpp | 57 ++++++++++++------------- src/karts/kart.hpp | 10 +++-- src/karts/kart_model.cpp | 40 +++++++++++------ src/karts/kart_model.hpp | 6 ++- src/modes/world.cpp | 5 +-- src/states_screens/feature_unlocked.cpp | 3 +- 8 files changed, 85 insertions(+), 52 deletions(-) diff --git a/src/karts/abstract_kart.cpp b/src/karts/abstract_kart.cpp index 3ad73b442..0171d5043 100644 --- a/src/karts/abstract_kart.cpp +++ b/src/karts/abstract_kart.cpp @@ -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 \ No newline at end of file diff --git a/src/karts/abstract_kart.hpp b/src/karts/abstract_kart.hpp index 7e681e418..5df0e817b 100644 --- a/src/karts/abstract_kart.hpp +++ b/src/karts/abstract_kart.hpp @@ -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; // ------------------------------------------------------------------------ diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 127cc565e..4b8fe38bd 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -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; igetNumWheels(); 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, diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp index 52c477b9d..087c510ab 100644 --- a/src/karts/kart.hpp +++ b/src/karts/kart.hpp @@ -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 (); diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp index 90ef13a5f..2b5fd2866 100644 --- a/src/karts/kart_model.cpp +++ b/src/karts/kart_model.cpp @@ -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; igetVehicle()->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 diff --git a/src/karts/kart_model.hpp b/src/karts/kart_model.hpp index 9d2138642..a5cd92201 100644 --- a/src/karts/kart_model.hpp +++ b/src/karts/kart_model.hpp @@ -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); diff --git a/src/modes/world.cpp b/src/modes/world.cpp index d80ae7b7d..438f5d8d8 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -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; } diff --git a/src/states_screens/feature_unlocked.cpp b/src/states_screens/feature_unlocked.cpp index 32510f341..3f24204ee 100644 --- a/src/states_screens/feature_unlocked.cpp +++ b/src/states_screens/feature_unlocked.cpp @@ -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"); From 856eb747b4c2cc4b6466a8068b25dad723cb64fe Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 21 Aug 2014 08:01:54 +1000 Subject: [PATCH 3/7] Fixed shadows with a hack. --- src/graphics/shadow.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/graphics/shadow.cpp b/src/graphics/shadow.cpp index e092f8284..5a6fb5cdb 100644 --- a/src/graphics/shadow.cpp +++ b/src/graphics/shadow.cpp @@ -23,7 +23,8 @@ #include #include -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 xOffset = 0.0, float yOffset = 0.0) { video::SMaterial m; m.setTexture(0, texture); @@ -49,6 +50,7 @@ Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node, float scale = buffer->recalculateBoundingBox(); m_node = irr_driver->addMesh(m_mesh); + m_node->setPosition(core::vector3df(0, -0.1f, 0)); #ifdef DEBUG m_node->setName("shadow"); #endif From 171b442ae618cbff78c396d3363926b8a0ff8abf Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 21 Aug 2014 09:59:29 +1000 Subject: [PATCH 4/7] Removed artificial Y offset to allow evaluation of more karts. --- src/graphics/shadow.cpp | 2 +- src/karts/kart.cpp | 2 +- src/karts/kart_model.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/graphics/shadow.cpp b/src/graphics/shadow.cpp index 5a6fb5cdb..c075d0ccc 100644 --- a/src/graphics/shadow.cpp +++ b/src/graphics/shadow.cpp @@ -50,7 +50,7 @@ Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node, buffer->recalculateBoundingBox(); m_node = irr_driver->addMesh(m_mesh); - m_node->setPosition(core::vector3df(0, -0.1f, 0)); + m_node->setPosition(core::vector3df(0, 0.0f, 0)); #ifdef DEBUG m_node->setName("shadow"); #endif diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 4b8fe38bd..b337760eb 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -2429,7 +2429,7 @@ void Kart::kartIsInRestNow() f += wi.m_chassisConnectionPointCS.getY() - wi.m_raycastInfo.m_suspensionLength - wi.m_wheelsRadius; } - m_graphical_y_offset = f/m_vehicle->getNumWheels() + 0.1f; + m_graphical_y_offset = f/m_vehicle->getNumWheels() + 0.0f; m_kart_model->setDefaultSuspension(); } // kartIsInRestNow diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp index 2b5fd2866..3350938b8 100644 --- a/src/karts/kart_model.cpp +++ b/src/karts/kart_model.cpp @@ -541,7 +541,7 @@ bool KartModel::loadModels(const KartProperties &kart_properties) } } for(unsigned int i=0; i<4; i++) - m_wheel_graphics_position[i].setY(m_wheel_graphics_position[i].getY()-0.1f); + m_wheel_graphics_position[i].setY(m_wheel_graphics_position[i].getY()-0.0f); // Load the wheel models. This can't be done early, since the default // values for the graphical position must be defined, which in turn From 15cccf9301f50bfa0bfd2129c75ecca81e13efe5 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 21 Aug 2014 17:28:06 +1000 Subject: [PATCH 5/7] Make the graphical y offset configurable (and basically disable it for now by setting it to 0). --- data/stk_config.xml | 11 ++++++----- src/graphics/shadow.cpp | 12 ++++++------ src/graphics/shadow.hpp | 5 ++--- src/karts/kart.cpp | 6 ++++-- src/karts/kart_model.cpp | 10 ++++++++-- src/karts/kart_properties.cpp | 14 ++++++++++---- src/karts/kart_properties.hpp | 13 +++++++++++-- 7 files changed, 47 insertions(+), 24 deletions(-) diff --git a/data/stk_config.xml b/data/stk_config.xml index b45b46a6e..81135667a 100644 --- a/data/stk_config.xml +++ b/data/stk_config.xml @@ -155,12 +155,13 @@ otherwise obstricts too much of the view. --> + + - - + + diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 5dffe87e7..b84ca215c 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1765,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); }