From 210a8e7ae9ba5d9678d0ec5c3eb4e03d07617b0c Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 20 Aug 2014 22:19:26 +1000 Subject: [PATCH] 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");