From 9292a9ce0b244579900f66143795ffb4ef29bd2f Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 3 Jun 2016 13:56:32 -0700 Subject: [PATCH 1/3] Added MyAvatar.hmdLeanRecenterEnabled property Used to disable the 'room-scale' avatar re-centering code. Disabling this can prevent sliding when the avatar is supposed to be sitting or mounted on a stationary object. Also, removed a bunch of old, unused leaning and torso twisting code. --- interface/src/avatar/Avatar.cpp | 1 - interface/src/avatar/Avatar.h | 1 - interface/src/avatar/Head.cpp | 21 +-------------- interface/src/avatar/Head.h | 9 +------ interface/src/avatar/MyAvatar.cpp | 36 +++++++++----------------- interface/src/avatar/MyAvatar.h | 11 +++++--- interface/src/avatar/SkeletonModel.cpp | 5 ---- interface/src/ui/PreferencesDialog.cpp | 10 ------- libraries/animation/src/Rig.cpp | 14 ---------- libraries/animation/src/Rig.h | 6 ----- libraries/avatars/src/HeadData.cpp | 15 ----------- libraries/avatars/src/HeadData.h | 14 ---------- 12 files changed, 21 insertions(+), 122 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 3e22448386..f46a906af8 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -84,7 +84,6 @@ Avatar::Avatar(RigPointer rig) : _acceleration(0.0f), _lastAngularVelocity(0.0f), _lastOrientation(), - _leanScale(0.5f), _worldUpDirection(DEFAULT_UP_DIRECTION), _moving(false), _initialized(false), diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 79952e8f58..064f0a9533 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -210,7 +210,6 @@ protected: glm::vec3 _angularAcceleration; glm::quat _lastOrientation; - float _leanScale; glm::vec3 _worldUpDirection; float _stringLength; bool _moving; ///< set when position is changing diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 3af8b8a423..928f46facb 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -54,8 +54,6 @@ Head::Head(Avatar* owningAvatar) : _deltaPitch(0.0f), _deltaYaw(0.0f), _deltaRoll(0.0f), - _deltaLeanSideways(0.0f), - _deltaLeanForward(0.0f), _isCameraMoving(false), _isLookingAtMe(false), _lookingAtMeStarted(0), @@ -70,7 +68,6 @@ void Head::init() { void Head::reset() { _baseYaw = _basePitch = _baseRoll = 0.0f; - _leanForward = _leanSideways = 0.0f; } void Head::simulate(float deltaTime, bool isMine, bool billboard) { @@ -118,13 +115,6 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { auto eyeTracker = DependencyManager::get(); _isEyeTrackerConnected = eyeTracker->isTracking(); } - - // Twist the upper body to follow the rotation of the head, but only do this with my avatar, - // since everyone else will see the full joint rotations for other people. - const float BODY_FOLLOW_HEAD_YAW_RATE = 0.1f; - const float BODY_FOLLOW_HEAD_FACTOR = 0.66f; - float currentTwist = getTorsoTwist(); - setTorsoTwist(currentTwist + (getFinalYaw() * BODY_FOLLOW_HEAD_FACTOR - currentTwist) * BODY_FOLLOW_HEAD_YAW_RATE); } if (!(_isFaceTrackerConnected || billboard)) { @@ -301,17 +291,13 @@ void Head::applyEyelidOffset(glm::quat headOrientation) { } } -void Head::relaxLean(float deltaTime) { +void Head::relax(float deltaTime) { // restore rotation, lean to neutral positions const float LEAN_RELAXATION_PERIOD = 0.25f; // seconds float relaxationFactor = 1.0f - glm::min(deltaTime / LEAN_RELAXATION_PERIOD, 1.0f); _deltaYaw *= relaxationFactor; _deltaPitch *= relaxationFactor; _deltaRoll *= relaxationFactor; - _leanSideways *= relaxationFactor; - _leanForward *= relaxationFactor; - _deltaLeanSideways *= relaxationFactor; - _deltaLeanForward *= relaxationFactor; } void Head::setScale (float scale) { @@ -419,8 +405,3 @@ float Head::getFinalPitch() const { float Head::getFinalRoll() const { return glm::clamp(_baseRoll + _deltaRoll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } - -void Head::addLeanDeltas(float sideways, float forward) { - _deltaLeanSideways += sideways; - _deltaLeanForward += forward; -} diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index e4b8fefea5..33ea180d33 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -59,8 +59,6 @@ public: glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } glm::vec3 getUpDirection() const { return getOrientation() * IDENTITY_UP; } glm::vec3 getFrontDirection() const { return getOrientation() * IDENTITY_FRONT; } - float getFinalLeanSideways() const { return _leanSideways + _deltaLeanSideways; } - float getFinalLeanForward() const { return _leanForward + _deltaLeanForward; } glm::quat getEyeRotation(const glm::vec3& eyePosition) const; @@ -91,8 +89,7 @@ public: virtual float getFinalYaw() const; virtual float getFinalRoll() const; - void relaxLean(float deltaTime); - void addLeanDeltas(float sideways, float forward); + void relax(float deltaTime); float getTimeWithoutTalking() const { return _timeWithoutTalking; } @@ -132,10 +129,6 @@ private: float _deltaYaw; float _deltaRoll; - // delta lean angles for lean perturbations (driven by collisions) - float _deltaLeanSideways; - float _deltaLeanForward; - bool _isCameraMoving; bool _isLookingAtMe; quint64 _lookingAtMeStarted; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6fdcd8f797..0f723d29e3 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -190,9 +190,6 @@ MyAvatar::MyAvatar(RigPointer rig) : if (!headData->getBlendshapeCoefficients().isEmpty()) { _headData->setBlendshapeCoefficients(headData->getBlendshapeCoefficients()); } - // head lean - _headData->setLeanForward(headData->getLeanForward()); - _headData->setLeanSideways(headData->getLeanSideways()); // head orientation _headData->setLookAtPosition(headData->getLookAtPosition()); } @@ -306,7 +303,7 @@ void MyAvatar::update(float deltaTime) { } Head* head = getHead(); - head->relaxLean(deltaTime); + head->relax(deltaTime); updateFromTrackers(deltaTime); // Get audio loudness data from audio input device @@ -574,16 +571,6 @@ void MyAvatar::updateFromTrackers(float deltaTime) { head->setDeltaYaw(estimatedRotation.y * magnifyFieldOfView); head->setDeltaRoll(estimatedRotation.z); } - - // Update torso lean distance based on accelerometer data - const float TORSO_LENGTH = 0.5f; - glm::vec3 relativePosition = estimatedPosition - glm::vec3(0.0f, -TORSO_LENGTH, 0.0f); - - const float MAX_LEAN = 45.0f; - head->setLeanSideways(glm::clamp(glm::degrees(atanf(relativePosition.x * _leanScale / TORSO_LENGTH)), - -MAX_LEAN, MAX_LEAN)); - head->setLeanForward(glm::clamp(glm::degrees(atanf(relativePosition.z * _leanScale / TORSO_LENGTH)), - -MAX_LEAN, MAX_LEAN)); } glm::vec3 MyAvatar::getLeftHandPosition() const { @@ -692,7 +679,6 @@ void MyAvatar::saveData() { settings.setValue("headPitch", getHead()->getBasePitch()); - settings.setValue("leanScale", _leanScale); settings.setValue("scale", _targetScale); settings.setValue("fullAvatarURL", @@ -809,7 +795,6 @@ void MyAvatar::loadData() { getHead()->setBasePitch(loadSetting(settings, "headPitch", 0.0f)); - _leanScale = loadSetting(settings, "leanScale", 0.05f); _targetScale = loadSetting(settings, "scale", 1.0f); setScale(glm::vec3(_targetScale)); @@ -2052,14 +2037,17 @@ bool MyAvatar::FollowHelper::shouldActivateVertical(const MyAvatar& myAvatar, co void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix, bool hasDriveInput) { _desiredBodyMatrix = desiredBodyMatrix; - if (!isActive(Rotation) && shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix)) { - activate(Rotation); - } - if (!isActive(Horizontal) && shouldActivateHorizontal(myAvatar, desiredBodyMatrix, currentBodyMatrix)) { - activate(Horizontal); - } - if (!isActive(Vertical) && (shouldActivateVertical(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { - activate(Vertical); + + if (myAvatar.getHMDLeanRecenterEnabled()) { + if (!isActive(Rotation) && shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix)) { + activate(Rotation); + } + if (!isActive(Horizontal) && shouldActivateHorizontal(myAvatar, desiredBodyMatrix, currentBodyMatrix)) { + activate(Horizontal); + } + if (!isActive(Vertical) && (shouldActivateVertical(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { + activate(Vertical); + } } glm::mat4 desiredWorldMatrix = myAvatar.getSensorToWorldMatrix() * _desiredBodyMatrix; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index d3da32e0ed..a938aea675 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -69,7 +69,6 @@ class MyAvatar : public Avatar { Q_PROPERTY(AudioListenerMode audioListenerModeCustom READ getAudioListenerModeCustom) //TODO: make gravity feature work Q_PROPERTY(glm::vec3 gravity READ getGravity WRITE setGravity) - Q_PROPERTY(glm::vec3 leftHandPosition READ getLeftHandPosition) Q_PROPERTY(glm::vec3 rightHandPosition READ getRightHandPosition) Q_PROPERTY(glm::vec3 leftHandTipPosition READ getLeftHandTipPosition) @@ -84,6 +83,8 @@ class MyAvatar : public Avatar { Q_PROPERTY(float energy READ getEnergy WRITE setEnergy) + Q_PROPERTY(bool hmdLeanRecenterEnabled READ getHMDLeanRecenterEnabled WRITE setHMDLeanRecenterEnabled) + public: explicit MyAvatar(RigPointer rig); ~MyAvatar(); @@ -123,9 +124,6 @@ public: void setRealWorldFieldOfView(float realWorldFov) { _realWorldFieldOfView.set(realWorldFov); } - void setLeanScale(float scale) { _leanScale = scale; } - float getLeanScale() const { return _leanScale; } - Q_INVOKABLE glm::vec3 getDefaultEyePosition() const; float getRealWorldFieldOfView() { return _realWorldFieldOfView.get(); } @@ -163,6 +161,9 @@ public: Q_INVOKABLE bool getClearOverlayWhenDriving() const { return _clearOverlayWhenDriving; } Q_INVOKABLE void setClearOverlayWhenDriving(bool on) { _clearOverlayWhenDriving = on; } + Q_INVOKABLE void setHMDLeanRecenterEnabled(bool value) { _hmdLeanRecenterEnabled = value; } + Q_INVOKABLE bool getHMDLeanRecenterEnabled() const { return _hmdLeanRecenterEnabled; } + // get/set avatar data void saveData(); void loadData(); @@ -470,6 +471,8 @@ private: ThreadSafeValueCache _leftHandControllerPoseInSensorFrameCache { controller::Pose() }; ThreadSafeValueCache _rightHandControllerPoseInSensorFrameCache { controller::Pose() }; + bool _hmdLeanRecenterEnabled = true; + float AVATAR_MOVEMENT_ENERGY_CONSTANT { 0.001f }; float AUDIO_ENERGY_CONSTANT { 0.000001f }; float MAX_AVATAR_MOVEMENT_PER_FRAME { 30.0f }; diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 5deeb545a1..889f0ef36b 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -106,10 +106,6 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { MyAvatar* myAvatar = static_cast(_owningAvatar); Rig::HeadParameters headParams; - headParams.enableLean = qApp->isHMDMode(); - headParams.leanSideways = head->getFinalLeanSideways(); - headParams.leanForward = head->getFinalLeanForward(); - headParams.torsoTwist = head->getTorsoTwist(); if (qApp->isHMDMode()) { headParams.isInHMD = true; @@ -131,7 +127,6 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { headParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame(); } - headParams.leanJointIndex = geometry.leanJointIndex; headParams.neckJointIndex = geometry.neckJointIndex; headParams.isTalking = head->getTimeWithoutTalking() <= 1.5f; diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index ce7bcc6323..6decef3240 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -129,16 +129,6 @@ void setupPreferences() { preference->setStep(1); preferences->addPreference(preference); } - { - auto getter = [=]()->float { return myAvatar->getLeanScale(); }; - auto setter = [=](float value) { myAvatar->setLeanScale(value); }; - auto preference = new SpinnerPreference(AVATAR_TUNING, "Lean scale (applies to Faceshift users)", getter, setter); - preference->setMin(0); - preference->setMax(99.9f); - preference->setDecimals(2); - preference->setStep(1); - preferences->addPreference(preference); - } { auto getter = [=]()->float { return myAvatar->getUniformScale(); }; auto setter = [=](float value) { myAvatar->setTargetScaleVerbose(value); }; // The hell? diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 9bba9ffc33..b21f5a0e84 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -931,11 +931,6 @@ glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) { } void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) { - if (params.enableLean) { - updateLeanJoint(params.leanJointIndex, params.leanSideways, params.leanForward, params.torsoTwist); - } else { - _animVars.unset("lean"); - } updateNeckJoint(params.neckJointIndex, params); _animVars.set("isTalking", params.isTalking); @@ -953,15 +948,6 @@ static const glm::vec3 X_AXIS(1.0f, 0.0f, 0.0f); static const glm::vec3 Y_AXIS(0.0f, 1.0f, 0.0f); static const glm::vec3 Z_AXIS(0.0f, 0.0f, 1.0f); -void Rig::updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist) { - if (isIndexValid(index)) { - glm::quat absRot = (glm::angleAxis(-RADIANS_PER_DEGREE * leanSideways, Z_AXIS) * - glm::angleAxis(-RADIANS_PER_DEGREE * leanForward, X_AXIS) * - glm::angleAxis(RADIANS_PER_DEGREE * torsoTwist, Y_AXIS)); - _animVars.set("lean", absRot); - } -} - void Rig::computeHeadNeckAnimVars(const AnimPose& hmdPose, glm::vec3& headPositionOut, glm::quat& headOrientationOut, glm::vec3& neckPositionOut, glm::quat& neckOrientationOut) const { diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 891d9fdb92..e2193e8479 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -42,15 +42,10 @@ public: }; struct HeadParameters { - float leanSideways = 0.0f; // degrees - float leanForward = 0.0f; // degrees - float torsoTwist = 0.0f; // degrees - bool enableLean = false; glm::quat worldHeadOrientation = glm::quat(); // world space (-z forward) glm::quat rigHeadOrientation = glm::quat(); // rig space (-z forward) glm::vec3 rigHeadPosition = glm::vec3(); // rig space bool isInHMD = false; - int leanJointIndex = -1; int neckJointIndex = -1; bool isTalking = false; }; @@ -222,7 +217,6 @@ protected: void applyOverridePoses(); void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut); - void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist); void updateNeckJoint(int index, const HeadParameters& params); void computeHeadNeckAnimVars(const AnimPose& hmdPose, glm::vec3& headPositionOut, glm::quat& headOrientationOut, glm::vec3& neckPositionOut, glm::quat& neckOrientationOut) const; diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index 1aee85b2cd..72516d9740 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -31,9 +31,6 @@ HeadData::HeadData(AvatarData* owningAvatar) : _baseYaw(0.0f), _basePitch(0.0f), _baseRoll(0.0f), - _leanSideways(0.0f), - _leanForward(0.0f), - _torsoTwist(0.0f), _lookAtPosition(0.0f, 0.0f, 0.0f), _audioLoudness(0.0f), _isFaceTrackerConnected(false), @@ -132,12 +129,6 @@ QJsonObject HeadData::toJson() const { if (getRawOrientation() != quat()) { headJson[JSON_AVATAR_HEAD_ROTATION] = toJsonValue(getRawOrientation()); } - if (getLeanForward() != 0.0f) { - headJson[JSON_AVATAR_HEAD_LEAN_FORWARD] = getLeanForward(); - } - if (getLeanSideways() != 0.0f) { - headJson[JSON_AVATAR_HEAD_LEAN_SIDEWAYS] = getLeanSideways(); - } auto lookat = getLookAtPosition(); if (lookat != vec3()) { vec3 relativeLookAt = glm::inverse(_owningAvatar->getOrientation()) * @@ -171,12 +162,6 @@ void HeadData::fromJson(const QJsonObject& json) { if (json.contains(JSON_AVATAR_HEAD_ROTATION)) { setOrientation(quatFromJsonValue(json[JSON_AVATAR_HEAD_ROTATION])); } - if (json.contains(JSON_AVATAR_HEAD_LEAN_FORWARD)) { - setLeanForward((float)json[JSON_AVATAR_HEAD_LEAN_FORWARD].toDouble()); - } - if (json.contains(JSON_AVATAR_HEAD_LEAN_SIDEWAYS)) { - setLeanSideways((float)json[JSON_AVATAR_HEAD_LEAN_SIDEWAYS].toDouble()); - } if (json.contains(JSON_AVATAR_HEAD_LOOKAT)) { auto relativeLookAt = vec3FromJsonValue(json[JSON_AVATAR_HEAD_LOOKAT]); diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index 535aa12847..af657339ba 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -68,17 +68,6 @@ public: const glm::vec3& getLookAtPosition() const { return _lookAtPosition; } void setLookAtPosition(const glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; } - - float getLeanSideways() const { return _leanSideways; } - float getLeanForward() const { return _leanForward; } - float getTorsoTwist() const { return _torsoTwist; } - virtual float getFinalLeanSideways() const { return _leanSideways; } - virtual float getFinalLeanForward() const { return _leanForward; } - - void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; } - void setLeanForward(float leanForward) { _leanForward = leanForward; } - void setTorsoTwist(float torsoTwist) { _torsoTwist = torsoTwist; } - friend class AvatarData; QJsonObject toJson() const; @@ -89,9 +78,6 @@ protected: float _baseYaw; float _basePitch; float _baseRoll; - float _leanSideways; - float _leanForward; - float _torsoTwist; glm::vec3 _lookAtPosition; float _audioLoudness; From 30d8ae36e8db11d17f7e4ea237ed89771630d221 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 7 Jun 2016 16:55:32 -0700 Subject: [PATCH 2/3] Added MyAvatar.characterControllerEnabled property --- interface/src/avatar/MyAvatar.cpp | 26 ++++++++++++++++++++------ interface/src/avatar/MyAvatar.h | 4 ++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 0f723d29e3..3495a05962 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -234,7 +234,7 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) { void MyAvatar::reset(bool andRecenter, bool andReload, bool andHead) { if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "reset", Q_ARG(bool, andRecenter)); + QMetaObject::invokeMethod(this, "reset", Q_ARG(bool, andRecenter), Q_ARG(bool, andReload), Q_ARG(bool, andHead)); return; } @@ -1816,6 +1816,16 @@ void MyAvatar::updateMotionBehaviorFromMenu() { _motionBehaviors &= ~AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED; } + setCharacterControllerEnabled(menu->isOptionChecked(MenuOption::EnableCharacterController)); +} + +void MyAvatar::setCharacterControllerEnabled(bool enabled) { + + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setCharacterControllerEnabled", Q_ARG(bool, enabled)); + return; + } + bool ghostingAllowed = true; EntityTreeRenderer* entityTreeRenderer = qApp->getEntities(); if (entityTreeRenderer) { @@ -1824,12 +1834,16 @@ void MyAvatar::updateMotionBehaviorFromMenu() { ghostingAllowed = zone->getGhostingAllowed(); } } - bool checked = menu->isOptionChecked(MenuOption::EnableCharacterController); - if (!ghostingAllowed) { - checked = true; - } + _characterController.setEnabled(ghostingAllowed ? enabled : true); +} - _characterController.setEnabled(checked); +bool MyAvatar::getCharacterControllerEnabled() { + if (QThread::currentThread() != thread()) { + bool result; + QMetaObject::invokeMethod(this, "getCharacterControllerEnabled", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, result)); + return result; + } + return _characterController.isEnabled(); } void MyAvatar::clearDriveKeys() { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index a938aea675..05afe39a32 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -84,6 +84,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) public: explicit MyAvatar(RigPointer rig); @@ -265,6 +266,9 @@ public: controller::Pose getLeftHandControllerPoseInAvatarFrame() const; controller::Pose getRightHandControllerPoseInAvatarFrame() const; + Q_INVOKABLE void setCharacterControllerEnabled(bool enabled); + Q_INVOKABLE bool getCharacterControllerEnabled(); + public slots: void increaseSize(); void decreaseSize(); From 1aae22f5a59246e795801aa09ecf07bd93ee50af Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 9 Jun 2016 09:35:19 -0700 Subject: [PATCH 3/3] Optimized MyAvatar.getCharacterControllerEnabled() Instead of doing a blocking queued invokeMethod, it just calls into CharacterController.isEnabled() which is now thread-safe. --- interface/src/avatar/MyAvatar.cpp | 11 +++-------- libraries/physics/src/CharacterController.h | 6 ++++-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3495a05962..d5c481164c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1253,13 +1253,13 @@ void MyAvatar::prepareForPhysicsSimulation() { void MyAvatar::harvestResultsFromPhysicsSimulation(float deltaTime) { glm::vec3 position = getPosition(); glm::quat orientation = getOrientation(); - if (_characterController.isEnabled()) { + if (_characterController.isEnabledAndReady()) { _characterController.getPositionAndOrientation(position, orientation); } nextAttitude(position, orientation); _bodySensorMatrix = _follow.postPhysicsUpdate(*this, _bodySensorMatrix); - if (_characterController.isEnabled()) { + if (_characterController.isEnabledAndReady()) { setVelocity(_characterController.getLinearVelocity() + _characterController.getFollowVelocity()); } else { setVelocity(getVelocity() + _characterController.getFollowVelocity()); @@ -1642,7 +1642,7 @@ void MyAvatar::updatePosition(float deltaTime) { vec3 velocity = getVelocity(); const float MOVING_SPEED_THRESHOLD_SQUARED = 0.0001f; // 0.01 m/s - if (!_characterController.isEnabled()) { + if (!_characterController.isEnabledAndReady()) { // _characterController is not in physics simulation but it can still compute its target velocity updateMotors(); _characterController.computeNewVelocity(deltaTime, velocity); @@ -1838,11 +1838,6 @@ void MyAvatar::setCharacterControllerEnabled(bool enabled) { } bool MyAvatar::getCharacterControllerEnabled() { - if (QThread::currentThread() != thread()) { - bool result; - QMetaObject::invokeMethod(this, "getCharacterControllerEnabled", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, result)); - return result; - } return _characterController.isEnabled(); } diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index 2191f46d55..586ea175e6 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -105,8 +106,9 @@ public: void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale); + bool isEnabled() const { return _enabled; } // thread-safe void setEnabled(bool enabled); - bool isEnabled() const { return _enabled && _dynamicsWorld; } + bool isEnabledAndReady() const { return _enabled && _dynamicsWorld; } bool getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation); @@ -167,7 +169,7 @@ protected: btQuaternion _followAngularDisplacement; btVector3 _linearAcceleration; - bool _enabled; + std::atomic_bool _enabled; State _state; bool _isPushingUp;