diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 88f5ed01a8..30881aa01c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -959,7 +959,7 @@ void MyAvatar::simulate(float deltaTime, bool inView) { head->simulate(deltaTime); CameraMode mode = qApp->getCamera().getMode(); if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { - if (!_pointAtActive) { + if (!_pointAtActive || !_isPointTargetValid) { updateHeadLookAt(deltaTime); } else { resetHeadLookAt(); @@ -6113,6 +6113,7 @@ bool MyAvatar::beginReaction(QString reactionName) { _reactionEnabledRefCounts[reactionIndex]++; if (reactionName == POINT_REACTION_NAME) { _pointAtActive = true; + _isPointTargetValid = true; } return true; } @@ -6145,10 +6146,13 @@ void MyAvatar::updateRigControllerParameters(Rig::ControllerParameters& params) for (int i = 0; i < TRIGGER_REACTION_NAMES.size(); i++) { params.reactionTriggers[i] = _reactionTriggers[i]; } - + int pointReactionIndex = beginEndReactionNameToIndex("point"); for (int i = 0; i < BEGIN_END_REACTION_NAMES.size(); i++) { // copy current state into params. params.reactionEnabledFlags[i] = _reactionEnabledRefCounts[i] > 0; + if (params.reactionEnabledFlags[i] && i == pointReactionIndex) { + params.reactionEnabledFlags[i] = _isPointTargetValid; + } } for (int i = 0; i < TRIGGER_REACTION_NAMES.size(); i++) { @@ -6753,18 +6757,24 @@ void MyAvatar::setHeadLookAt(const glm::vec3& lookAtTarget) { _lookAtScriptTarget = lookAtTarget; } -void MyAvatar::setPointAt(const glm::vec3& pointAtTarget) { +bool MyAvatar::setPointAt(const glm::vec3& pointAtTarget) { if (QThread::currentThread() != thread()) { - BLOCKING_INVOKE_METHOD(this, "setPointAt", + bool result = false; + BLOCKING_INVOKE_METHOD(this, "setPointAt", Q_RETURN_ARG(bool, result), Q_ARG(const glm::vec3&, pointAtTarget)); - return; + return result; } - if (_skeletonModelLoaded) { + if (_skeletonModelLoaded && _pointAtActive) { glm::vec3 aimVector = pointAtTarget - getJointPosition(POINT_REF_JOINT_NAME); - glm::vec3 pointAtBlend = aimToBlendValues(aimVector, getWorldOrientation()); - _skeletonModel->getRig().setDirectionalBlending(POINT_BLEND_DIRECTIONAL_ALPHA_NAME, pointAtBlend, - POINT_BLEND_LINEAR_ALPHA_NAME, POINT_ALPHA_BLENDING); + _isPointTargetValid = glm::dot(aimVector, getWorldOrientation() * Vectors::FRONT) > 0.0f; + if (_isPointTargetValid) { + glm::vec3 pointAtBlend = aimToBlendValues(aimVector, getWorldOrientation()); + _skeletonModel->getRig().setDirectionalBlending(POINT_BLEND_DIRECTIONAL_ALPHA_NAME, pointAtBlend, + POINT_BLEND_LINEAR_ALPHA_NAME, POINT_ALPHA_BLENDING); + } + return _isPointTargetValid; } + return false; } void MyAvatar::resetPointAt() { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 20ce6fa147..7d1537e30a 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1769,10 +1769,11 @@ public: * Aims the pointing directional blending towards the provided target point. * The "point" reaction should be triggered before using this method. * MyAvatar.beginReaction("point") + * Returns true if the target point lays in front of the avatar. * @function MyAvatar.setPointAt * @param {Vec3} pointAtTarget - The target point in world coordinates. */ - Q_INVOKABLE void setPointAt(const glm::vec3& pointAtTarget); + Q_INVOKABLE bool setPointAt(const glm::vec3& pointAtTarget); glm::quat getLookAtRotation() { return _lookAtYaw * _lookAtPitch; } @@ -2662,7 +2663,8 @@ private: bool _shouldTurnToFaceCamera { false }; bool _scriptControlsHeadLookAt { false }; float _scriptHeadControlTimer { 0.0f }; - bool _pointAtActive{ false }; + bool _pointAtActive { false }; + bool _isPointTargetValid { true }; Setting::Handle _realWorldFieldOfView; Setting::Handle _useAdvancedMovementControls; diff --git a/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js b/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js index b30ed989e8..8633fe8870 100644 --- a/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js +++ b/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js @@ -208,11 +208,12 @@ var pointReticle = null; var mouseMoveEventsConnected = false; var targetPointInterpolateConnected = false; var pointAtTarget = Vec3.ZERO; +var isReticleVisible = true; function targetPointInterpolate() { if (reticlePosition) { pointAtTarget = Vec3.mix(pointAtTarget, reticlePosition, POINT_AT_MIX_ALPHA); - MyAvatar.setPointAt(pointAtTarget); + isReticleVisible = MyAvatar.setPointAt(pointAtTarget); } } @@ -297,7 +298,7 @@ function mouseMoveEvent(event) { } if (pointReticle && reticlePosition) { - Entities.editEntity(pointReticle, { position: reticlePosition }); + Entities.editEntity(pointReticle, { position: reticlePosition, visible: isReticleVisible }); } else if (reticlePosition) { pointReticle = Entities.addEntity({ type: "Box",