From 237022d3042438ec462452039a187bf72fcbeb51 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Wed, 12 Sep 2018 10:56:19 -0700 Subject: [PATCH] Refactor new pick parenting system for use with RayPick, ParabolaPick --- interface/src/Application.cpp | 12 +- interface/src/raypick/CollisionPick.cpp | 2 +- interface/src/raypick/CollisionPick.h | 1 - interface/src/raypick/JointParabolaPick.cpp | 43 ----- interface/src/raypick/JointParabolaPick.h | 32 ---- interface/src/raypick/JointRayPick.cpp | 45 ----- interface/src/raypick/JointRayPick.h | 33 ---- interface/src/raypick/MouseParabolaPick.cpp | 28 --- interface/src/raypick/MouseParabolaPick.h | 24 --- interface/src/raypick/MouseRayPick.cpp | 29 --- interface/src/raypick/MouseRayPick.h | 26 --- interface/src/raypick/ParabolaPick.cpp | 49 +++-- interface/src/raypick/ParabolaPick.h | 14 +- .../src/raypick/PickScriptingInterface.cpp | 177 ++++++++++-------- .../src/raypick/PickScriptingInterface.h | 1 + interface/src/raypick/RayPick.cpp | 11 ++ interface/src/raypick/RayPick.h | 7 +- .../src/raypick/RayPickScriptingInterface.cpp | 4 - interface/src/raypick/StaticParabolaPick.cpp | 19 -- interface/src/raypick/StaticParabolaPick.h | 26 --- interface/src/raypick/StaticRayPick.cpp | 18 -- interface/src/raypick/StaticRayPick.h | 25 --- interface/src/raypick/StylusPick.h | 1 + libraries/pointers/src/Pick.h | 20 +- libraries/shared/src/RegisteredMetaTypes.h | 2 + 25 files changed, 185 insertions(+), 464 deletions(-) delete mode 100644 interface/src/raypick/JointParabolaPick.cpp delete mode 100644 interface/src/raypick/JointParabolaPick.h delete mode 100644 interface/src/raypick/JointRayPick.cpp delete mode 100644 interface/src/raypick/JointRayPick.h delete mode 100644 interface/src/raypick/MouseParabolaPick.cpp delete mode 100644 interface/src/raypick/MouseParabolaPick.h delete mode 100644 interface/src/raypick/MouseRayPick.cpp delete mode 100644 interface/src/raypick/MouseRayPick.h delete mode 100644 interface/src/raypick/StaticParabolaPick.cpp delete mode 100644 interface/src/raypick/StaticParabolaPick.h delete mode 100644 interface/src/raypick/StaticRayPick.cpp delete mode 100644 interface/src/raypick/StaticRayPick.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e290531471..7f43c3d773 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -214,7 +214,8 @@ #include #include #include -#include +#include +#include #include @@ -2235,8 +2236,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo }); // Setup the mouse ray pick and related operators - DependencyManager::get()->setMouseRayPickID(DependencyManager::get()->addPick(PickQuery::Ray, std::make_shared( - PickFilter(PickScriptingInterface::PICK_ENTITIES() | PickScriptingInterface::PICK_INCLUDE_NONCOLLIDABLE()), 0.0f, true))); + { + auto mouseRayPick = std::make_shared(glm::vec3(), Vectors::UP, + PickFilter(PickScriptingInterface::PICK_ENTITIES() | PickScriptingInterface::PICK_INCLUDE_NONCOLLIDABLE()), 0.0f, true); + mouseRayPick->parentTransform = std::make_shared(); + auto mouseRayPickID = DependencyManager::get()->addPick(PickQuery::Ray, mouseRayPick); + DependencyManager::get()->setMouseRayPickID(mouseRayPickID); + } DependencyManager::get()->setMouseRayPickResultOperator([](unsigned int rayPickID) { RayToEntityIntersectionResult entityResult; entityResult.intersects = false; diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index 9aee76a3da..f79879bf93 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -347,8 +347,8 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha CollisionPick::CollisionPick(const PickFilter& filter, float maxDistance, bool enabled, CollisionRegion collisionRegion, PhysicsEnginePointer physicsEngine) : Pick(filter, maxDistance, enabled), - _mathPick(collisionRegion), _physicsEngine(physicsEngine) { + _mathPick = collisionRegion; if (collisionRegion.shouldComputeShapeInfo()) { _cachedResource = DependencyManager::get()->getCollisionGeometryResource(collisionRegion.modelURL); } diff --git a/interface/src/raypick/CollisionPick.h b/interface/src/raypick/CollisionPick.h index 0662ab6c19..79238b37fc 100644 --- a/interface/src/raypick/CollisionPick.h +++ b/interface/src/raypick/CollisionPick.h @@ -67,7 +67,6 @@ protected: void computeShapeInfoDimensionsOnly(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer resource); void filterIntersections(std::vector& intersections) const; - CollisionRegion _mathPick; PhysicsEnginePointer _physicsEngine; QSharedPointer _cachedResource; diff --git a/interface/src/raypick/JointParabolaPick.cpp b/interface/src/raypick/JointParabolaPick.cpp deleted file mode 100644 index 11a2e90819..0000000000 --- a/interface/src/raypick/JointParabolaPick.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Created by Sam Gondelman 7/2/2018 -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#include "JointParabolaPick.h" - -#include "avatar/AvatarManager.h" - -JointParabolaPick::JointParabolaPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, - float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, bool scaleWithAvatar, PickFilter& filter, float maxDistance, bool enabled) : - ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, scaleWithAvatar, filter, maxDistance, enabled), - _jointName(jointName), - _posOffset(posOffset), - _dirOffset(dirOffset) -{ -} - -PickParabola JointParabolaPick::getMathematicalPick() const { - auto myAvatar = DependencyManager::get()->getMyAvatar(); - int jointIndex = myAvatar->getJointIndex(QString::fromStdString(_jointName)); - bool useAvatarHead = _jointName == "Avatar"; - const int INVALID_JOINT = -1; - if (jointIndex != INVALID_JOINT || useAvatarHead) { - glm::vec3 jointPos = useAvatarHead ? myAvatar->getHeadPosition() : myAvatar->getAbsoluteJointTranslationInObjectFrame(jointIndex); - glm::quat jointRot = useAvatarHead ? myAvatar->getHeadOrientation() : myAvatar->getAbsoluteJointRotationInObjectFrame(jointIndex); - glm::vec3 avatarPos = myAvatar->getWorldPosition(); - glm::quat avatarRot = myAvatar->getWorldOrientation(); - - glm::vec3 pos = useAvatarHead ? jointPos : avatarPos + (avatarRot * jointPos); - glm::quat rot = useAvatarHead ? jointRot * glm::angleAxis(-PI / 2.0f, Vectors::RIGHT) : avatarRot * jointRot; - - // Apply offset - pos = pos + (rot * (myAvatar->getSensorToWorldScale() * _posOffset)); - glm::vec3 dir = glm::normalize(rot * glm::normalize(_dirOffset)); - - return PickParabola(pos, getSpeed() * dir, getAcceleration()); - } - - return PickParabola(); -} diff --git a/interface/src/raypick/JointParabolaPick.h b/interface/src/raypick/JointParabolaPick.h deleted file mode 100644 index aff6bd34d8..0000000000 --- a/interface/src/raypick/JointParabolaPick.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// Created by Sam Gondelman 7/2/2018 -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#ifndef hifi_JointParabolaPick_h -#define hifi_JointParabolaPick_h - -#include "ParabolaPick.h" - -class JointParabolaPick : public ParabolaPick { - -public: - JointParabolaPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, - float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, bool scaleWithAvatar, - PickFilter& filter, float maxDistance = 0.0f, bool enabled = false); - - PickParabola getMathematicalPick() const override; - - bool isLeftHand() const override { return (_jointName == "_CONTROLLER_LEFTHAND") || (_jointName == "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND"); } - bool isRightHand() const override { return (_jointName == "_CONTROLLER_RIGHTHAND") || (_jointName == "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND"); } - -private: - std::string _jointName; - glm::vec3 _posOffset; - glm::vec3 _dirOffset; - -}; - -#endif // hifi_JointParabolaPick_h diff --git a/interface/src/raypick/JointRayPick.cpp b/interface/src/raypick/JointRayPick.cpp deleted file mode 100644 index 340014e7d2..0000000000 --- a/interface/src/raypick/JointRayPick.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// JointRayPick.cpp -// interface/src/raypick -// -// Created by Sam Gondelman 7/11/2017 -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#include "JointRayPick.h" - -#include "avatar/AvatarManager.h" - -JointRayPick::JointRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const PickFilter& filter, float maxDistance, bool enabled) : - RayPick(filter, maxDistance, enabled), - _jointName(jointName), - _posOffset(posOffset), - _dirOffset(dirOffset) -{ -} - -PickRay JointRayPick::getMathematicalPick() const { - auto myAvatar = DependencyManager::get()->getMyAvatar(); - int jointIndex = myAvatar->getJointIndex(QString::fromStdString(_jointName)); - bool useAvatarHead = _jointName == "Avatar"; - const int INVALID_JOINT = -1; - if (jointIndex != INVALID_JOINT || useAvatarHead) { - glm::vec3 jointPos = useAvatarHead ? myAvatar->getHeadPosition() : myAvatar->getAbsoluteJointTranslationInObjectFrame(jointIndex); - glm::quat jointRot = useAvatarHead ? myAvatar->getHeadOrientation() : myAvatar->getAbsoluteJointRotationInObjectFrame(jointIndex); - glm::vec3 avatarPos = myAvatar->getWorldPosition(); - glm::quat avatarRot = myAvatar->getWorldOrientation(); - - glm::vec3 pos = useAvatarHead ? jointPos : avatarPos + (avatarRot * jointPos); - glm::quat rot = useAvatarHead ? jointRot * glm::angleAxis(-PI / 2.0f, Vectors::RIGHT) : avatarRot * jointRot; - - // Apply offset - pos = pos + (rot * (myAvatar->getSensorToWorldScale() * _posOffset)); - glm::vec3 dir = glm::normalize(rot * glm::normalize(_dirOffset)); - - return PickRay(pos, dir); - } - - return PickRay(); -} diff --git a/interface/src/raypick/JointRayPick.h b/interface/src/raypick/JointRayPick.h deleted file mode 100644 index c0031d87ff..0000000000 --- a/interface/src/raypick/JointRayPick.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// JointRayPick.h -// interface/src/raypick -// -// Created by Sam Gondelman 7/11/2017 -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#ifndef hifi_JointRayPick_h -#define hifi_JointRayPick_h - -#include "RayPick.h" - -class JointRayPick : public RayPick { - -public: - JointRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const PickFilter& filter, float maxDistance = 0.0f, bool enabled = false); - - PickRay getMathematicalPick() const override; - - bool isLeftHand() const override { return (_jointName == "_CONTROLLER_LEFTHAND") || (_jointName == "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND"); } - bool isRightHand() const override { return (_jointName == "_CONTROLLER_RIGHTHAND") || (_jointName == "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND"); } - -private: - std::string _jointName; - glm::vec3 _posOffset; - glm::vec3 _dirOffset; - -}; - -#endif // hifi_JointRayPick_h diff --git a/interface/src/raypick/MouseParabolaPick.cpp b/interface/src/raypick/MouseParabolaPick.cpp deleted file mode 100644 index 66351f4520..0000000000 --- a/interface/src/raypick/MouseParabolaPick.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// Created by Sam Gondelman 7/2/2018 -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#include "MouseParabolaPick.h" - -#include "Application.h" -#include "display-plugins/CompositorHelper.h" - -MouseParabolaPick::MouseParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, - bool scaleWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) : - ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, scaleWithAvatar, filter, maxDistance, enabled) -{ -} - -PickParabola MouseParabolaPick::getMathematicalPick() const { - QVariant position = qApp->getApplicationCompositor().getReticleInterface()->getPosition(); - if (position.isValid()) { - QVariantMap posMap = position.toMap(); - PickRay pickRay = qApp->getCamera().computePickRay(posMap["x"].toFloat(), posMap["y"].toFloat()); - return PickParabola(pickRay.origin, getSpeed() * pickRay.direction, getAcceleration()); - } - - return PickParabola(); -} diff --git a/interface/src/raypick/MouseParabolaPick.h b/interface/src/raypick/MouseParabolaPick.h deleted file mode 100644 index cb67c3b361..0000000000 --- a/interface/src/raypick/MouseParabolaPick.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// Created by Sam Gondelman 7/2/2018 -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#ifndef hifi_MouseParabolaPick_h -#define hifi_MouseParabolaPick_h - -#include "ParabolaPick.h" - -class MouseParabolaPick : public ParabolaPick { - -public: - MouseParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, bool scaleWithAvatar, - const PickFilter& filter, float maxDistance = 0.0f, bool enabled = false); - - PickParabola getMathematicalPick() const override; - - bool isMouse() const override { return true; } -}; - -#endif // hifi_MouseParabolaPick_h diff --git a/interface/src/raypick/MouseRayPick.cpp b/interface/src/raypick/MouseRayPick.cpp deleted file mode 100644 index 2b55c44460..0000000000 --- a/interface/src/raypick/MouseRayPick.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// MouseRayPick.cpp -// interface/src/raypick -// -// Created by Sam Gondelman 7/19/2017 -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#include "MouseRayPick.h" - -#include "Application.h" -#include "display-plugins/CompositorHelper.h" - -MouseRayPick::MouseRayPick(const PickFilter& filter, float maxDistance, bool enabled) : - RayPick(filter, maxDistance, enabled) -{ -} - -PickRay MouseRayPick::getMathematicalPick() const { - QVariant position = qApp->getApplicationCompositor().getReticleInterface()->getPosition(); - if (position.isValid()) { - QVariantMap posMap = position.toMap(); - return qApp->getCamera().computePickRay(posMap["x"].toFloat(), posMap["y"].toFloat()); - } - - return PickRay(); -} diff --git a/interface/src/raypick/MouseRayPick.h b/interface/src/raypick/MouseRayPick.h deleted file mode 100644 index a9070e8b92..0000000000 --- a/interface/src/raypick/MouseRayPick.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// MouseRayPick.h -// interface/src/raypick -// -// Created by Sam Gondelman 7/19/2017 -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#ifndef hifi_MouseRayPick_h -#define hifi_MouseRayPick_h - -#include "RayPick.h" - -class MouseRayPick : public RayPick { - -public: - MouseRayPick(const PickFilter& filter, float maxDistance = 0.0f, bool enabled = false); - - PickRay getMathematicalPick() const override; - - bool isMouse() const override { return true; } -}; - -#endif // hifi_MouseRayPick_h diff --git a/interface/src/raypick/ParabolaPick.cpp b/interface/src/raypick/ParabolaPick.cpp index 1b37eee096..a2a9211b88 100644 --- a/interface/src/raypick/ParabolaPick.cpp +++ b/interface/src/raypick/ParabolaPick.cpp @@ -14,6 +14,43 @@ #include "scripting/HMDScriptingInterface.h" #include "DependencyManager.h" +ParabolaPick::ParabolaPick(const glm::vec3& position, const glm::vec3& direction, float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, bool rotateAccelerationWithParent, bool scaleWithParent, const PickFilter& filter, float maxDistance, bool enabled) : + Pick(filter, maxDistance, enabled), + _rotateAccelerationWithAvatar(rotateAccelerationWithAvatar), + _rotateAccelerationWithParent(rotateAccelerationWithParent), + _scaleWithParent(scaleWithParent) { + _mathPick = PickParabola(position, speed*direction, accelerationAxis); +} + +PickParabola ParabolaPick::getMathematicalPick() const { + if (!parentTransform) { + PickParabola mathPick = _mathPick; + if (_rotateAccelerationWithAvatar) { + mathPick.acceleration = DependencyManager::get()->getMyAvatar()->getWorldOrientation() * mathPick.acceleration; + } + return mathPick; + } + + Transform currentParentTransform = parentTransform->getTransform(); + + glm::vec3 position = currentParentTransform.transform(_mathPick.origin); + glm::vec3 velocity = _mathPick.velocity; + if (_scaleWithParent) { + velocity = currentParentTransform.transformDirection(velocity); + } + glm::vec3 acceleration = _mathPick.acceleration; + if (_rotateAccelerationWithAvatar) { + acceleration = DependencyManager::get()->getMyAvatar()->getWorldOrientation() * acceleration; + } else if (_rotateAccelerationWithParent) { + acceleration = currentParentTransform.getRotation() * acceleration; + } + if (_scaleWithParent) { + acceleration *= currentParentTransform.getScale(); + } + + return PickParabola(position, velocity, acceleration); +} + PickResultPointer ParabolaPick::getEntityIntersection(const PickParabola& pick) { if (glm::length2(pick.acceleration) > EPSILON && glm::length2(pick.velocity) > EPSILON) { ParabolaToEntityIntersectionResult entityRes = @@ -57,18 +94,6 @@ PickResultPointer ParabolaPick::getHUDIntersection(const PickParabola& pick) { return std::make_shared(pick.toVariantMap()); } -float ParabolaPick::getSpeed() const { - return (_scaleWithAvatar ? DependencyManager::get()->getMyAvatar()->getSensorToWorldScale() * _speed : _speed); -} - -glm::vec3 ParabolaPick::getAcceleration() const { - float scale = (_scaleWithAvatar ? DependencyManager::get()->getMyAvatar()->getSensorToWorldScale() : 1.0f); - if (_rotateAccelerationWithAvatar) { - return scale * (DependencyManager::get()->getMyAvatar()->getWorldOrientation() * _accelerationAxis); - } - return scale * _accelerationAxis; -} - Transform ParabolaPick::getResultTransform() const { PickResultPointer result = getPrevPickResult(); if (!result) { diff --git a/interface/src/raypick/ParabolaPick.h b/interface/src/raypick/ParabolaPick.h index 01454390f9..7089228d21 100644 --- a/interface/src/raypick/ParabolaPick.h +++ b/interface/src/raypick/ParabolaPick.h @@ -74,9 +74,9 @@ public: class ParabolaPick : public Pick { public: - ParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, bool scaleWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) : - Pick(filter, maxDistance, enabled), _speed(speed), _accelerationAxis(accelerationAxis), _rotateAccelerationWithAvatar(rotateAccelerationWithAvatar), - _scaleWithAvatar(scaleWithAvatar) {} + ParabolaPick(const glm::vec3& position, const glm::vec3& direction, float speed, const glm::vec3& acceleration, bool rotateAccelerationWithAvatar, bool rotateAccelerationWithParent, bool scaleWithParent, const PickFilter& filter, float maxDistance, bool enabled); + + PickParabola getMathematicalPick() const override; PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared(pickVariant); } PickResultPointer getEntityIntersection(const PickParabola& pick) override; @@ -86,13 +86,9 @@ public: Transform getResultTransform() const override; protected: - float _speed; - glm::vec3 _accelerationAxis; bool _rotateAccelerationWithAvatar; - bool _scaleWithAvatar; - - float getSpeed() const; - glm::vec3 getAcceleration() const; + bool _rotateAccelerationWithParent; + bool _scaleWithParent; }; #endif // hifi_ParabolaPick_h diff --git a/interface/src/raypick/PickScriptingInterface.cpp b/interface/src/raypick/PickScriptingInterface.cpp index b9693f6782..600be743fe 100644 --- a/interface/src/raypick/PickScriptingInterface.cpp +++ b/interface/src/raypick/PickScriptingInterface.cpp @@ -14,13 +14,9 @@ #include "Application.h" #include -#include "StaticRayPick.h" -#include "JointRayPick.h" -#include "MouseRayPick.h" +#include "RayPick.h" #include "StylusPick.h" -#include "StaticParabolaPick.h" -#include "JointParabolaPick.h" -#include "MouseParabolaPick.h" +#include "ParabolaPick.h" #include "CollisionPick.h" #include "SpatialParentFinder.h" @@ -56,9 +52,9 @@ unsigned int PickScriptingInterface::createPick(const PickQuery::PickType type, * @property {boolean} [enabled=false] If this Pick should start enabled or not. Disabled Picks do not updated their pick results. * @property {number} [filter=Picks.PICK_NOTHING] The filter for this Pick to use, constructed using filter flags combined using bitwise OR. * @property {number} [maxDistance=0.0] The max distance at which this Pick will intersect. 0.0 = no max. < 0.0 is invalid. - * @property {string} [joint] Only for Joint or Mouse Ray Picks. If "Mouse", it will create a Ray Pick that follows the system mouse, in desktop or HMD. - * If "Avatar", it will create a Joint Ray Pick that follows your avatar's head. Otherwise, it will create a Joint Ray Pick that follows the given joint, if it - * exists on your current avatar. + * @property {Uuid} parentID - The ID of the parent, either an avatar, an entity, or an overlay. + * @property {number} parentJointIndex - The joint of the parent to parent to, for example, the joints on the model of an avatar. (default = 0, no joint) + * @property {string} joint - If "Mouse," parents the pick to the mouse. If "Avatar," parents the pick to MyAvatar's head. Otherwise, parents to the joint of the given name on MyAvatar. * @property {Vec3} [posOffset=Vec3.ZERO] Only for Joint Ray Picks. A local joint position offset, in meters. x = upward, y = forward, z = lateral * @property {Vec3} [dirOffset=Vec3.UP] Only for Joint Ray Picks. A local joint direction offset. x = upward, y = forward, z = lateral * @property {Vec3} [position] Only for Static Ray Picks. The world-space origin of the ray. @@ -82,38 +78,30 @@ unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) { maxDistance = propMap["maxDistance"].toFloat(); } - if (propMap["joint"].isValid()) { - std::string jointName = propMap["joint"].toString().toStdString(); - - if (jointName != "Mouse") { - // x = upward, y = forward, z = lateral - glm::vec3 posOffset = Vectors::ZERO; - if (propMap["posOffset"].isValid()) { - posOffset = vec3FromVariant(propMap["posOffset"]); - } - - glm::vec3 dirOffset = Vectors::UP; - if (propMap["dirOffset"].isValid()) { - dirOffset = vec3FromVariant(propMap["dirOffset"]); - } - - return DependencyManager::get()->addPick(PickQuery::Ray, std::make_shared(jointName, posOffset, dirOffset, filter, maxDistance, enabled)); - - } else { - return DependencyManager::get()->addPick(PickQuery::Ray, std::make_shared(filter, maxDistance, enabled)); - } - } else if (propMap["position"].isValid()) { - glm::vec3 position = vec3FromVariant(propMap["position"]); - - glm::vec3 direction = -Vectors::UP; - if (propMap["direction"].isValid()) { - direction = vec3FromVariant(propMap["direction"]); - } - - return DependencyManager::get()->addPick(PickQuery::Ray, std::make_shared(position, direction, filter, maxDistance, enabled)); + glm::vec3 position = Vectors::ZERO; + if (propMap["position"].isValid()) { + position = vec3FromVariant(propMap["position"]); + } else if (propMap["posOffset"].isValid()) { + position = vec3FromVariant(propMap["posOffset"]); } - return PickManager::INVALID_PICK_ID; + // direction has two defaults to ensure compatibility with older scripts + // Joint ray picks had default direction = Vec3.UP + // Static ray picks had default direction = -Vec3.UP + glm::vec3 direction = propMap["joint"].isValid() ? Vectors::UP : -Vectors::UP; + if (propMap["orientation"].isValid()) { + direction = quatFromVariant(propMap["orientation"]) * Vectors::UP; + } else if (propMap["direction"].isValid()) { + direction = vec3FromVariant(propMap["direction"]); + } else if (propMap["dirOffset"].isValid()) { + direction = vec3FromVariant(propMap["dirOffset"]); + } + + auto rayPick = std::make_shared(position, direction, filter, maxDistance, enabled); + rayPick->parentTransform = createTransformNode(propMap); + rayPick->setJointState(getPickJointState(propMap)); + + return DependencyManager::get()->addPick(PickQuery::Ray, rayPick); } /**jsdoc @@ -153,23 +141,26 @@ unsigned int PickScriptingInterface::createStylusPick(const QVariant& properties return DependencyManager::get()->addPick(PickQuery::Stylus, std::make_shared(side, filter, maxDistance, enabled)); } +// NOTE: Laser pointer still uses scaleWithAvatar. Until scaleWithAvatar is also deprecated for pointers, scaleWithAvatar should not be removed from the pick API. /**jsdoc * A set of properties that can be passed to {@link Picks.createPick} to create a new Parabola Pick. * @typedef {object} Picks.ParabolaPickProperties * @property {boolean} [enabled=false] If this Pick should start enabled or not. Disabled Picks do not updated their pick results. * @property {number} [filter=Picks.PICK_NOTHING] The filter for this Pick to use, constructed using filter flags combined using bitwise OR. * @property {number} [maxDistance=0.0] The max distance at which this Pick will intersect. 0.0 = no max. < 0.0 is invalid. - * @property {string} [joint] Only for Joint or Mouse Parabola Picks. If "Mouse", it will create a Parabola Pick that follows the system mouse, in desktop or HMD. - * If "Avatar", it will create a Joint Parabola Pick that follows your avatar's head. Otherwise, it will create a Joint Parabola Pick that follows the given joint, if it - * exists on your current avatar. + * @property {Uuid} parentID - The ID of the parent, either an avatar, an entity, or an overlay. + * @property {number} parentJointIndex - The joint of the parent to parent to, for example, the joints on the model of an avatar. (default = 0, no joint) + * @property {string} joint - If "Mouse," parents the pick to the mouse. If "Avatar," parents the pick to MyAvatar's head. Otherwise, parents to the joint of the given name on MyAvatar. * @property {Vec3} [posOffset=Vec3.ZERO] Only for Joint Parabola Picks. A local joint position offset, in meters. x = upward, y = forward, z = lateral * @property {Vec3} [dirOffset=Vec3.UP] Only for Joint Parabola Picks. A local joint direction offset. x = upward, y = forward, z = lateral * @property {Vec3} [position] Only for Static Parabola Picks. The world-space origin of the parabola segment. * @property {Vec3} [direction=-Vec3.FRONT] Only for Static Parabola Picks. The world-space direction of the parabola segment. * @property {number} [speed=1] The initial speed of the parabola, i.e. the initial speed of the projectile whose trajectory defines the parabola. * @property {Vec3} [accelerationAxis=-Vec3.UP] The acceleration of the parabola, i.e. the acceleration of the projectile whose trajectory defines the parabola, both magnitude and direction. - * @property {boolean} [rotateAccelerationWithAvatar=true] Whether or not the acceleration axis should rotate with your avatar's local Y axis. - * @property {boolean} [scaleWithAvatar=false] If true, the velocity and acceleration of the Pick will scale linearly with your avatar. + * @property {boolean} [rotateAccelerationWithAvatar=true] Whether or not the acceleration axis should rotate with the avatar's local Y axis. + * @property {boolean} [rotateAccelerationWithParent=false] Whether or not the acceleration axis should rotate with the parent's local Y axis, if available. + * @property {boolean} [scaleWithParent=false] If true, the velocity and acceleration of the Pick will scale linearly with the parent, if available. + * @property {boolean} [scaleWithAvatar] Alias for scaleWithParent. Deprecated. */ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properties) { QVariantMap propMap = properties.toMap(); @@ -204,48 +195,38 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti rotateAccelerationWithAvatar = propMap["rotateAccelerationWithAvatar"].toBool(); } - bool scaleWithAvatar = false; - if (propMap["scaleWithAvatar"].isValid()) { - scaleWithAvatar = propMap["scaleWithAvatar"].toBool(); + bool rotateAccelerationWithParent = false; + if (propMap["rotateAccelerationWithParent"].isValid()) { + rotateAccelerationWithParent = propMap["rotateAccelerationWithParent"].toBool(); } - if (propMap["joint"].isValid()) { - std::string jointName = propMap["joint"].toString().toStdString(); - - if (jointName != "Mouse") { - // x = upward, y = forward, z = lateral - glm::vec3 posOffset = Vectors::ZERO; - if (propMap["posOffset"].isValid()) { - posOffset = vec3FromVariant(propMap["posOffset"]); - } - - glm::vec3 dirOffset = Vectors::UP; - if (propMap["dirOffset"].isValid()) { - dirOffset = vec3FromVariant(propMap["dirOffset"]); - } - - return DependencyManager::get()->addPick(PickQuery::Parabola, std::make_shared(jointName, posOffset, dirOffset, - speed, accelerationAxis, rotateAccelerationWithAvatar, - scaleWithAvatar, filter, maxDistance, enabled)); - - } else { - return DependencyManager::get()->addPick(PickQuery::Parabola, std::make_shared(speed, accelerationAxis, rotateAccelerationWithAvatar, - scaleWithAvatar, filter, maxDistance, enabled)); - } - } else if (propMap["position"].isValid()) { - glm::vec3 position = vec3FromVariant(propMap["position"]); - - glm::vec3 direction = -Vectors::FRONT; - if (propMap["direction"].isValid()) { - direction = vec3FromVariant(propMap["direction"]); - } - - return DependencyManager::get()->addPick(PickQuery::Parabola, std::make_shared(position, direction, speed, accelerationAxis, - rotateAccelerationWithAvatar, scaleWithAvatar, - filter, maxDistance, enabled)); + bool scaleWithParent = false; + if (propMap["scaleWithParent"].isValid()) { + scaleWithParent = propMap["scaleWithParent"].toBool(); + } else if (propMap["scaleWithAvatar"].isValid()) { + scaleWithParent = propMap["scaleWithAvatar"].toBool(); } - return PickManager::INVALID_PICK_ID; + glm::vec3 position = glm::vec3(); + glm::vec3 direction = -Vectors::FRONT; + if (propMap["position"].isValid()) { + position = vec3FromVariant(propMap["position"]); + } else if (propMap["posOffset"].isValid()) { + position = vec3FromVariant(propMap["posOffset"]); + } + if (propMap["orientation"].isValid()) { + direction = quatFromVariant(propMap["orientation"]) * Vectors::UP; + } else if (propMap["direction"].isValid()) { + direction = vec3FromVariant(propMap["direction"]); + } else if (propMap["dirOffset"].isValid()) { + direction = vec3FromVariant(propMap["dirOffset"]); + } + + auto parabolaPick = std::make_shared(position, direction, speed, accelerationAxis, + rotateAccelerationWithAvatar, rotateAccelerationWithParent, scaleWithParent, filter, maxDistance, enabled); + parabolaPick->parentTransform = createTransformNode(propMap); + parabolaPick->setJointState(getPickJointState(propMap)); + return DependencyManager::get()->addPick(PickQuery::Parabola, parabolaPick); } /**jsdoc @@ -297,6 +278,7 @@ unsigned int PickScriptingInterface::createCollisionPick(const QVariant& propert CollisionRegion collisionRegion(propMap); auto collisionPick = std::make_shared(filter, maxDistance, enabled, collisionRegion, qApp->getPhysicsEngine()); collisionPick->parentTransform = createTransformNode(propMap); + collisionPick->setJointState(getPickJointState(propMap)); return DependencyManager::get()->addPick(PickQuery::Collision, collisionPick); } @@ -373,6 +355,37 @@ void PickScriptingInterface::setPerFrameTimeBudget(unsigned int numUsecs) { DependencyManager::get()->setPerFrameTimeBudget(numUsecs); } +PickQuery::JointState PickScriptingInterface::getPickJointState(const QVariantMap& propMap) { + if (propMap["parentID"].isValid()) { + QUuid parentUuid = propMap["parentID"].toUuid(); + if (propMap["parentJointIndex"].isValid() && parentUuid == DependencyManager::get()->getMyAvatar()->getSessionUUID()) { + int jointIndex = propMap["parentJointIndes"].toInt(); + if (jointIndex == CONTROLLER_LEFTHAND_INDEX || jointIndex == CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX) { + return PickQuery::JOINT_STATE_LEFT_HAND; + } else if (jointIndex == CONTROLLER_RIGHTHAND_INDEX || jointIndex == CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX) { + return PickQuery::JOINT_STATE_RIGHT_HAND; + } else { + return PickQuery::JOINT_STATE_NONE; + } + } else { + return PickQuery::JOINT_STATE_NONE; + } + } else if (propMap["joint"].isValid()) { + QString joint = propMap["joint"].toString(); + if (joint == "Mouse") { + return PickQuery::JOINT_STATE_MOUSE; + } else if (joint == "_CONTROLLER_LEFTHAND" || joint == "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND") { + return PickQuery::JOINT_STATE_LEFT_HAND; + } else if (joint== "_CONTROLLER_RIGHTHAND" || joint == "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND") { + return PickQuery::JOINT_STATE_RIGHT_HAND; + } else { + return PickQuery::JOINT_STATE_NONE; + } + } else { + return PickQuery::JOINT_STATE_NONE; + } +} + std::shared_ptr PickScriptingInterface::createTransformNode(const QVariantMap& propMap) { if (propMap["parentID"].isValid()) { QUuid parentUuid = propMap["parentID"].toUuid(); diff --git a/interface/src/raypick/PickScriptingInterface.h b/interface/src/raypick/PickScriptingInterface.h index 36079cec2b..224f7a547e 100644 --- a/interface/src/raypick/PickScriptingInterface.h +++ b/interface/src/raypick/PickScriptingInterface.h @@ -320,6 +320,7 @@ public slots: static constexpr unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; } protected: + static PickQuery::JointState getPickJointState(const QVariantMap& propMap); static std::shared_ptr createTransformNode(const QVariantMap& propMap); }; diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp index 736d3c1760..d16e10a3f4 100644 --- a/interface/src/raypick/RayPick.cpp +++ b/interface/src/raypick/RayPick.cpp @@ -14,6 +14,17 @@ #include "scripting/HMDScriptingInterface.h" #include "DependencyManager.h" +PickRay RayPick::getMathematicalPick() const { + if (!parentTransform) { + return _mathPick; + } + + Transform currentParentTransform = parentTransform->getTransform(); + Transform relativeTransform(rotationBetween(Vectors::UP, _mathPick.direction), glm::vec3(1.0f), _mathPick.origin); + Transform pickTransform = currentParentTransform.worldTransform(relativeTransform); + return PickRay(pickTransform.getTranslation(), pickTransform.getRotation() * Vectors::UP); +} + PickResultPointer RayPick::getEntityIntersection(const PickRay& pick) { RayToEntityIntersectionResult entityRes = DependencyManager::get()->findRayIntersectionVector(pick, !getFilter().doesPickCoarse(), diff --git a/interface/src/raypick/RayPick.h b/interface/src/raypick/RayPick.h index 11f985cec2..7c7ea5758a 100644 --- a/interface/src/raypick/RayPick.h +++ b/interface/src/raypick/RayPick.h @@ -70,7 +70,12 @@ public: class RayPick : public Pick { public: - RayPick(const PickFilter& filter, float maxDistance, bool enabled) : Pick(filter, maxDistance, enabled) {} + RayPick(glm::vec3 position, glm::vec3 direction, const PickFilter& filter, float maxDistance, bool enabled) : + Pick(filter, maxDistance, enabled) { + _mathPick = PickRay(position, direction); + } + + PickRay getMathematicalPick() const override; PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared(pickVariant); } PickResultPointer getEntityIntersection(const PickRay& pick) override; diff --git a/interface/src/raypick/RayPickScriptingInterface.cpp b/interface/src/raypick/RayPickScriptingInterface.cpp index c90f5d6c6c..247368df51 100644 --- a/interface/src/raypick/RayPickScriptingInterface.cpp +++ b/interface/src/raypick/RayPickScriptingInterface.cpp @@ -16,10 +16,6 @@ #include -#include "StaticRayPick.h" -#include "JointRayPick.h" -#include "MouseRayPick.h" - unsigned int RayPickScriptingInterface::createRayPick(const QVariant& properties) { return DependencyManager::get()->createRayPick(properties); } diff --git a/interface/src/raypick/StaticParabolaPick.cpp b/interface/src/raypick/StaticParabolaPick.cpp deleted file mode 100644 index a4e3ccb97f..0000000000 --- a/interface/src/raypick/StaticParabolaPick.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// -// Created by Sam Gondelman 7/2/2018 -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#include "StaticParabolaPick.h" - -StaticParabolaPick::StaticParabolaPick(const glm::vec3& position, const glm::vec3& direction, float speed, const glm::vec3& accelerationAxis, - bool scaleWithAvatar, bool rotateAccelerationWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) : - ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, scaleWithAvatar, filter, maxDistance, enabled), - _position(position), _velocity(direction) -{ -} - -PickParabola StaticParabolaPick::getMathematicalPick() const { - return PickParabola(_position, getSpeed() * _velocity, getAcceleration()); -} \ No newline at end of file diff --git a/interface/src/raypick/StaticParabolaPick.h b/interface/src/raypick/StaticParabolaPick.h deleted file mode 100644 index df2057a6f0..0000000000 --- a/interface/src/raypick/StaticParabolaPick.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Created by Sam Gondelman 7/2/2018 -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#ifndef hifi_StaticParabolaPick_h -#define hifi_StaticParabolaPick_h - -#include "ParabolaPick.h" - -class StaticParabolaPick : public ParabolaPick { - -public: - StaticParabolaPick(const glm::vec3& position, const glm::vec3& direction, float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, - bool scaleWithAvatar, const PickFilter& filter, float maxDistance = 0.0f, bool enabled = false); - - PickParabola getMathematicalPick() const override; - -private: - glm::vec3 _position; - glm::vec3 _velocity; -}; - -#endif // hifi_StaticParabolaPick_h diff --git a/interface/src/raypick/StaticRayPick.cpp b/interface/src/raypick/StaticRayPick.cpp deleted file mode 100644 index b74afd6b5d..0000000000 --- a/interface/src/raypick/StaticRayPick.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// -// Created by Sam Gondelman 7/11/2017 -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#include "StaticRayPick.h" - -StaticRayPick::StaticRayPick(const glm::vec3& position, const glm::vec3& direction, const PickFilter& filter, float maxDistance, bool enabled) : - RayPick(filter, maxDistance, enabled), - _pickRay(position, direction) -{ -} - -PickRay StaticRayPick::getMathematicalPick() const { - return _pickRay; -} \ No newline at end of file diff --git a/interface/src/raypick/StaticRayPick.h b/interface/src/raypick/StaticRayPick.h deleted file mode 100644 index e4da2dbd55..0000000000 --- a/interface/src/raypick/StaticRayPick.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Created by Sam Gondelman 7/11/2017 -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#ifndef hifi_StaticRayPick_h -#define hifi_StaticRayPick_h - -#include "RayPick.h" - -class StaticRayPick : public RayPick { - -public: - StaticRayPick(const glm::vec3& position, const glm::vec3& direction, const PickFilter& filter, float maxDistance = 0.0f, bool enabled = false); - - PickRay getMathematicalPick() const override; - -private: - PickRay _pickRay; - -}; - -#endif // hifi_StaticRayPick_h diff --git a/interface/src/raypick/StylusPick.h b/interface/src/raypick/StylusPick.h index ca80e9fbea..e6b1da9914 100644 --- a/interface/src/raypick/StylusPick.h +++ b/interface/src/raypick/StylusPick.h @@ -70,6 +70,7 @@ public: bool isLeftHand() const override { return _side == Side::Left; } bool isRightHand() const override { return _side == Side::Right; } + bool isMouse() const override { return false; } private: const Side _side; diff --git a/libraries/pointers/src/Pick.h b/libraries/pointers/src/Pick.h index 099a791407..42a9354122 100644 --- a/libraries/pointers/src/Pick.h +++ b/libraries/pointers/src/Pick.h @@ -170,6 +170,13 @@ public: }; Q_ENUM(PickType) + enum JointState { + JOINT_STATE_NONE = 0, + JOINT_STATE_LEFT_HAND, + JOINT_STATE_RIGHT_HAND, + JOINT_STATE_MOUSE + }; + void enable(bool enabled = true); void disable() { enable(false); } @@ -210,9 +217,11 @@ public: void setIgnoreItems(const QVector& items); void setIncludeItems(const QVector& items); - virtual bool isLeftHand() const { return false; } - virtual bool isRightHand() const { return false; } - virtual bool isMouse() const { return false; } + virtual bool isLeftHand() const { return _jointState == JOINT_STATE_LEFT_HAND; } + virtual bool isRightHand() const { return _jointState == JOINT_STATE_RIGHT_HAND; } + virtual bool isMouse() const { return _jointState == JOINT_STATE_MOUSE; } + + void setJointState(JointState jointState) { _jointState = jointState; } virtual Transform getResultTransform() const = 0; @@ -226,6 +235,8 @@ private: QVector _ignoreItems; QVector _includeItems; + + JointState _jointState = JOINT_STATE_NONE; }; Q_DECLARE_METATYPE(PickQuery::PickType) @@ -240,6 +251,9 @@ public: virtual PickResultPointer getOverlayIntersection(const T& pick) = 0; virtual PickResultPointer getAvatarIntersection(const T& pick) = 0; virtual PickResultPointer getHUDIntersection(const T& pick) = 0; + +protected: + T _mathPick; }; namespace std { diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 6ecf9faca7..46f112f5c6 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -178,7 +178,9 @@ public: QVariantMap toVariantMap() const override { QVariantMap pickRay; pickRay["origin"] = vec3toVariant(origin); + pickRay["position"] = vec3toVariant(origin); pickRay["direction"] = vec3toVariant(direction); + pickRay["orientation"] = quatToVariant(rotationBetween(Vectors::UP, direction)); return pickRay; } };