mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 02:03:11 +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;
|
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) {
|
if ((_desiredStateAge >= STATE_CHANGE_HYSTERESIS_TIMER) && _desiredState != _state) {
|
||||||
_state = _desiredState;
|
_state = _desiredState;
|
||||||
_desiredStateAge = 0.0f;
|
_desiredStateAge = 0.0f;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//
|
//
|
||||||
// CharacterControllerInterface.cpp
|
// CharacterControllerInterface.cpp
|
||||||
// libraries/physcis/src
|
// libraries/physcis/src
|
||||||
//
|
//
|
||||||
|
@ -15,11 +15,14 @@
|
||||||
|
|
||||||
#include "PhysicsCollisionGroups.h"
|
#include "PhysicsCollisionGroups.h"
|
||||||
#include "ObjectMotionState.h"
|
#include "ObjectMotionState.h"
|
||||||
|
#include "PhysicsLogging.h"
|
||||||
|
|
||||||
const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f);
|
const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f);
|
||||||
const float JUMP_SPEED = 3.5f;
|
const float JUMP_SPEED = 3.5f;
|
||||||
const float MAX_FALL_HEIGHT = 20.0f;
|
const float MAX_FALL_HEIGHT = 20.0f;
|
||||||
|
|
||||||
|
#define DEBUG_STATE_CHANGE
|
||||||
|
|
||||||
// helper class for simple ray-traces from character
|
// helper class for simple ray-traces from character
|
||||||
class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback {
|
class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback {
|
||||||
public:
|
public:
|
||||||
|
@ -220,7 +223,7 @@ void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
|
||||||
// Dynamicaly compute a follow velocity to move this body toward the _followDesiredBodyTransform.
|
// 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.
|
// 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().
|
// 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 MINIMUM_TIME_REMAINING = 0.005f;
|
||||||
const float MAX_DISPLACEMENT = 0.5f * _radius;
|
const float MAX_DISPLACEMENT = 0.5f * _radius;
|
||||||
_followTimeRemaining -= dt;
|
_followTimeRemaining -= dt;
|
||||||
|
@ -258,18 +261,21 @@ void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
|
||||||
void CharacterController::jump() {
|
void CharacterController::jump() {
|
||||||
// check for case where user is holding down "jump" key...
|
// check for case where user is holding down "jump" key...
|
||||||
// we'll eventually transition to "hover"
|
// we'll eventually transition to "hover"
|
||||||
if (_state == State::Hover) {
|
if (_state != State::Takeoff) {
|
||||||
quint64 now = usecTimestampNow();
|
if (_state == State::InAir) {
|
||||||
const quint64 JUMP_TO_HOVER_PERIOD = 75 * (USECS_PER_SECOND / 100);
|
quint64 now = usecTimestampNow();
|
||||||
if (now - _jumpToHoverStart > JUMP_TO_HOVER_PERIOD) {
|
if (!_isPushingUp) {
|
||||||
_isPushingUp = true;
|
_isPushingUp = true;
|
||||||
setState(State::Hover);
|
_jumpToHoverStart = now;
|
||||||
}
|
}
|
||||||
} else {
|
const quint64 JUMP_TO_HOVER_PERIOD = 750 * MSECS_PER_SECOND;
|
||||||
if (_state != State::Takeoff) {
|
if (now - _jumpToHoverStart > JUMP_TO_HOVER_PERIOD) {
|
||||||
_jumpToHoverStart = usecTimestampNow();
|
setState(State::Hover);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
_pendingFlags |= PENDING_FLAG_JUMP;
|
_pendingFlags |= PENDING_FLAG_JUMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,19 +284,41 @@ bool CharacterController::onGround() const {
|
||||||
return _floorDistance < FLOOR_PROXIMITY_THRESHOLD || _hasSupport;
|
return _floorDistance < FLOOR_PROXIMITY_THRESHOLD || _hasSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::setState(State desiredState) {
|
#ifdef DEBUG_STATE_CHANGE
|
||||||
if (desiredState == State::Hover && _state != State::Hover) {
|
static const char* stateToStr(CharacterController::State state) {
|
||||||
// hover enter
|
switch (state) {
|
||||||
if (_rigidBody) {
|
case CharacterController::State::Ground:
|
||||||
_rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f));
|
return "Ground";
|
||||||
}
|
case CharacterController::State::Takeoff:
|
||||||
} else if (_state == State::Hover && desiredState != State::Hover) {
|
return "Takeoff";
|
||||||
// hover exit
|
case CharacterController::State::InAir:
|
||||||
if (_rigidBody) {
|
return "InAir";
|
||||||
_rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp);
|
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) {
|
void CharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) {
|
||||||
|
@ -411,6 +439,7 @@ void CharacterController::preSimulation() {
|
||||||
if (_enabled && _dynamicsWorld) {
|
if (_enabled && _dynamicsWorld) {
|
||||||
// slam body to where it is supposed to be
|
// slam body to where it is supposed to be
|
||||||
_rigidBody->setWorldTransform(_characterBodyTransform);
|
_rigidBody->setWorldTransform(_characterBodyTransform);
|
||||||
|
btVector3 velocity = _rigidBody->getLinearVelocity();
|
||||||
|
|
||||||
// scan for distant floor
|
// scan for distant floor
|
||||||
// rayStart is at center of bottom sphere
|
// 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
|
// TODO: use collision events rather than ray-trace test to disable jumping
|
||||||
const btScalar JUMP_PROXIMITY_THRESHOLD = 0.1f * _radius;
|
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);
|
setState(State::Ground);
|
||||||
}
|
}
|
||||||
} else if (!_hasSupport) {
|
} else if (!_hasSupport) {
|
||||||
|
@ -454,7 +483,6 @@ void CharacterController::preSimulation() {
|
||||||
setState(State::InAir);
|
setState(State::InAir);
|
||||||
|
|
||||||
_takeoffToInAirStart = now + USECS_PER_SECOND * 86500.0f;
|
_takeoffToInAirStart = now + USECS_PER_SECOND * 86500.0f;
|
||||||
btVector3 velocity = _rigidBody->getLinearVelocity();
|
|
||||||
velocity += _jumpSpeed * _currentUp;
|
velocity += _jumpSpeed * _currentUp;
|
||||||
_rigidBody->setLinearVelocity(velocity);
|
_rigidBody->setLinearVelocity(velocity);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue