From 55159fbdcd2ccd380b328b04f002ac753ff66817 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 4 Jan 2018 08:58:37 +1100 Subject: [PATCH 1/6] Prevented a crash when aborting STK (audio thread is not shut down in this case, but is getting deleted - but the audio thread might still try to insert an update event during that time). --- src/audio/sfx_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index a49eae713..72bb93c6d 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -411,7 +411,7 @@ void* SFXManager::mainLoop(void *obj) PROFILER_PUSH_CPU_MARKER("yield", 0, 0, 255); // We access the size without lock, doesn't matter if we // should get an incorrect value because of concurrent read/writes - if (me->m_sfx_commands.getData().size() == 0) + if (me->m_sfx_commands.getData().size() == 0 && me->sfxAllowed()) { // Wait some time to let other threads run, then queue an // update event to keep music playing. From baa0677b1ab7c819529c8f4b4ec8de36d793d10a Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 5 Feb 2018 15:57:40 +1100 Subject: [PATCH 2/6] 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 From 884e966ab9a7ee1bb6a0f895a5e76285d24d4517 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 5 Feb 2018 16:11:19 +1100 Subject: [PATCH 3/6] Added capability to handle setting the maximum speed first to 0, and then later to a higher value (which happens in overworld, which sets max speed to 0, but the value got later overwritten with the normal supertuxkart max_speed handling. --- .../Dynamics/btActionInterface.h | 2 +- .../Dynamics/btDiscreteDynamicsWorld.cpp | 6 ++++++ src/physics/btKart.cpp | 4 ++-- src/physics/btKart.hpp | 18 ++++++++++++++++-- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/bullet/src/BulletDynamics/Dynamics/btActionInterface.h b/lib/bullet/src/BulletDynamics/Dynamics/btActionInterface.h index e1fea3a49..910752402 100644 --- a/lib/bullet/src/BulletDynamics/Dynamics/btActionInterface.h +++ b/lib/bullet/src/BulletDynamics/Dynamics/btActionInterface.h @@ -39,7 +39,7 @@ public: virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTimeStep)=0; virtual void debugDraw(btIDebugDraw* debugDrawer) = 0; - + virtual void resetMaxSpeed() = 0; }; #endif //_BT_ACTION_INTERFACE_H diff --git a/lib/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/lib/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index b006c67b1..a54e6d336 100644 --- a/lib/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/lib/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -297,6 +297,12 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, } clearForces(); + // Reset the max speeds of all karts, so that supertuxkart can + // set any new max_speed. + for (int i = 0; iresetMaxSpeed(); + } #ifndef BT_NO_PROFILE CProfileManager::Increment_Frame_Counter(); diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index eefb8656c..34742a3a7 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -128,7 +128,7 @@ 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_max_speed = -1.0f; m_min_speed = 0.0f; // Set the brakes so that karts don't slide downhill @@ -1056,7 +1056,7 @@ void btKart::adjustSpeed(btScalar min_speed, btScalar max_speed) m_chassisBody->setLinearVelocity(velocity * velocity_ratio); } } - else if (speed >0 && speed>max_speed) + else if (speed >0 && max_speed >= 0 && speed > max_speed) { const float velocity_ratio = max_speed / speed; m_chassisBody->setLinearVelocity(velocity * velocity_ratio); diff --git a/src/physics/btKart.hpp b/src/physics/btKart.hpp index b8c32d77b..4cb0e917e 100644 --- a/src/physics/btKart.hpp +++ b/src/physics/btKart.hpp @@ -129,7 +129,8 @@ private: * speed requested (in the next physics step). */ btScalar m_min_speed; - /** Maximum speed for the kart. */ + /** Maximum speed for the kart. It is reset to -1 at the end of each + * physics steps, so need to be set again by the application. */ btScalar m_max_speed; /** True if the visual wheels touch the ground. */ @@ -285,7 +286,20 @@ public: float getInstantSpeedIncrease() const { return m_zipper_speed; } // ------------------------------------------------------------------------ /** Sets the maximum speed for this kart. */ - void setMaxSpeed(float s) { m_max_speed = s; } + void setMaxSpeed(float new_max_speed) + { + // Only change m_max_speed if it has not been set (<0), or + // the new value is smaller than the current maximum. For example, + // overworld will set the max_speed to 0 in case of teleporting to + // a bubble, but set it again later (based on zipper etc activated). + // We need to make sure that the 0 is maintained. + if(m_max_speed <0 || m_max_speed > new_max_speed) + m_max_speed = new_max_speed; + } // setMaxSpeed + // ------------------------------------------------------------------------ + /** Resets the maximum so any new maximum value from the application will + * be accepted. */ + virtual void resetMaxSpeed() { m_max_speed = -1.0f; } // ------------------------------------------------------------------------ /** Sets the minimum speed for this kart. */ void setMinSpeed(float s) { m_min_speed = s; } From 1c2fdc1c14324f5b8eac65b26bfdd5ea18fab6c4 Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 6 Feb 2018 08:29:18 +1100 Subject: [PATCH 4/6] Fixed compiler warnings. --- src/input/gamepad_device.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/input/gamepad_device.cpp b/src/input/gamepad_device.cpp index 8fe7fb7ed..c7302d9ba 100644 --- a/src/input/gamepad_device.cpp +++ b/src/input/gamepad_device.cpp @@ -94,7 +94,7 @@ int GamePadDevice::getNumberOfButtons() const // ---------------------------------------------------------------------------- bool GamePadDevice::isButtonPressed(const int i) { - if (i < m_button_pressed.size()) + if (i < (int)m_button_pressed.size()) return m_button_pressed[i]; else return false; @@ -104,7 +104,7 @@ bool GamePadDevice::isButtonPressed(const int i) void GamePadDevice::setButtonPressed(const int i, bool isButtonPressed) { - if (i < m_button_pressed.size()) + if (i < (int)m_button_pressed.size()) m_button_pressed[i] = isButtonPressed; } // setButtonPressed From d5938a244783229d23f0adba853ba0f8647e38cb Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 6 Feb 2018 08:51:17 +1100 Subject: [PATCH 5/6] Replaced old zipper handling in physics with minSpeed setting. --- src/karts/kart.cpp | 2 +- src/karts/kart_rewinder.cpp | 4 +- src/physics/btKart.cpp | 80 +++++++++++-------------------------- src/physics/btKart.hpp | 10 +---- 4 files changed, 29 insertions(+), 67 deletions(-) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 4d33e9cee..a20cca20e 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1209,7 +1209,7 @@ void Kart::eliminate() void Kart::update(float dt) { // Reset any instand speed increase in the bullet kart - m_vehicle->resetInstantSpeed(); + m_vehicle->setMinSpeed(0); // update star effect (call will do nothing if stars are not activated) m_stars_effect->update(dt); diff --git a/src/karts/kart_rewinder.cpp b/src/karts/kart_rewinder.cpp index 8de2ec2f3..8957a55c7 100644 --- a/src/karts/kart_rewinder.cpp +++ b/src/karts/kart_rewinder.cpp @@ -74,7 +74,7 @@ BareNetworkString* KartRewinder::saveState() const buffer->add(body->getLinearVelocity()); buffer->add(body->getAngularVelocity()); buffer->addUInt8(m_has_started); // necessary for startup speed boost - buffer->addFloat(m_vehicle->getInstantSpeedIncrease()); + buffer->addFloat(m_vehicle->getMinSpeed()); // 2) Steering and other player controls // ------------------------------------- @@ -120,7 +120,7 @@ void KartRewinder::rewindToState(BareNetworkString *buffer) // before Moveable::update() is called (which updates the transform) setTrans(t); m_has_started = buffer->getUInt8()!=0; // necessary for startup speed boost - m_vehicle->instantSpeedIncreaseTo(buffer->getFloat()); + m_vehicle->setMinSpeed(buffer->getFloat()); // 2) Steering and other controls // ------------------------------ diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index 34742a3a7..842fb9a21 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -118,7 +118,6 @@ void btKart::reset() updateWheelTransform(i, true); } m_visual_wheels_touch_ground = false; - m_zipper_speed = btScalar(0); m_skid_angular_velocity = 0; m_is_skidding = false; m_allow_sliding = false; @@ -773,51 +772,35 @@ void btKart::updateFriction(btScalar timeStep) (btRigidBody*) wheelInfo.m_raycastInfo.m_groundObject; if(!groundObject) continue; - if(m_zipper_speed > 0) - { - if (wheel==2 || wheel==3) - { - // The zipper velocity is the speed that should be - // reached. So compute the impulse to accelerate the - // kart up to that speed: - m_forwardImpulse[wheel] = - 0.5f*(m_zipper_speed - - getRigidBody()->getLinearVelocity().length()) - / m_chassisBody->getInvMass(); - } + btScalar rollingFriction = 0.f; + if (wheelInfo.m_engineForce != 0.f) + { + rollingFriction = wheelInfo.m_engineForce* timeStep; } else { - btScalar rollingFriction = 0.f; - - if (wheelInfo.m_engineForce != 0.f) - { - rollingFriction = wheelInfo.m_engineForce* timeStep; - } - else - { - btScalar defaultRollingFrictionImpulse = 0.f; - btScalar maxImpulse = wheelInfo.m_brake - ? wheelInfo.m_brake - : defaultRollingFrictionImpulse; - btWheelContactPoint contactPt(m_chassisBody, groundObject, - wheelInfo.m_raycastInfo.m_contactPointWS, - m_forwardWS[wheel],maxImpulse); - rollingFriction = calcRollingFriction(contactPt); - // This is a work around for the problem that a kart shakes - // if it is braking: we get a minor impulse forward, which - // bullet then tries to offset by applying a backward - // impulse - which is a bit too big, causing a impulse - // backwards, ... till the kart is shaking backwards and - // forwards. By only applying half of the impulse in case - // of low friction this goes away. - if(wheelInfo.m_brake && fabsf(rollingFriction)<10) - rollingFriction*=0.5f; - } - - m_forwardImpulse[wheel] = rollingFriction; + btScalar defaultRollingFrictionImpulse = 0.f; + btScalar maxImpulse = wheelInfo.m_brake + ? wheelInfo.m_brake + : defaultRollingFrictionImpulse; + btWheelContactPoint contactPt(m_chassisBody, groundObject, + wheelInfo.m_raycastInfo.m_contactPointWS, + m_forwardWS[wheel], maxImpulse); + rollingFriction = calcRollingFriction(contactPt); + // This is a work around for the problem that a kart shakes + // if it is braking: we get a minor impulse forward, which + // bullet then tries to offset by applying a backward + // impulse - which is a bit too big, causing a impulse + // backwards, ... till the kart is shaking backwards and + // forwards. By only applying half of the impulse in case + // of low friction this goes away. + if (wheelInfo.m_brake && fabsf(rollingFriction) < 10) + rollingFriction *= 0.5f; } + + m_forwardImpulse[wheel] = rollingFriction; + if(m_time_additional_impulse>0) { sliding = true; @@ -1017,21 +1000,6 @@ void btKart::setSliding(bool active) m_allow_sliding = active; } // setSliding -// ---------------------------------------------------------------------------- -/** Activates an additional speedup for the kart so that it reaches the - * specified speed. - * \param speed The speed to reach. - */ -void btKart::instantSpeedIncreaseTo(btScalar speed) -{ - // Avoid that a speed 'increase' might cause a slowdown - if (m_chassisBody->getLinearVelocity().length2() > speed*speed) - { - return; - } - m_zipper_speed = speed; -} // activateZipper - // ---------------------------------------------------------------------------- /** 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 diff --git a/src/physics/btKart.hpp b/src/physics/btKart.hpp index 4cb0e917e..c02e4fa5d 100644 --- a/src/physics/btKart.hpp +++ b/src/physics/btKart.hpp @@ -69,10 +69,6 @@ private: btScalar m_damping; btVehicleRaycaster *m_vehicleRaycaster; - /** The zipper speed (i.e. the velocity the kart should reach in - * the first frame that the zipper is active). */ - btScalar m_zipper_speed; - /** The angular velocity to be applied when the kart skids. * 0 means no skidding. */ btScalar m_skid_angular_velocity; @@ -282,9 +278,6 @@ public: m_time_additional_rotation = t; } // setTimedTorque // ------------------------------------------------------------------------ - /** Returns the current zipper speed. */ - float getInstantSpeedIncrease() const { return m_zipper_speed; } - // ------------------------------------------------------------------------ /** Sets the maximum speed for this kart. */ void setMaxSpeed(float new_max_speed) { @@ -304,7 +297,8 @@ public: /** Sets the minimum speed for this kart. */ void setMinSpeed(float s) { m_min_speed = s; } // ------------------------------------------------------------------------ - void resetInstantSpeed() { m_zipper_speed = 0; } + /** Returns the minimum speed for this kart. */ + btScalar getMinSpeed() const { return m_min_speed; } }; // class btKart #endif //BT_KART_HPP From 6c0f97261a527a4831d296166d760719df0636a6 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 9 Feb 2018 09:15:23 +1100 Subject: [PATCH 6/6] Fixed missing startup boost, improved maths to only use velocity in the current plane for boosting. --- src/physics/btKart.cpp | 21 +++++++++++++-------- src/physics/btKart.hpp | 7 +++++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index 842fb9a21..4d32ae01c 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -1011,17 +1011,22 @@ void btKart::adjustSpeed(btScalar min_speed, btScalar max_speed) { const btVector3 &velocity = m_chassisBody->getLinearVelocity(); float speed = velocity.length(); + + if (speed < min_speed && min_speed > 0) { - if (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); + // The speedup is only for the direction of the normal. + const btVector3 &normal = m_kart->getNormal(); + btVector3 upright_component = normal * normal.dot(velocity); + // Subtract the upright velocity component, + btVector3 v = velocity - upright_component; + const float velocity_ratio = min_speed / v.length(); + // Scale the velocity in the plane, then add the upright component + // of the velocity back in. + m_chassisBody->setLinearVelocity( v*velocity_ratio + + upright_component ); } } else if (speed >0 && max_speed >= 0 && speed > max_speed) diff --git a/src/physics/btKart.hpp b/src/physics/btKart.hpp index c02e4fa5d..69eb071ea 100644 --- a/src/physics/btKart.hpp +++ b/src/physics/btKart.hpp @@ -292,10 +292,13 @@ public: // ------------------------------------------------------------------------ /** Resets the maximum so any new maximum value from the application will * be accepted. */ - virtual void resetMaxSpeed() { m_max_speed = -1.0f; } + virtual void resetMaxSpeed() { m_max_speed = -1.0f; m_min_speed = 0.0f; } // ------------------------------------------------------------------------ /** Sets the minimum speed for this kart. */ - void setMinSpeed(float s) { m_min_speed = s; } + void setMinSpeed(float s) + { + if(s > m_min_speed) m_min_speed = s; + } // ------------------------------------------------------------------------ /** Returns the minimum speed for this kart. */ btScalar getMinSpeed() const { return m_min_speed; }