mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 01:03:57 +02:00
CharacterController jump is more reliable.
This commit is contained in:
parent
2936811484
commit
47f3ce3786
2 changed files with 61 additions and 26 deletions
|
@ -624,6 +624,13 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
|
||||
const float STATE_CHANGE_HYSTERESIS_TIMER = 0.1f;
|
||||
|
||||
// Skip hystersis timer for jump transitions.
|
||||
if (_desiredState == RigRole::Takeoff) {
|
||||
_desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER;
|
||||
} else if (_state == RigRole::InAir && _desiredState != RigRole::InAir) {
|
||||
_desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER;
|
||||
}
|
||||
|
||||
if ((_desiredStateAge >= STATE_CHANGE_HYSTERESIS_TIMER) && _desiredState != _state) {
|
||||
_state = _desiredState;
|
||||
_desiredStateAge = 0.0f;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//
|
||||
//
|
||||
// CharacterControllerInterface.cpp
|
||||
// libraries/physcis/src
|
||||
//
|
||||
|
@ -15,11 +15,14 @@
|
|||
|
||||
#include "PhysicsCollisionGroups.h"
|
||||
#include "ObjectMotionState.h"
|
||||
#include "PhysicsLogging.h"
|
||||
|
||||
const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f);
|
||||
const float JUMP_SPEED = 3.5f;
|
||||
const float MAX_FALL_HEIGHT = 20.0f;
|
||||
|
||||
#define DEBUG_STATE_CHANGE
|
||||
|
||||
// helper class for simple ray-traces from character
|
||||
class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback {
|
||||
public:
|
||||
|
@ -220,7 +223,7 @@ void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
|
|||
// Dynamicaly compute a follow velocity to move this body toward the _followDesiredBodyTransform.
|
||||
// Rather then add this velocity to velocity the RigidBody, we explicitly teleport the RigidBody towards its goal.
|
||||
// This mirrors the computation done in MyAvatar::FollowHelper::postPhysicsUpdate().
|
||||
// These two computations must be kept in sync.
|
||||
|
||||
const float MINIMUM_TIME_REMAINING = 0.005f;
|
||||
const float MAX_DISPLACEMENT = 0.5f * _radius;
|
||||
_followTimeRemaining -= dt;
|
||||
|
@ -258,18 +261,21 @@ void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
|
|||
void CharacterController::jump() {
|
||||
// check for case where user is holding down "jump" key...
|
||||
// we'll eventually transition to "hover"
|
||||
if (_state == State::Hover) {
|
||||
quint64 now = usecTimestampNow();
|
||||
const quint64 JUMP_TO_HOVER_PERIOD = 75 * (USECS_PER_SECOND / 100);
|
||||
if (now - _jumpToHoverStart > JUMP_TO_HOVER_PERIOD) {
|
||||
_isPushingUp = true;
|
||||
setState(State::Hover);
|
||||
}
|
||||
} else {
|
||||
if (_state != State::Takeoff) {
|
||||
_jumpToHoverStart = usecTimestampNow();
|
||||
if (_state != State::Takeoff) {
|
||||
if (_state == State::InAir) {
|
||||
quint64 now = usecTimestampNow();
|
||||
if (!_isPushingUp) {
|
||||
_isPushingUp = true;
|
||||
_jumpToHoverStart = now;
|
||||
}
|
||||
const quint64 JUMP_TO_HOVER_PERIOD = 750 * MSECS_PER_SECOND;
|
||||
if (now - _jumpToHoverStart > JUMP_TO_HOVER_PERIOD) {
|
||||
setState(State::Hover);
|
||||
}
|
||||
} else {
|
||||
_pendingFlags |= PENDING_FLAG_JUMP;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,19 +284,41 @@ bool CharacterController::onGround() const {
|
|||
return _floorDistance < FLOOR_PROXIMITY_THRESHOLD || _hasSupport;
|
||||
}
|
||||
|
||||
void CharacterController::setState(State desiredState) {
|
||||
if (desiredState == State::Hover && _state != State::Hover) {
|
||||
// hover enter
|
||||
if (_rigidBody) {
|
||||
_rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
} else if (_state == State::Hover && desiredState != State::Hover) {
|
||||
// hover exit
|
||||
if (_rigidBody) {
|
||||
_rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp);
|
||||
}
|
||||
#ifdef DEBUG_STATE_CHANGE
|
||||
static const char* stateToStr(CharacterController::State state) {
|
||||
switch (state) {
|
||||
case CharacterController::State::Ground:
|
||||
return "Ground";
|
||||
case CharacterController::State::Takeoff:
|
||||
return "Takeoff";
|
||||
case CharacterController::State::InAir:
|
||||
return "InAir";
|
||||
case CharacterController::State::Hover:
|
||||
return "Hover";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
#endif // #ifdef DEBUG_STATE_CHANGE
|
||||
|
||||
void CharacterController::setState(State desiredState) {
|
||||
if (desiredState != _state) {
|
||||
#ifdef DEBUG_STATE_CHANGE
|
||||
qCDebug(physics) << "CharacterController::setState" << stateToStr(desiredState) << "<-" << stateToStr(_state);
|
||||
#endif
|
||||
if (desiredState == State::Hover && _state != State::Hover) {
|
||||
// hover enter
|
||||
if (_rigidBody) {
|
||||
_rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
} else if (_state == State::Hover && desiredState != State::Hover) {
|
||||
// hover exit
|
||||
if (_rigidBody) {
|
||||
_rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp);
|
||||
}
|
||||
}
|
||||
_state = desiredState;
|
||||
}
|
||||
_state = desiredState;
|
||||
}
|
||||
|
||||
void CharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) {
|
||||
|
@ -411,6 +439,7 @@ void CharacterController::preSimulation() {
|
|||
if (_enabled && _dynamicsWorld) {
|
||||
// slam body to where it is supposed to be
|
||||
_rigidBody->setWorldTransform(_characterBodyTransform);
|
||||
btVector3 velocity = _rigidBody->getLinearVelocity();
|
||||
|
||||
// scan for distant floor
|
||||
// rayStart is at center of bottom sphere
|
||||
|
@ -431,7 +460,7 @@ void CharacterController::preSimulation() {
|
|||
}
|
||||
// TODO: use collision events rather than ray-trace test to disable jumping
|
||||
const btScalar JUMP_PROXIMITY_THRESHOLD = 0.1f * _radius;
|
||||
if (_state != State::Takeoff && (_floorDistance < JUMP_PROXIMITY_THRESHOLD || _hasSupport)) {
|
||||
if (_state != State::Takeoff && (velocity.dot(_currentUp) <= (JUMP_SPEED / 2.0f)) && ((_floorDistance < JUMP_PROXIMITY_THRESHOLD) || _hasSupport)) {
|
||||
setState(State::Ground);
|
||||
}
|
||||
} else if (!_hasSupport) {
|
||||
|
@ -454,7 +483,6 @@ void CharacterController::preSimulation() {
|
|||
setState(State::InAir);
|
||||
|
||||
_takeoffToInAirStart = now + USECS_PER_SECOND * 86500.0f;
|
||||
btVector3 velocity = _rigidBody->getLinearVelocity();
|
||||
velocity += _jumpSpeed * _currentUp;
|
||||
_rigidBody->setLinearVelocity(velocity);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue