From baa0677b1ab7c819529c8f4b4ec8de36d793d10a Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 5 Feb 2018 15:57:40 +1100 Subject: [PATCH] Handle max- and min-speed capping in phyiscs (which is frame rate independent). --- src/karts/max_speed.cpp | 13 +++++++++---- src/modes/overworld.cpp | 2 +- src/physics/btKart.cpp | 32 ++++++++++++++++++++++++++------ src/physics/btKart.hpp | 18 ++++++++++++++++-- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/karts/max_speed.cpp b/src/karts/max_speed.cpp index 9ab14fa50..f9d4e9412 100644 --- a/src/karts/max_speed.cpp +++ b/src/karts/max_speed.cpp @@ -133,7 +133,7 @@ void MaxSpeed::instantSpeedIncrease(unsigned int category, // the speed might be too low for certain jumps). if(speed < m_min_speed) speed = m_min_speed; - m_kart->getVehicle()->instantSpeedIncreaseTo(speed); + m_kart->getVehicle()->setMinSpeed(speed); } // instantSpeedIncrease @@ -318,10 +318,15 @@ void MaxSpeed::update(float dt) // -------------------------------------- if(m_min_speed > 0 && m_kart->getSpeed() < m_min_speed) { - m_kart->getVehicle()->instantSpeedIncreaseTo(m_min_speed); + m_kart->getVehicle()->setMinSpeed(m_min_speed); } - else if ( m_kart->getSpeed()>m_current_max_speed && m_kart->isOnGround() ) - m_kart->getVehicle()->capSpeed(m_current_max_speed); + else + m_kart->getVehicle()->setMinSpeed(0); // no additional acceleration + + if (m_kart->isOnGround()) + m_kart->getVehicle()->setMaxSpeed(m_current_max_speed); + else + m_kart->getVehicle()->setMaxSpeed(9999.9f); } // update diff --git a/src/modes/overworld.cpp b/src/modes/overworld.cpp index 898badb01..4ba075674 100644 --- a/src/modes/overworld.cpp +++ b/src/modes/overworld.cpp @@ -278,7 +278,7 @@ void OverWorld::onMouseClick(int x, int y) // be the location of the challenge bubble. AbstractKart* kart = getKart(0); kart->setXYZ(challenge->m_position); - kart->getVehicle()->capSpeed(0); + kart->getVehicle()->setMaxSpeed(0); unsigned int index = getRescuePositionIndex(kart); btTransform s = getRescueTransform(index); diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index 9ea106195..eefb8656c 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -128,6 +128,8 @@ void btKart::reset() m_additional_rotation = btVector3(0,0,0); m_time_additional_rotation = 0; m_visual_rotation = 0; + m_max_speed = 9999.9f; + m_min_speed = 0.0f; // Set the brakes so that karts don't slide downhill setAllBrakes(5.0f); @@ -551,6 +553,7 @@ void btKart::updateVehicle( btScalar step ) iwt.setRotation(iwt.getRotation()*add_rot); m_time_additional_rotation -= dt; } + adjustSpeed(m_min_speed, m_max_speed); } // updateVehicle // ---------------------------------------------------------------------------- @@ -1019,7 +1022,7 @@ void btKart::setSliding(bool active) * specified speed. * \param speed The speed to reach. */ -void btKart::instantSpeedIncreaseTo(float speed) +void btKart::instantSpeedIncreaseTo(btScalar speed) { // Avoid that a speed 'increase' might cause a slowdown if (m_chassisBody->getLinearVelocity().length2() > speed*speed) @@ -1030,18 +1033,35 @@ void btKart::instantSpeedIncreaseTo(float speed) } // activateZipper // ---------------------------------------------------------------------------- -/** Caps the speed at a given value. If necessary the kart will - * instantaneously change its speed. */ -void btKart::capSpeed(float max_speed) +/** Adjusts the velocity of this kart to be at least the specified minimum, + * and less than or equal to the maximum. If necessary the kart will + * instantaneously change its speed. + * \param min_speed Minimum speed, 0 means no effect. + * \param max_speed Maximum speed the kart is allowed to have. + */ +void btKart::adjustSpeed(btScalar min_speed, btScalar max_speed) { const btVector3 &velocity = m_chassisBody->getLinearVelocity(); float speed = velocity.length(); - if(speed!=0) + if (speed < min_speed && min_speed > 0) + { + if (speed == 0) + { + m_chassisBody->setLinearVelocity(btVector3(0, 0, min_speed)); + } + else + { + + const float velocity_ratio = min_speed / speed; + m_chassisBody->setLinearVelocity(velocity * velocity_ratio); + } + } + else if (speed >0 && speed>max_speed) { const float velocity_ratio = max_speed / speed; m_chassisBody->setLinearVelocity(velocity * velocity_ratio); } -} // capSpeed +} // adjustSpeed // ---------------------------------------------------------------------------- //Shorter version of above raycast function. This is used when projecting diff --git a/src/physics/btKart.hpp b/src/physics/btKart.hpp index 9a93f12e8..b8c32d77b 100644 --- a/src/physics/btKart.hpp +++ b/src/physics/btKart.hpp @@ -124,6 +124,14 @@ private: * for skid marks. */ float m_visual_rotation; + /** Minimum speed for the kart. Used e.g. for zippers. Setting this value + * will potentially instantaneously accelerate the kart to the minimum + * speed requested (in the next physics step). */ + btScalar m_min_speed; + + /** Maximum speed for the kart. */ + btScalar m_max_speed; + /** True if the visual wheels touch the ground. */ bool m_visual_wheels_touch_ground; @@ -176,8 +184,8 @@ public: virtual void updateFriction(btScalar timeStep); public: void setSliding(bool active); - void instantSpeedIncreaseTo(float speed); - void capSpeed(float max_speed); + void instantSpeedIncreaseTo(btScalar speed); + void adjustSpeed(btScalar min_speed, btScalar max_speed); void updateAllWheelPositions(); // ------------------------------------------------------------------------ /** Returns true if both rear visual wheels touch the ground. */ @@ -276,6 +284,12 @@ public: /** Returns the current zipper speed. */ float getInstantSpeedIncrease() const { return m_zipper_speed; } // ------------------------------------------------------------------------ + /** Sets the maximum speed for this kart. */ + void setMaxSpeed(float s) { m_max_speed = s; } + // ------------------------------------------------------------------------ + /** Sets the minimum speed for this kart. */ + void setMinSpeed(float s) { m_min_speed = s; } + // ------------------------------------------------------------------------ void resetInstantSpeed() { m_zipper_speed = 0; } }; // class btKart