Refactor new pick parenting system for use with RayPick, ParabolaPick

This commit is contained in:
sabrina-shanman 2018-09-12 10:56:19 -07:00
parent d2c41f02e5
commit 237022d304
25 changed files with 185 additions and 464 deletions

View file

@ -214,7 +214,8 @@
#include <raypick/LaserPointerScriptingInterface.h>
#include <raypick/PickScriptingInterface.h>
#include <raypick/PointerScriptingInterface.h>
#include <raypick/MouseRayPick.h>
#include <raypick/RayPick.h>
#include <raypick/MouseTransformNode.h>
#include <FadeEffect.h>
@ -2235,8 +2236,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
});
// Setup the mouse ray pick and related operators
DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, std::make_shared<MouseRayPick>(
PickFilter(PickScriptingInterface::PICK_ENTITIES() | PickScriptingInterface::PICK_INCLUDE_NONCOLLIDABLE()), 0.0f, true)));
{
auto mouseRayPick = std::make_shared<RayPick>(glm::vec3(), Vectors::UP,
PickFilter(PickScriptingInterface::PICK_ENTITIES() | PickScriptingInterface::PICK_INCLUDE_NONCOLLIDABLE()), 0.0f, true);
mouseRayPick->parentTransform = std::make_shared<MouseTransformNode>();
auto mouseRayPickID = DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, mouseRayPick);
DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(mouseRayPickID);
}
DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([](unsigned int rayPickID) {
RayToEntityIntersectionResult entityResult;
entityResult.intersects = false;

View file

@ -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<ModelCache>()->getCollisionGeometryResource(collisionRegion.modelURL);
}

View file

@ -67,7 +67,6 @@ protected:
void computeShapeInfoDimensionsOnly(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource);
void filterIntersections(std::vector<ContactTestResult>& intersections) const;
CollisionRegion _mathPick;
PhysicsEnginePointer _physicsEngine;
QSharedPointer<GeometryResource> _cachedResource;

View file

@ -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<AvatarManager>()->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();
}

View file

@ -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

View file

@ -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<AvatarManager>()->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();
}

View file

@ -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

View file

@ -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();
}

View file

@ -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

View file

@ -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();
}

View file

@ -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

View file

@ -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<AvatarManager>()->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<AvatarManager>()->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<ParabolaPickResult>(pick.toVariantMap());
}
float ParabolaPick::getSpeed() const {
return (_scaleWithAvatar ? DependencyManager::get<AvatarManager>()->getMyAvatar()->getSensorToWorldScale() * _speed : _speed);
}
glm::vec3 ParabolaPick::getAcceleration() const {
float scale = (_scaleWithAvatar ? DependencyManager::get<AvatarManager>()->getMyAvatar()->getSensorToWorldScale() : 1.0f);
if (_rotateAccelerationWithAvatar) {
return scale * (DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * _accelerationAxis);
}
return scale * _accelerationAxis;
}
Transform ParabolaPick::getResultTransform() const {
PickResultPointer result = getPrevPickResult();
if (!result) {

View file

@ -74,9 +74,9 @@ public:
class ParabolaPick : public Pick<PickParabola> {
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<ParabolaPickResult>(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

View file

@ -14,13 +14,9 @@
#include "Application.h"
#include <PickManager.h>
#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<PickManager>()->addPick(PickQuery::Ray, std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled));
} else {
return DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, std::make_shared<MouseRayPick>(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<PickManager>()->addPick(PickQuery::Ray, std::make_shared<StaticRayPick>(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<RayPick>(position, direction, filter, maxDistance, enabled);
rayPick->parentTransform = createTransformNode(propMap);
rayPick->setJointState(getPickJointState(propMap));
return DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, rayPick);
}
/**jsdoc
@ -153,23 +141,26 @@ unsigned int PickScriptingInterface::createStylusPick(const QVariant& properties
return DependencyManager::get<PickManager>()->addPick(PickQuery::Stylus, std::make_shared<StylusPick>(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. <em>Deprecated.</em>
*/
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<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<JointParabolaPick>(jointName, posOffset, dirOffset,
speed, accelerationAxis, rotateAccelerationWithAvatar,
scaleWithAvatar, filter, maxDistance, enabled));
} else {
return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<MouseParabolaPick>(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<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<StaticParabolaPick>(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<ParabolaPick>(position, direction, speed, accelerationAxis,
rotateAccelerationWithAvatar, rotateAccelerationWithParent, scaleWithParent, filter, maxDistance, enabled);
parabolaPick->parentTransform = createTransformNode(propMap);
parabolaPick->setJointState(getPickJointState(propMap));
return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, parabolaPick);
}
/**jsdoc
@ -297,6 +278,7 @@ unsigned int PickScriptingInterface::createCollisionPick(const QVariant& propert
CollisionRegion collisionRegion(propMap);
auto collisionPick = std::make_shared<CollisionPick>(filter, maxDistance, enabled, collisionRegion, qApp->getPhysicsEngine());
collisionPick->parentTransform = createTransformNode(propMap);
collisionPick->setJointState(getPickJointState(propMap));
return DependencyManager::get<PickManager>()->addPick(PickQuery::Collision, collisionPick);
}
@ -373,6 +355,37 @@ void PickScriptingInterface::setPerFrameTimeBudget(unsigned int numUsecs) {
DependencyManager::get<PickManager>()->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<AvatarManager>()->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<TransformNode> PickScriptingInterface::createTransformNode(const QVariantMap& propMap) {
if (propMap["parentID"].isValid()) {
QUuid parentUuid = propMap["parentID"].toUuid();

View file

@ -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<TransformNode> createTransformNode(const QVariantMap& propMap);
};

View file

@ -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<EntityScriptingInterface>()->findRayIntersectionVector(pick, !getFilter().doesPickCoarse(),

View file

@ -70,7 +70,12 @@ public:
class RayPick : public Pick<PickRay> {
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<RayPickResult>(pickVariant); }
PickResultPointer getEntityIntersection(const PickRay& pick) override;

View file

@ -16,10 +16,6 @@
#include <PickManager.h>
#include "StaticRayPick.h"
#include "JointRayPick.h"
#include "MouseRayPick.h"
unsigned int RayPickScriptingInterface::createRayPick(const QVariant& properties) {
return DependencyManager::get<PickScriptingInterface>()->createRayPick(properties);
}

View file

@ -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());
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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<QUuid>& items);
void setIncludeItems(const QVector<QUuid>& 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<QUuid> _ignoreItems;
QVector<QUuid> _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 {

View file

@ -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;
}
};