mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 18:23:54 +02:00
expose setting avatar collisionless
This commit is contained in:
parent
ffb1bae1f0
commit
954d690b8a
7 changed files with 127 additions and 109 deletions
|
@ -3667,13 +3667,6 @@ void Application::update(float deltaTime) {
|
|||
if (nearbyEntitiesAreReadyForPhysics()) {
|
||||
_physicsEnabled = true;
|
||||
getMyAvatar()->updateMotionBehaviorFromMenu();
|
||||
} else {
|
||||
auto characterController = getMyAvatar()->getCharacterController();
|
||||
if (characterController) {
|
||||
// if we have a character controller, disable it here so the avatar doesn't get stuck due to
|
||||
// a non-loading collision hull.
|
||||
characterController->setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -502,7 +502,7 @@ Menu::Menu() {
|
|||
avatar, SLOT(updateMotionBehaviorFromMenu()),
|
||||
UNSPECIFIED_POSITION, "Developer");
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableCharacterController, 0, true,
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableAvatarCollisions, 0, true,
|
||||
avatar, SLOT(updateMotionBehaviorFromMenu()),
|
||||
UNSPECIFIED_POSITION, "Developer");
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ namespace MenuOption {
|
|||
const QString DontRenderEntitiesAsScene = "Don't Render Entities as Scene";
|
||||
const QString EchoLocalAudio = "Echo Local Audio";
|
||||
const QString EchoServerAudio = "Echo Server Audio";
|
||||
const QString EnableCharacterController = "Enable avatar collisions";
|
||||
const QString EnableAvatarCollisions = "Enable Avatar Collisions";
|
||||
const QString EnableInverseKinematics = "Enable Inverse Kinematics";
|
||||
const QString ExpandMyAvatarSimulateTiming = "Expand /myAvatar/simulation";
|
||||
const QString ExpandMyAvatarTiming = "Expand /myAvatar";
|
||||
|
|
|
@ -137,8 +137,6 @@ MyAvatar::MyAvatar(RigPointer rig) :
|
|||
connect(DependencyManager::get<AddressManager>().data(), &AddressManager::locationChangeRequired,
|
||||
this, static_cast<SlotType>(&MyAvatar::goToLocation));
|
||||
|
||||
_characterController.setEnabled(true);
|
||||
|
||||
_bodySensorMatrix = deriveBodyFromHMDSensor();
|
||||
|
||||
using namespace recording;
|
||||
|
@ -506,8 +504,8 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
}
|
||||
});
|
||||
_characterController.setFlyingAllowed(flyingAllowed);
|
||||
if (!_characterController.isEnabled() && !ghostingAllowed) {
|
||||
_characterController.setEnabled(true);
|
||||
if (!ghostingAllowed && _characterController.getCollisionGroup() == BULLET_COLLISION_GROUP_COLLISIONLESS) {
|
||||
_characterController.setCollisionGroup(BULLET_COLLISION_GROUP_MY_AVATAR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1270,7 +1268,8 @@ void MyAvatar::updateMotors() {
|
|||
_characterController.clearMotors();
|
||||
glm::quat motorRotation;
|
||||
if (_motionBehaviors & AVATAR_MOTION_ACTION_MOTOR_ENABLED) {
|
||||
if (_characterController.getState() == CharacterController::State::Hover) {
|
||||
if (_characterController.getState() == CharacterController::State::Hover ||
|
||||
_characterController.getCollisionGroup() == BULLET_COLLISION_GROUP_COLLISIONLESS) {
|
||||
motorRotation = getHead()->getCameraOrientation();
|
||||
} else {
|
||||
// non-hovering = walking: follow camera twist about vertical but not lift
|
||||
|
@ -1316,6 +1315,7 @@ void MyAvatar::prepareForPhysicsSimulation() {
|
|||
qDebug() << "Warning: getParentVelocity failed" << getID();
|
||||
parentVelocity = glm::vec3();
|
||||
}
|
||||
_characterController.handleChangedCollisionGroup();
|
||||
_characterController.setParentVelocity(parentVelocity);
|
||||
|
||||
_characterController.setPositionAndOrientation(getPosition(), getOrientation());
|
||||
|
@ -1933,13 +1933,13 @@ void MyAvatar::updateMotionBehaviorFromMenu() {
|
|||
_motionBehaviors &= ~AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED;
|
||||
}
|
||||
|
||||
setCharacterControllerEnabled(menu->isOptionChecked(MenuOption::EnableCharacterController));
|
||||
setAvatarCollisionsEnabled(menu->isOptionChecked(MenuOption::EnableAvatarCollisions));
|
||||
}
|
||||
|
||||
void MyAvatar::setCharacterControllerEnabled(bool enabled) {
|
||||
void MyAvatar::setAvatarCollisionsEnabled(bool enabled) {
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setCharacterControllerEnabled", Q_ARG(bool, enabled));
|
||||
QMetaObject::invokeMethod(this, "setAvatarCollisionsEnabled", Q_ARG(bool, enabled));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1951,11 +1951,12 @@ void MyAvatar::setCharacterControllerEnabled(bool enabled) {
|
|||
ghostingAllowed = zone->getGhostingAllowed();
|
||||
}
|
||||
}
|
||||
_characterController.setEnabled(ghostingAllowed ? enabled : true);
|
||||
int16_t group = enabled || !ghostingAllowed ? BULLET_COLLISION_GROUP_MY_AVATAR : BULLET_COLLISION_GROUP_COLLISIONLESS;
|
||||
_characterController.setCollisionGroup(group);
|
||||
}
|
||||
|
||||
bool MyAvatar::getCharacterControllerEnabled() {
|
||||
return _characterController.isEnabled();
|
||||
bool MyAvatar::getAvatarCollisionsEnabled() {
|
||||
return _characterController.getCollisionGroup() != BULLET_COLLISION_GROUP_COLLISIONLESS;
|
||||
}
|
||||
|
||||
void MyAvatar::clearDriveKeys() {
|
||||
|
@ -2063,9 +2064,6 @@ void MyAvatar::lateUpdatePalms() {
|
|||
Avatar::updatePalms();
|
||||
}
|
||||
|
||||
|
||||
static const float FOLLOW_TIME = 0.5f;
|
||||
|
||||
MyAvatar::FollowHelper::FollowHelper() {
|
||||
deactivate();
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ class MyAvatar : public Avatar {
|
|||
Q_PROPERTY(float energy READ getEnergy WRITE setEnergy)
|
||||
|
||||
Q_PROPERTY(bool hmdLeanRecenterEnabled READ getHMDLeanRecenterEnabled WRITE setHMDLeanRecenterEnabled)
|
||||
Q_PROPERTY(bool characterControllerEnabled READ getCharacterControllerEnabled WRITE setCharacterControllerEnabled)
|
||||
Q_PROPERTY(bool avatarCollisionsEnabled READ getAvatarCollisionsEnabled WRITE setAvatarCollisionsEnabled)
|
||||
|
||||
public:
|
||||
explicit MyAvatar(RigPointer rig);
|
||||
|
@ -273,8 +273,8 @@ public:
|
|||
|
||||
bool hasDriveInput() const;
|
||||
|
||||
Q_INVOKABLE void setCharacterControllerEnabled(bool enabled);
|
||||
Q_INVOKABLE bool getCharacterControllerEnabled();
|
||||
Q_INVOKABLE void setAvatarCollisionsEnabled(bool enabled);
|
||||
Q_INVOKABLE bool getAvatarCollisionsEnabled();
|
||||
|
||||
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
|
||||
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include <NumericalConstants.h>
|
||||
|
||||
#include "PhysicsCollisionGroups.h"
|
||||
#include "ObjectMotionState.h"
|
||||
#include "PhysicsLogging.h"
|
||||
|
||||
|
@ -62,10 +61,7 @@ CharacterController::CharacterMotor::CharacterMotor(const glm::vec3& vel, const
|
|||
}
|
||||
|
||||
CharacterController::CharacterController() {
|
||||
_halfHeight = 1.0f;
|
||||
|
||||
_enabled = false;
|
||||
|
||||
_halfHeight = 1.0f;
|
||||
_floorDistance = MAX_FALL_HEIGHT;
|
||||
|
||||
_targetVelocity.setValue(0.0f, 0.0f, 0.0f);
|
||||
|
@ -119,7 +115,7 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
|
|||
// Before adding the RigidBody to the world we must save its oldGravity to the side
|
||||
// because adding an object to the world will overwrite it with the default gravity.
|
||||
btVector3 oldGravity = _rigidBody->getGravity();
|
||||
_dynamicsWorld->addRigidBody(_rigidBody, BULLET_COLLISION_GROUP_MY_AVATAR, BULLET_COLLISION_MASK_MY_AVATAR);
|
||||
_dynamicsWorld->addRigidBody(_rigidBody, _collisionGroup, BULLET_COLLISION_MASK_MY_AVATAR);
|
||||
_dynamicsWorld->addAction(this);
|
||||
// restore gravity settings
|
||||
_rigidBody->setGravity(oldGravity);
|
||||
|
@ -199,7 +195,7 @@ void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
|
|||
// This mirrors the computation done in MyAvatar::FollowHelper::postPhysicsUpdate().
|
||||
|
||||
if (_following) {
|
||||
// HACK these copied form elsewhere
|
||||
// OUTOFBODY_HACK -- these consts were copied from elsewhere, and then tuned
|
||||
const float NORMAL_WALKING_SPEED = 0.5f;
|
||||
const float FOLLOW_TIME = 0.8f;
|
||||
const float FOLLOW_ROTATION_THRESHOLD = cosf(PI / 6.0f);
|
||||
|
@ -282,15 +278,17 @@ void CharacterController::setState(State desiredState) {
|
|||
#ifdef DEBUG_STATE_CHANGE
|
||||
qCDebug(physics) << "CharacterController::setState" << stateToStr(desiredState) << "from" << stateToStr(_state) << "," << reason;
|
||||
#endif
|
||||
if (desiredState == State::Hover && _state != State::Hover) {
|
||||
// hover enter
|
||||
if (_rigidBody) {
|
||||
if (_rigidBody) {
|
||||
if (desiredState == State::Hover && _state != State::Hover) {
|
||||
// hover enter
|
||||
_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);
|
||||
} else if (_state == State::Hover && desiredState != State::Hover) {
|
||||
// hover exit
|
||||
if (_collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) {
|
||||
_rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f));
|
||||
} else {
|
||||
_rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp);
|
||||
}
|
||||
}
|
||||
}
|
||||
_state = desiredState;
|
||||
|
@ -320,39 +318,45 @@ void CharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm
|
|||
_pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION;
|
||||
}
|
||||
_pendingFlags |= PENDING_FLAG_UPDATE_SHAPE;
|
||||
// only need to ADD back when we happen to be enabled
|
||||
if (_enabled) {
|
||||
_pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION;
|
||||
}
|
||||
_pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION;
|
||||
}
|
||||
|
||||
// it's ok to change offset immediately -- there are no thread safety issues here
|
||||
_shapeLocalOffset = corner + 0.5f * _boxScale;
|
||||
}
|
||||
|
||||
void CharacterController::setEnabled(bool enabled) {
|
||||
if (enabled != _enabled) {
|
||||
if (enabled) {
|
||||
// Don't bother clearing REMOVE bit since it might be paired with an UPDATE_SHAPE bit.
|
||||
// Setting the ADD bit here works for all cases so we don't even bother checking other bits.
|
||||
_pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION;
|
||||
} else {
|
||||
if (_dynamicsWorld) {
|
||||
_pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION;
|
||||
}
|
||||
_pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION;
|
||||
void CharacterController::setCollisionGroup(int16_t group) {
|
||||
if (_collisionGroup != group) {
|
||||
_collisionGroup = group;
|
||||
_pendingFlags |= PENDING_FLAG_UPDATE_COLLISION_GROUP;
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterController::handleChangedCollisionGroup() {
|
||||
if (_pendingFlags & PENDING_FLAG_UPDATE_COLLISION_GROUP) {
|
||||
// ATM the easiest way to update collision groups is to remove/re-add the RigidBody
|
||||
if (_dynamicsWorld) {
|
||||
_dynamicsWorld->removeRigidBody(_rigidBody);
|
||||
_dynamicsWorld->addRigidBody(_rigidBody, _collisionGroup, BULLET_COLLISION_MASK_MY_AVATAR);
|
||||
}
|
||||
_pendingFlags &= ~PENDING_FLAG_UPDATE_COLLISION_GROUP;
|
||||
|
||||
if (_state != State::Hover && _rigidBody) {
|
||||
if (_collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) {
|
||||
_rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f));
|
||||
} else {
|
||||
_rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp);
|
||||
}
|
||||
}
|
||||
SET_STATE(State::Hover, "setEnabled");
|
||||
_enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterController::updateUpAxis(const glm::quat& rotation) {
|
||||
btVector3 oldUp = _currentUp;
|
||||
_currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS);
|
||||
if (_state != State::Hover) {
|
||||
const btScalar MIN_UP_ERROR = 0.01f;
|
||||
if (oldUp.distance(_currentUp) > MIN_UP_ERROR) {
|
||||
if (_state != State::Hover && _rigidBody) {
|
||||
if (_collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) {
|
||||
_rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f));
|
||||
} else {
|
||||
_rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp);
|
||||
}
|
||||
}
|
||||
|
@ -370,7 +374,7 @@ void CharacterController::setPositionAndOrientation(
|
|||
}
|
||||
|
||||
void CharacterController::getPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const {
|
||||
if (_enabled && _rigidBody) {
|
||||
if (_rigidBody) {
|
||||
const btTransform& avatarTransform = _rigidBody->getWorldTransform();
|
||||
rotation = bulletToGLM(avatarTransform.getRotation());
|
||||
position = bulletToGLM(avatarTransform.getOrigin()) - rotation * _shapeLocalOffset;
|
||||
|
@ -438,7 +442,8 @@ void CharacterController::applyMotor(int index, btScalar dt, btVector3& worldVel
|
|||
btScalar angle = motor.rotation.getAngle();
|
||||
btVector3 velocity = worldVelocity.rotate(axis, -angle);
|
||||
|
||||
if (_state == State::Hover || motor.hTimescale == motor.vTimescale) {
|
||||
if (_collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS ||
|
||||
_state == State::Hover || motor.hTimescale == motor.vTimescale) {
|
||||
// modify velocity
|
||||
btScalar tau = dt / motor.hTimescale;
|
||||
if (tau > 1.0f) {
|
||||
|
@ -534,7 +539,7 @@ void CharacterController::computeNewVelocity(btScalar dt, glm::vec3& velocity) {
|
|||
}
|
||||
|
||||
void CharacterController::preSimulation() {
|
||||
if (_enabled && _dynamicsWorld) {
|
||||
if (_dynamicsWorld) {
|
||||
quint64 now = usecTimestampNow();
|
||||
|
||||
// slam body to where it is supposed to be
|
||||
|
@ -584,51 +589,61 @@ void CharacterController::preSimulation() {
|
|||
btVector3 actualHorizVelocity = velocity - velocity.dot(_currentUp) * _currentUp;
|
||||
bool flyingFast = _state == State::Hover && actualHorizVelocity.length() > (MAX_WALKING_SPEED * 0.75f);
|
||||
|
||||
switch (_state) {
|
||||
case State::Ground:
|
||||
if (!rayHasHit && !_hasSupport) {
|
||||
SET_STATE(State::Hover, "no ground detected");
|
||||
} else if (_pendingFlags & PENDING_FLAG_JUMP && _jumpButtonDownCount != _takeoffJumpButtonID) {
|
||||
_takeoffJumpButtonID = _jumpButtonDownCount;
|
||||
_takeoffToInAirStartTime = now;
|
||||
SET_STATE(State::Takeoff, "jump pressed");
|
||||
} else if (rayHasHit && !_hasSupport && _floorDistance > GROUND_TO_FLY_THRESHOLD) {
|
||||
SET_STATE(State::InAir, "falling");
|
||||
// OUTOFBODY_HACK -- disable normal state transitions while collisionless
|
||||
if (_collisionGroup == BULLET_COLLISION_GROUP_MY_AVATAR) {
|
||||
switch (_state) {
|
||||
case State::Ground:
|
||||
if (!rayHasHit && !_hasSupport) {
|
||||
SET_STATE(State::Hover, "no ground detected");
|
||||
} else if (_pendingFlags & PENDING_FLAG_JUMP && _jumpButtonDownCount != _takeoffJumpButtonID) {
|
||||
_takeoffJumpButtonID = _jumpButtonDownCount;
|
||||
_takeoffToInAirStartTime = now;
|
||||
SET_STATE(State::Takeoff, "jump pressed");
|
||||
} else if (rayHasHit && !_hasSupport && _floorDistance > GROUND_TO_FLY_THRESHOLD) {
|
||||
SET_STATE(State::InAir, "falling");
|
||||
}
|
||||
break;
|
||||
case State::Takeoff:
|
||||
if (!rayHasHit && !_hasSupport) {
|
||||
SET_STATE(State::Hover, "no ground");
|
||||
} else if ((now - _takeoffToInAirStartTime) > TAKE_OFF_TO_IN_AIR_PERIOD) {
|
||||
SET_STATE(State::InAir, "takeoff done");
|
||||
velocity += _jumpSpeed * _currentUp;
|
||||
_rigidBody->setLinearVelocity(velocity);
|
||||
}
|
||||
break;
|
||||
case State::InAir: {
|
||||
if ((velocity.dot(_currentUp) <= (JUMP_SPEED / 2.0f)) && ((_floorDistance < FLY_TO_GROUND_THRESHOLD) || _hasSupport)) {
|
||||
SET_STATE(State::Ground, "hit ground");
|
||||
} else {
|
||||
btVector3 desiredVelocity = _targetVelocity;
|
||||
if (desiredVelocity.length2() < MIN_TARGET_SPEED_SQUARED) {
|
||||
desiredVelocity = btVector3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
bool vertTargetSpeedIsNonZero = desiredVelocity.dot(_currentUp) > MIN_TARGET_SPEED;
|
||||
if ((jumpButtonHeld || vertTargetSpeedIsNonZero) && (_takeoffJumpButtonID != _jumpButtonDownCount)) {
|
||||
SET_STATE(State::Hover, "double jump button");
|
||||
} else if ((jumpButtonHeld || vertTargetSpeedIsNonZero) && (now - _jumpButtonDownStartTime) > JUMP_TO_HOVER_PERIOD) {
|
||||
SET_STATE(State::Hover, "jump button held");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case State::Takeoff:
|
||||
if (!rayHasHit && !_hasSupport) {
|
||||
SET_STATE(State::Hover, "no ground");
|
||||
} else if ((now - _takeoffToInAirStartTime) > TAKE_OFF_TO_IN_AIR_PERIOD) {
|
||||
SET_STATE(State::InAir, "takeoff done");
|
||||
velocity += _jumpSpeed * _currentUp;
|
||||
_rigidBody->setLinearVelocity(velocity);
|
||||
case State::Hover:
|
||||
if ((_floorDistance < MIN_HOVER_HEIGHT) && !jumpButtonHeld && !flyingFast) {
|
||||
SET_STATE(State::InAir, "near ground");
|
||||
} else if (((_floorDistance < FLY_TO_GROUND_THRESHOLD) || _hasSupport) && !flyingFast) {
|
||||
SET_STATE(State::Ground, "touching ground");
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case State::InAir: {
|
||||
if ((velocity.dot(_currentUp) <= (JUMP_SPEED / 2.0f)) && ((_floorDistance < FLY_TO_GROUND_THRESHOLD) || _hasSupport)) {
|
||||
SET_STATE(State::Ground, "hit ground");
|
||||
} else {
|
||||
// OUTOFBODY_HACK -- in collisionless state switch between Ground and Hover states
|
||||
if (rayHasHit) {
|
||||
SET_STATE(State::Ground, "collisionless above ground");
|
||||
} else {
|
||||
btVector3 desiredVelocity = _targetVelocity;
|
||||
if (desiredVelocity.length2() < MIN_TARGET_SPEED_SQUARED) {
|
||||
desiredVelocity = btVector3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
bool vertTargetSpeedIsNonZero = desiredVelocity.dot(_currentUp) > MIN_TARGET_SPEED;
|
||||
if ((jumpButtonHeld || vertTargetSpeedIsNonZero) && (_takeoffJumpButtonID != _jumpButtonDownCount)) {
|
||||
SET_STATE(State::Hover, "double jump button");
|
||||
} else if ((jumpButtonHeld || vertTargetSpeedIsNonZero) && (now - _jumpButtonDownStartTime) > JUMP_TO_HOVER_PERIOD) {
|
||||
SET_STATE(State::Hover, "jump button held");
|
||||
}
|
||||
SET_STATE(State::Hover, "collisionless in air");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case State::Hover:
|
||||
if ((_floorDistance < MIN_HOVER_HEIGHT) && !jumpButtonHeld && !flyingFast) {
|
||||
SET_STATE(State::InAir, "near ground");
|
||||
} else if (((_floorDistance < FLY_TO_GROUND_THRESHOLD) || _hasSupport) && !flyingFast) {
|
||||
SET_STATE(State::Ground, "touching ground");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -664,7 +679,10 @@ void CharacterController::setFlyingAllowed(bool value) {
|
|||
_flyingAllowed = value;
|
||||
|
||||
if (!_flyingAllowed && _state == State::Hover) {
|
||||
SET_STATE(State::InAir, "flying not allowed");
|
||||
// OUTOFBODY_HACK -- disable normal state transitions while collisionless
|
||||
if (_collisionGroup == BULLET_COLLISION_GROUP_MY_AVATAR) {
|
||||
SET_STATE(State::InAir, "flying not allowed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,15 @@
|
|||
#include <BulletDynamics/Character/btCharacterControllerInterface.h>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <PhysicsCollisionGroups.h>
|
||||
|
||||
#include "BulletUtil.h"
|
||||
|
||||
const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0;
|
||||
const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1;
|
||||
const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2;
|
||||
const uint32_t PENDING_FLAG_JUMP = 1U << 3;
|
||||
const uint32_t PENDING_FLAG_UPDATE_COLLISION_GROUP = 1U << 4;
|
||||
|
||||
const float DEFAULT_CHARACTER_GRAVITY = -5.0f;
|
||||
|
||||
|
@ -107,9 +110,15 @@ public:
|
|||
|
||||
void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale);
|
||||
|
||||
/*
|
||||
bool isEnabled() const { return _enabled; } // thread-safe
|
||||
void setEnabled(bool enabled);
|
||||
bool isEnabledAndReady() const { return _enabled && _dynamicsWorld; }
|
||||
*/
|
||||
bool isEnabledAndReady() const { return _dynamicsWorld; }
|
||||
|
||||
void setCollisionGroup(int16_t group);
|
||||
int16_t getCollisionGroup() const { return _collisionGroup; }
|
||||
void handleChangedCollisionGroup();
|
||||
|
||||
bool getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
|
||||
|
||||
|
@ -170,7 +179,6 @@ protected:
|
|||
btVector3 _linearAcceleration;
|
||||
bool _following { false };
|
||||
|
||||
std::atomic_bool _enabled;
|
||||
State _state;
|
||||
bool _isPushingUp;
|
||||
|
||||
|
@ -180,6 +188,7 @@ protected:
|
|||
uint32_t _previousFlags { 0 };
|
||||
|
||||
bool _flyingAllowed { true };
|
||||
int16_t _collisionGroup { BULLET_COLLISION_GROUP_MY_AVATAR };
|
||||
};
|
||||
|
||||
#endif // hifi_CharacterControllerInterface_h
|
||||
|
|
Loading…
Reference in a new issue