generalized scripting interfaces

This commit is contained in:
SamGondelman 2017-10-20 14:37:10 -07:00
parent 24ce09f914
commit fb969964f3
24 changed files with 417 additions and 231 deletions

View file

@ -197,6 +197,8 @@
#include <pointers/PointerManager.h>
#include <raypick/RayPickScriptingInterface.h>
#include <raypick/LaserPointerScriptingInterface.h>
#include <raypick/PickScriptingInterface.h>
#include <raypick/PointerScriptingInterface.h>
#include <raypick/MouseRayPick.h>
#include <FadeEffect.h>
@ -696,6 +698,8 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
DependencyManager::set<PointerManager>();
DependencyManager::set<LaserPointerScriptingInterface>();
DependencyManager::set<RayPickScriptingInterface>();
DependencyManager::set<PointerScriptingInterface>();
DependencyManager::set<PickScriptingInterface>();
return previousSessionCrashed;
}
@ -1825,14 +1829,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
DependencyManager::get<PickManager>()->setShouldPickHUDOperator([&]() { return DependencyManager::get<HMDScriptingInterface>()->isHMDMode(); });
// Setup the mouse ray pick and related operators
DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(DependencyManager::get<PickManager>()->addPick(RAY, std::make_shared<MouseRayPick>(
PickFilter(RayPickScriptingInterface::PICK_ENTITIES() | RayPickScriptingInterface::PICK_INCLUDE_NONCOLLIDABLE()), 0.0f, true)));
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)));
DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([&](QUuid rayPickID) {
RayToEntityIntersectionResult entityResult;
entityResult.intersects = false;
QVariantMap result = DependencyManager::get<PickManager>()->getPrevPickResult(rayPickID);
if (result["type"].isValid()) {
entityResult.intersects = result["type"] != RayPickScriptingInterface::INTERSECTED_NONE();
entityResult.intersects = result["type"] != PickScriptingInterface::INTERSECTED_NONE();
if (entityResult.intersects) {
entityResult.intersection = vec3FromVariant(result["intersection"]);
entityResult.distance = result["distance"].toFloat();
@ -5798,6 +5802,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
scriptEngine->registerGlobalObject("RayPick", DependencyManager::get<RayPickScriptingInterface>().data());
scriptEngine->registerGlobalObject("LaserPointers", DependencyManager::get<LaserPointerScriptingInterface>().data());
scriptEngine->registerGlobalObject("Picks", DependencyManager::get<PickScriptingInterface>().data());
scriptEngine->registerGlobalObject("Pointers", DependencyManager::get<PointerScriptingInterface>().data());
// Caches
scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get<AnimationCache>().data());

View file

@ -15,6 +15,7 @@
#include <GLMHelpers.h>
#include "PointerScriptingInterface.h"
#include "Application.h"
void LaserPointerScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) const {
@ -25,109 +26,9 @@ void LaserPointerScriptingInterface::setIncludeItems(const QUuid& uid, const QSc
}
QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) const {
QVariantMap propertyMap = properties.toMap();
bool faceAvatar = false;
if (propertyMap["faceAvatar"].isValid()) {
faceAvatar = propertyMap["faceAvatar"].toBool();
}
bool centerEndY = true;
if (propertyMap["centerEndY"].isValid()) {
centerEndY = propertyMap["centerEndY"].toBool();
}
bool lockEnd = false;
if (propertyMap["lockEnd"].isValid()) {
lockEnd = propertyMap["lockEnd"].toBool();
}
bool enabled = false;
if (propertyMap["enabled"].isValid()) {
enabled = propertyMap["enabled"].toBool();
}
LaserPointer::RenderStateMap renderStates;
if (propertyMap["renderStates"].isValid()) {
QList<QVariant> renderStateVariants = propertyMap["renderStates"].toList();
for (QVariant& renderStateVariant : renderStateVariants) {
if (renderStateVariant.isValid()) {
QVariantMap renderStateMap = renderStateVariant.toMap();
if (renderStateMap["name"].isValid()) {
std::string name = renderStateMap["name"].toString().toStdString();
renderStates[name] = buildRenderState(renderStateMap);
}
}
}
}
LaserPointer::DefaultRenderStateMap defaultRenderStates;
if (propertyMap["defaultRenderStates"].isValid()) {
QList<QVariant> renderStateVariants = propertyMap["defaultRenderStates"].toList();
for (QVariant& renderStateVariant : renderStateVariants) {
if (renderStateVariant.isValid()) {
QVariantMap renderStateMap = renderStateVariant.toMap();
if (renderStateMap["name"].isValid() && renderStateMap["distance"].isValid()) {
std::string name = renderStateMap["name"].toString().toStdString();
float distance = renderStateMap["distance"].toFloat();
defaultRenderStates[name] = std::pair<float, RenderState>(distance, buildRenderState(renderStateMap));
}
}
}
}
return DependencyManager::get<PointerManager>()->addPointer(std::make_shared<LaserPointer>(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled));
return DependencyManager::get<PointerScriptingInterface>()->createLaserPointer(properties);
}
void LaserPointerScriptingInterface::editRenderState(const QUuid& uid, const QString& renderState, const QVariant& properties) const {
QVariantMap propMap = properties.toMap();
QVariant startProps;
if (propMap["start"].isValid()) {
startProps = propMap["start"];
}
QVariant pathProps;
if (propMap["path"].isValid()) {
pathProps = propMap["path"];
}
QVariant endProps;
if (propMap["end"].isValid()) {
endProps = propMap["end"];
}
DependencyManager::get<PointerManager>()->editRenderState(uid, renderState.toStdString(), startProps, pathProps, endProps);
}
RenderState LaserPointerScriptingInterface::buildRenderState(const QVariantMap& propMap) {
QUuid startID;
if (propMap["start"].isValid()) {
QVariantMap startMap = propMap["start"].toMap();
if (startMap["type"].isValid()) {
startMap.remove("visible");
startID = qApp->getOverlays().addOverlay(startMap["type"].toString(), startMap);
}
}
QUuid pathID;
if (propMap["path"].isValid()) {
QVariantMap pathMap = propMap["path"].toMap();
// right now paths must be line3ds
if (pathMap["type"].isValid() && pathMap["type"].toString() == "line3d") {
pathMap.remove("visible");
pathID = qApp->getOverlays().addOverlay(pathMap["type"].toString(), pathMap);
}
}
QUuid endID;
if (propMap["end"].isValid()) {
QVariantMap endMap = propMap["end"].toMap();
if (endMap["type"].isValid()) {
endMap.remove("visible");
endID = qApp->getOverlays().addOverlay(endMap["type"].toString(), endMap);
}
}
return RenderState(startID, pathID, endID);
DependencyManager::get<PointerScriptingInterface>()->editRenderState(uid, renderState, properties);
}

View file

@ -16,8 +16,6 @@
#include "DependencyManager.h"
#include <pointers/PointerManager.h>
#include "LaserPointer.h"
class LaserPointerScriptingInterface : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
@ -29,7 +27,7 @@ public slots:
Q_INVOKABLE void removeLaserPointer(const QUuid& uid) const { DependencyManager::get<PointerManager>()->removePointer(uid); }
Q_INVOKABLE void editRenderState(const QUuid& uid, const QString& renderState, const QVariant& properties) const;
Q_INVOKABLE void setRenderState(const QUuid& uid, const QString& renderState) const { DependencyManager::get<PointerManager>()->setRenderState(uid, renderState.toStdString()); }
Q_INVOKABLE QVariantMap getPrevRayPickResult(QUuid uid) const { return DependencyManager::get<PointerManager>()->getPrevRayPickResult(uid); }
Q_INVOKABLE QVariantMap getPrevRayPickResult(QUuid uid) const { return DependencyManager::get<PointerManager>()->getPrevPickResult(uid); }
Q_INVOKABLE void setPrecisionPicking(const QUuid& uid, bool precisionPicking) const { DependencyManager::get<PointerManager>()->setPrecisionPicking(uid, precisionPicking); }
Q_INVOKABLE void setLaserLength(const QUuid& uid, float laserLength) const { DependencyManager::get<PointerManager>()->setLength(uid, laserLength); }
@ -38,9 +36,6 @@ public slots:
Q_INVOKABLE void setLockEndUUID(const QUuid& uid, const QUuid& objectID, bool isOverlay) const { DependencyManager::get<PointerManager>()->setLockEndUUID(uid, objectID, isOverlay); }
private:
static RenderState buildRenderState(const QVariantMap& propMap);
};
#endif // hifi_LaserPointerScriptingInterface_h

View file

@ -0,0 +1,107 @@
//
// Created by Sam Gondelman 10/20/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 "PickScriptingInterface.h"
#include <QVariant>
#include "GLMHelpers.h"
#include <pointers/PickManager.h>
#include "StaticRayPick.h"
#include "JointRayPick.h"
#include "MouseRayPick.h"
QUuid PickScriptingInterface::createPick(const PickQuery::PickType type, const QVariant& properties) {
switch (type) {
case PickQuery::PickType::Ray:
return createRayPick(properties);
default:
return QUuid();
}
}
QUuid PickScriptingInterface::createRayPick(const QVariant& properties) {
QVariantMap propMap = properties.toMap();
bool enabled = false;
if (propMap["enabled"].isValid()) {
enabled = propMap["enabled"].toBool();
}
PickFilter filter = PickFilter();
if (propMap["filter"].isValid()) {
filter = PickFilter(propMap["filter"].toUInt());
}
float maxDistance = 0.0f;
if (propMap["maxDistance"].isValid()) {
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));
}
return QUuid();
}
void PickScriptingInterface::enablePick(const QUuid& uid) {
DependencyManager::get<PickManager>()->enablePick(uid);
}
void PickScriptingInterface::disablePick(const QUuid& uid) {
DependencyManager::get<PickManager>()->disablePick(uid);
}
void PickScriptingInterface::removePick(const QUuid& uid) {
DependencyManager::get<PickManager>()->removePick(uid);
}
QVariantMap PickScriptingInterface::getPrevPickResult(const QUuid& uid) {
return DependencyManager::get<PickManager>()->getPrevPickResult(uid);
}
void PickScriptingInterface::setPrecisionPicking(const QUuid& uid, const bool precisionPicking) {
DependencyManager::get<PickManager>()->setPrecisionPicking(uid, precisionPicking);
}
void PickScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) {
DependencyManager::get<PickManager>()->setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems));
}
void PickScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) {
DependencyManager::get<PickManager>()->setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems));
}

View file

@ -0,0 +1,65 @@
//
// Created by Sam Gondelman 10/20/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_PickScriptingInterface_h
#define hifi_PickScriptingInterface_h
#include <QtCore/QObject>
#include <RegisteredMetaTypes.h>
#include <DependencyManager.h>
#include <pointers/Pick.h>
class PickScriptingInterface : public QObject, public Dependency {
Q_OBJECT
Q_PROPERTY(unsigned int PICK_NOTHING READ PICK_NOTHING CONSTANT)
Q_PROPERTY(unsigned int PICK_ENTITIES READ PICK_ENTITIES CONSTANT)
Q_PROPERTY(unsigned int PICK_OVERLAYS READ PICK_OVERLAYS CONSTANT)
Q_PROPERTY(unsigned int PICK_AVATARS READ PICK_AVATARS CONSTANT)
Q_PROPERTY(unsigned int PICK_HUD READ PICK_HUD CONSTANT)
Q_PROPERTY(unsigned int PICK_COARSE READ PICK_COARSE CONSTANT)
Q_PROPERTY(unsigned int PICK_INCLUDE_INVISIBLE READ PICK_INCLUDE_INVISIBLE CONSTANT)
Q_PROPERTY(unsigned int PICK_INCLUDE_NONCOLLIDABLE READ PICK_INCLUDE_NONCOLLIDABLE CONSTANT)
Q_PROPERTY(unsigned int PICK_ALL_INTERSECTIONS READ PICK_ALL_INTERSECTIONS CONSTANT)
Q_PROPERTY(unsigned int INTERSECTED_NONE READ INTERSECTED_NONE CONSTANT)
Q_PROPERTY(unsigned int INTERSECTED_ENTITY READ INTERSECTED_ENTITY CONSTANT)
Q_PROPERTY(unsigned int INTERSECTED_OVERLAY READ INTERSECTED_OVERLAY CONSTANT)
Q_PROPERTY(unsigned int INTERSECTED_AVATAR READ INTERSECTED_AVATAR CONSTANT)
Q_PROPERTY(unsigned int INTERSECTED_HUD READ INTERSECTED_HUD CONSTANT)
SINGLETON_DEPENDENCY
public:
QUuid createRayPick(const QVariant& properties);
public slots:
Q_INVOKABLE QUuid createPick(const PickQuery::PickType type, const QVariant& properties);
Q_INVOKABLE void enablePick(const QUuid& uid);
Q_INVOKABLE void disablePick(const QUuid& uid);
Q_INVOKABLE void removePick(const QUuid& uid);
Q_INVOKABLE QVariantMap getPrevPickResult(const QUuid& uid);
Q_INVOKABLE void setPrecisionPicking(const QUuid& uid, const bool precisionPicking);
Q_INVOKABLE void setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreEntities);
Q_INVOKABLE void setIncludeItems(const QUuid& uid, const QScriptValue& includeEntities);
static constexpr unsigned int PICK_NOTHING() { return 0; }
static constexpr unsigned int PICK_ENTITIES() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ENTITIES); }
static constexpr unsigned int PICK_OVERLAYS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_OVERLAYS); }
static constexpr unsigned int PICK_AVATARS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_AVATARS); }
static constexpr unsigned int PICK_HUD() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_HUD); }
static constexpr unsigned int PICK_COARSE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_COARSE); }
static constexpr unsigned int PICK_INCLUDE_INVISIBLE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_INCLUDE_INVISIBLE); }
static constexpr unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_INCLUDE_NONCOLLIDABLE); }
static constexpr unsigned int PICK_ALL_INTERSECTIONS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ALL_INTERSECTIONS); }
static constexpr unsigned int INTERSECTED_NONE() { return IntersectionType::NONE; }
static constexpr unsigned int INTERSECTED_ENTITY() { return IntersectionType::ENTITY; }
static constexpr unsigned int INTERSECTED_OVERLAY() { return IntersectionType::OVERLAY; }
static constexpr unsigned int INTERSECTED_AVATAR() { return IntersectionType::AVATAR; }
static constexpr unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; }
};
#endif // hifi_PickScriptingInterface_h

View file

@ -0,0 +1,139 @@
//
// Created by Sam Gondelman 10/20/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 "PointerScriptingInterface.h"
#include <QtCore/QVariant>
#include <GLMHelpers.h>
#include "Application.h"
void PointerScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) const {
DependencyManager::get<PointerManager>()->setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems));
}
void PointerScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) const {
DependencyManager::get<PointerManager>()->setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems));
}
QUuid PointerScriptingInterface::createPointer(const PickQuery::PickType type, const QVariant& properties) const {
switch (type) {
case PickQuery::PickType::Ray:
return createLaserPointer(properties);
default:
return QUuid();
}
}
QUuid PointerScriptingInterface::createLaserPointer(const QVariant& properties) const {
QVariantMap propertyMap = properties.toMap();
bool faceAvatar = false;
if (propertyMap["faceAvatar"].isValid()) {
faceAvatar = propertyMap["faceAvatar"].toBool();
}
bool centerEndY = true;
if (propertyMap["centerEndY"].isValid()) {
centerEndY = propertyMap["centerEndY"].toBool();
}
bool lockEnd = false;
if (propertyMap["lockEnd"].isValid()) {
lockEnd = propertyMap["lockEnd"].toBool();
}
bool enabled = false;
if (propertyMap["enabled"].isValid()) {
enabled = propertyMap["enabled"].toBool();
}
LaserPointer::RenderStateMap renderStates;
if (propertyMap["renderStates"].isValid()) {
QList<QVariant> renderStateVariants = propertyMap["renderStates"].toList();
for (QVariant& renderStateVariant : renderStateVariants) {
if (renderStateVariant.isValid()) {
QVariantMap renderStateMap = renderStateVariant.toMap();
if (renderStateMap["name"].isValid()) {
std::string name = renderStateMap["name"].toString().toStdString();
renderStates[name] = buildRenderState(renderStateMap);
}
}
}
}
LaserPointer::DefaultRenderStateMap defaultRenderStates;
if (propertyMap["defaultRenderStates"].isValid()) {
QList<QVariant> renderStateVariants = propertyMap["defaultRenderStates"].toList();
for (QVariant& renderStateVariant : renderStateVariants) {
if (renderStateVariant.isValid()) {
QVariantMap renderStateMap = renderStateVariant.toMap();
if (renderStateMap["name"].isValid() && renderStateMap["distance"].isValid()) {
std::string name = renderStateMap["name"].toString().toStdString();
float distance = renderStateMap["distance"].toFloat();
defaultRenderStates[name] = std::pair<float, RenderState>(distance, buildRenderState(renderStateMap));
}
}
}
}
return DependencyManager::get<PointerManager>()->addPointer(std::make_shared<LaserPointer>(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled));
}
void PointerScriptingInterface::editRenderState(const QUuid& uid, const QString& renderState, const QVariant& properties) const {
QVariantMap propMap = properties.toMap();
QVariant startProps;
if (propMap["start"].isValid()) {
startProps = propMap["start"];
}
QVariant pathProps;
if (propMap["path"].isValid()) {
pathProps = propMap["path"];
}
QVariant endProps;
if (propMap["end"].isValid()) {
endProps = propMap["end"];
}
DependencyManager::get<PointerManager>()->editRenderState(uid, renderState.toStdString(), startProps, pathProps, endProps);
}
RenderState PointerScriptingInterface::buildRenderState(const QVariantMap& propMap) {
QUuid startID;
if (propMap["start"].isValid()) {
QVariantMap startMap = propMap["start"].toMap();
if (startMap["type"].isValid()) {
startMap.remove("visible");
startID = qApp->getOverlays().addOverlay(startMap["type"].toString(), startMap);
}
}
QUuid pathID;
if (propMap["path"].isValid()) {
QVariantMap pathMap = propMap["path"].toMap();
// right now paths must be line3ds
if (pathMap["type"].isValid() && pathMap["type"].toString() == "line3d") {
pathMap.remove("visible");
pathID = qApp->getOverlays().addOverlay(pathMap["type"].toString(), pathMap);
}
}
QUuid endID;
if (propMap["end"].isValid()) {
QVariantMap endMap = propMap["end"].toMap();
if (endMap["type"].isValid()) {
endMap.remove("visible");
endID = qApp->getOverlays().addOverlay(endMap["type"].toString(), endMap);
}
}
return RenderState(startID, pathID, endID);
}

View file

@ -0,0 +1,46 @@
//
// Created by Sam Gondelman 10/20/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_PointerScriptingInterface_h
#define hifi_PointerScriptingInterface_h
#include <QtCore/QObject>
#include "DependencyManager.h"
#include <pointers/PointerManager.h>
#include "LaserPointer.h"
class PointerScriptingInterface : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public:
QUuid createLaserPointer(const QVariant& properties) const;
public slots:
Q_INVOKABLE QUuid createPointer(const PickQuery::PickType type, const QVariant& properties) const;
Q_INVOKABLE void enablePointer(const QUuid& uid) const { DependencyManager::get<PointerManager>()->enablePointer(uid); }
Q_INVOKABLE void disablePointer(const QUuid& uid) const { DependencyManager::get<PointerManager>()->disablePointer(uid); }
Q_INVOKABLE void removePointer(const QUuid& uid) const { DependencyManager::get<PointerManager>()->removePointer(uid); }
Q_INVOKABLE void editRenderState(const QUuid& uid, const QString& renderState, const QVariant& properties) const;
Q_INVOKABLE void setRenderState(const QUuid& uid, const QString& renderState) const { DependencyManager::get<PointerManager>()->setRenderState(uid, renderState.toStdString()); }
Q_INVOKABLE QVariantMap getPrevPickResult(QUuid uid) const { return DependencyManager::get<PointerManager>()->getPrevPickResult(uid); }
Q_INVOKABLE void setPrecisionPicking(const QUuid& uid, bool precisionPicking) const { DependencyManager::get<PointerManager>()->setPrecisionPicking(uid, precisionPicking); }
Q_INVOKABLE void setLaserLength(const QUuid& uid, float laserLength) const { DependencyManager::get<PointerManager>()->setLength(uid, laserLength); }
Q_INVOKABLE void setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreEntities) const;
Q_INVOKABLE void setIncludeItems(const QUuid& uid, const QScriptValue& includeEntities) const;
Q_INVOKABLE void setLockEndUUID(const QUuid& uid, const QUuid& objectID, bool isOverlay) const { DependencyManager::get<PointerManager>()->setLockEndUUID(uid, objectID, isOverlay); }
private:
static RenderState buildRenderState(const QVariantMap& propMap);
};
#endif // hifi_PointerScriptingInterface_h

View file

@ -21,55 +21,7 @@
#include "MouseRayPick.h"
QUuid RayPickScriptingInterface::createRayPick(const QVariant& properties) {
QVariantMap propMap = properties.toMap();
bool enabled = false;
if (propMap["enabled"].isValid()) {
enabled = propMap["enabled"].toBool();
}
PickFilter filter = PickFilter();
if (propMap["filter"].isValid()) {
filter = PickFilter(propMap["filter"].toUInt());
}
float maxDistance = 0.0f;
if (propMap["maxDistance"].isValid()) {
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(RAY, std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled));
} else {
return DependencyManager::get<PickManager>()->addPick(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(RAY, std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled));
}
return QUuid();
return DependencyManager::get<PickScriptingInterface>()->createRayPick(properties);
}
void RayPickScriptingInterface::enableRayPick(const QUuid& uid) {

View file

@ -17,22 +17,10 @@
#include <DependencyManager.h>
#include "RayPick.h"
#include "PickScriptingInterface.h"
class RayPickScriptingInterface : public QObject, public Dependency {
Q_OBJECT
Q_PROPERTY(unsigned int PICK_NOTHING READ PICK_NOTHING CONSTANT)
Q_PROPERTY(unsigned int PICK_ENTITIES READ PICK_ENTITIES CONSTANT)
Q_PROPERTY(unsigned int PICK_OVERLAYS READ PICK_OVERLAYS CONSTANT)
Q_PROPERTY(unsigned int PICK_AVATARS READ PICK_AVATARS CONSTANT)
Q_PROPERTY(unsigned int PICK_HUD READ PICK_HUD CONSTANT)
Q_PROPERTY(unsigned int PICK_COARSE READ PICK_COARSE CONSTANT)
Q_PROPERTY(unsigned int PICK_INCLUDE_INVISIBLE READ PICK_INCLUDE_INVISIBLE CONSTANT)
Q_PROPERTY(unsigned int PICK_INCLUDE_NONCOLLIDABLE READ PICK_INCLUDE_NONCOLLIDABLE CONSTANT)
Q_PROPERTY(unsigned int PICK_ALL_INTERSECTIONS READ PICK_ALL_INTERSECTIONS CONSTANT)
Q_PROPERTY(unsigned int INTERSECTED_NONE READ INTERSECTED_NONE CONSTANT)
Q_PROPERTY(unsigned int INTERSECTED_ENTITY READ INTERSECTED_ENTITY CONSTANT)
Q_PROPERTY(unsigned int INTERSECTED_OVERLAY READ INTERSECTED_OVERLAY CONSTANT)
Q_PROPERTY(unsigned int INTERSECTED_AVATAR READ INTERSECTED_AVATAR CONSTANT)
Q_PROPERTY(unsigned int INTERSECTED_HUD READ INTERSECTED_HUD CONSTANT)
SINGLETON_DEPENDENCY
public slots:
@ -45,21 +33,6 @@ public slots:
Q_INVOKABLE void setPrecisionPicking(const QUuid& uid, const bool precisionPicking);
Q_INVOKABLE void setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreEntities);
Q_INVOKABLE void setIncludeItems(const QUuid& uid, const QScriptValue& includeEntities);
static constexpr unsigned int PICK_NOTHING() { return 0; }
static constexpr unsigned int PICK_ENTITIES() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ENTITIES); }
static constexpr unsigned int PICK_OVERLAYS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_OVERLAYS); }
static constexpr unsigned int PICK_AVATARS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_AVATARS); }
static constexpr unsigned int PICK_HUD() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_HUD); }
static constexpr unsigned int PICK_COARSE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_COARSE); }
static constexpr unsigned int PICK_INCLUDE_INVISIBLE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_INCLUDE_INVISIBLE); }
static constexpr unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_INCLUDE_NONCOLLIDABLE); }
static constexpr unsigned int PICK_ALL_INTERSECTIONS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ALL_INTERSECTIONS); }
static constexpr unsigned int INTERSECTED_NONE() { return IntersectionType::NONE; }
static constexpr unsigned int INTERSECTED_ENTITY() { return IntersectionType::ENTITY; }
static constexpr unsigned int INTERSECTED_OVERLAY() { return IntersectionType::OVERLAY; }
static constexpr unsigned int INTERSECTED_AVATAR() { return IntersectionType::AVATAR; }
static constexpr unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; }
};
#endif // hifi_RayPickScriptingInterface_h

View file

@ -130,9 +130,16 @@ public:
using PickResultPointer = std::shared_ptr<PickResult>;
class PickQuery : protected ReadWriteLockable {
Q_GADGET
public:
PickQuery(const PickFilter& filter, const float maxDistance, const bool enabled);
enum PickType {
Ray = 0,
Stylus
};
Q_ENUM(PickType)
void enable(bool enabled = true);
void disable() { enable(false); }

View file

@ -11,7 +11,7 @@ PickManager::PickManager() {
setShouldPickHUDOperator([]() { return false; });
}
QUuid PickManager::addPick(PickType type, const std::shared_ptr<PickQuery> pick) {
QUuid PickManager::addPick(PickQuery::PickType type, const std::shared_ptr<PickQuery> pick) {
QUuid id = QUuid::createUuid();
withWriteLock([&] {
_picks[type][id] = pick;
@ -84,11 +84,11 @@ void PickManager::setIncludeItems(const QUuid& uid, const QVector<QUuid>& includ
}
void PickManager::update() {
QHash<PickType, QHash<QUuid, std::shared_ptr<PickQuery>>> cachedPicks;
QHash<PickQuery::PickType, QHash<QUuid, std::shared_ptr<PickQuery>>> cachedPicks;
withReadLock([&] {
cachedPicks = _picks;
});
bool shouldPickHUD = _shouldPickHUDOperator();
_rayPickCacheOptimizer.update(cachedPicks[RAY], shouldPickHUD);
_rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], shouldPickHUD);
}

View file

@ -16,11 +16,6 @@
#include "Pick.h"
#include "PickCacheOptimizer.h"
enum PickType {
RAY = 0,
STYLUS
};
class PickManager : public Dependency, protected ReadWriteLockable {
SINGLETON_DEPENDENCY
@ -29,7 +24,7 @@ public:
void update();
QUuid addPick(PickType type, const std::shared_ptr<PickQuery> pick);
QUuid addPick(PickQuery::PickType type, const std::shared_ptr<PickQuery> pick);
void removePick(const QUuid& uid);
void enablePick(const QUuid& uid) const;
void disablePick(const QUuid& uid) const;
@ -46,8 +41,8 @@ protected:
std::function<bool()> _shouldPickHUDOperator;
std::shared_ptr<PickQuery> findPick(const QUuid& uid) const;
QHash<PickType, QHash<QUuid, std::shared_ptr<PickQuery>>> _picks;
QHash<QUuid, PickType> _typeMap;
QHash<PickQuery::PickType, QHash<QUuid, std::shared_ptr<PickQuery>>> _picks;
QHash<QUuid, PickQuery::PickType> _typeMap;
PickCacheOptimizer<PickRay> _rayPickCacheOptimizer;
};

View file

@ -61,7 +61,7 @@ void PointerManager::editRenderState(const QUuid& uid, const std::string& state,
}
}
const QVariantMap PointerManager::getPrevRayPickResult(const QUuid& uid) const {
const QVariantMap PointerManager::getPrevPickResult(const QUuid& uid) const {
auto pointer = find(uid);
if (pointer) {
return pointer->getPrevPickResult();

View file

@ -30,7 +30,7 @@ public:
void disablePointer(const QUuid& uid) const;
void setRenderState(const QUuid& uid, const std::string& renderState) const;
void editRenderState(const QUuid& uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) const;
const QVariantMap getPrevRayPickResult(const QUuid& uid) const;
const QVariantMap getPrevPickResult(const QUuid& uid) const;
void setPrecisionPicking(const QUuid& uid, const bool precisionPicking) const;
void setIgnoreItems(const QUuid& uid, const QVector<QUuid>& ignoreEntities) const;

View file

@ -252,7 +252,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
length: 1000
};
if (rayPicks[h].type === RayPick.INTERSECTED_ENTITY) {
if (rayPicks[h].type === Picks.INTERSECTED_ENTITY) {
// XXX check to make sure this one isn't already in nearbyEntityProperties?
if (rayPicks[h].distance < NEAR_GRAB_PICK_RADIUS * sensorScaleFactor) {
var nearEntityID = rayPicks[h].objectID;
@ -390,35 +390,35 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
this.leftControllerRayPick = RayPick.createRayPick({
joint: "_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS,
enabled: true,
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand, true)
});
this.leftControllerHudRayPick = RayPick.createRayPick({
joint: "_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_HUD,
filter: Picks.PICK_HUD,
enabled: true,
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand, true)
});
this.rightControllerRayPick = RayPick.createRayPick({
joint: "_CONTROLLER_RIGHTHAND",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS,
enabled: true,
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand, true)
});
this.rightControllerHudRayPick = RayPick.createRayPick({
joint: "_CONTROLLER_RIGHTHAND",
filter: RayPick.PICK_HUD,
filter: Picks.PICK_HUD,
enabled: true,
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand, true)
});
this.mouseRayPick = RayPick.createRayPick({
joint: "Mouse",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS,
enabled: true
});

View file

@ -376,8 +376,8 @@ Script.include("/~/system/libraries/controllers.js");
var entityType = entityProperty.type;
var hudRayPick = controllerData.hudRayPicks[this.hand];
var point2d = this.calculateNewReticlePosition(hudRayPick.intersection);
if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web") ||
intersection.type === RayPick.INTERSECTED_OVERLAY || Window.isPointOnDesktopWindow(point2d)) {
if ((intersection.type === Picks.INTERSECTED_ENTITY && entityType === "Web") ||
intersection.type === Picks.INTERSECTED_OVERLAY || Window.isPointOnDesktopWindow(point2d)) {
return true;
}
return false;
@ -497,7 +497,7 @@ Script.include("/~/system/libraries/controllers.js");
}
var rayPickInfo = controllerData.rayPicks[this.hand];
if (rayPickInfo.type === RayPick.INTERSECTED_ENTITY) {
if (rayPickInfo.type === Picks.INTERSECTED_ENTITY) {
if (controllerData.triggerClicks[this.hand]) {
var entityID = rayPickInfo.objectID;
var targetProps = Entities.getEntityProperties(entityID, [
@ -581,7 +581,7 @@ Script.include("/~/system/libraries/controllers.js");
this.fullEnd = fullEnd;
this.laserPointer = LaserPointers.createLaserPointer({
joint: (this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS,
maxDistance: PICK_MAX_DISTANCE,
posOffset: getGrabPointSphereOffset(this.handToController(), true),
renderStates: renderStates,

View file

@ -196,7 +196,7 @@ Script.include("/~/system/libraries/controllers.js");
this.fullEnd = fullEnd;
this.laserPointer = LaserPointers.createLaserPointer({
joint: (this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS,
maxDistance: PICK_MAX_DISTANCE,
posOffset: getGrabPointSphereOffset(this.handToController(), true),
renderStates: renderStates,

View file

@ -216,7 +216,7 @@
this.fullEnd = fullEnd;
this.laserPointer = LaserPointers.createLaserPointer({
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_HUD,
filter: Picks.PICK_HUD,
maxDistance: PICK_MAX_DISTANCE,
posOffset: getGrabPointSphereOffset(this.handToController(), true),
renderStates: renderStates,

View file

@ -153,12 +153,12 @@ Script.include("/~/system/libraries/utils.js");
this.sendPickData = function(controllerData) {
if (controllerData.triggerClicks[this.hand] && !this.triggerClicked) {
var intersection = controllerData.rayPicks[this.hand];
if (intersection.type === RayPick.INTERSECTED_ENTITY) {
if (intersection.type === Picks.INTERSECTED_ENTITY) {
Messages.sendLocalMessage("entityToolUpdates", JSON.stringify({
method: "selectEntity",
entityID: intersection.objectID
}));
} else if (intersection.type === RayPick.INTERSECTED_OVERLAY) {
} else if (intersection.type === Picks.INTERSECTED_OVERLAY) {
Messages.sendLocalMessage("entityToolUpdates", JSON.stringify({
method: "selectOverlay",
overlayID: intersection.objectID
@ -243,7 +243,7 @@ Script.include("/~/system/libraries/utils.js");
this.laserPointer = LaserPointers.createLaserPointer({
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS,
maxDistance: PICK_MAX_DISTANCE,
posOffset: getGrabPointSphereOffset(this.handToController(), true),
renderStates: renderStates,

View file

@ -301,7 +301,7 @@ Script.include("/~/system/libraries/controllers.js");
this.shouldExit = function(controllerData) {
var intersection = controllerData.rayPicks[this.hand];
var offOverlay = (intersection.type !== RayPick.INTERSECTED_OVERLAY);
var offOverlay = (intersection.type !== Picks.INTERSECTED_OVERLAY);
var triggerOff = (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE);
if (triggerOff) {
this.deleteContextOverlay();
@ -375,7 +375,7 @@ Script.include("/~/system/libraries/controllers.js");
this.fullEnd = fullEnd;
this.laserPointer = LaserPointers.createLaserPointer({
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_OVERLAYS,
filter: Picks.PICK_OVERLAYS,
maxDistance: PICK_MAX_DISTANCE,
posOffset: getGrabPointSphereOffset(this.handToController(), true),
renderStates: renderStates,

View file

@ -149,7 +149,7 @@ Script.include("/~/system/libraries/controllers.js");
this.teleportRayHandVisible = LaserPointers.createLaserPointer({
joint: (_this.hand === RIGHT_HAND) ? "RightHand" : "LeftHand",
filter: RayPick.PICK_ENTITIES,
filter: Picks.PICK_ENTITIES,
faceAvatar: true,
centerEndY: false,
renderStates: teleportRenderStates,
@ -157,14 +157,14 @@ Script.include("/~/system/libraries/controllers.js");
});
this.teleportRayHandInvisible = LaserPointers.createLaserPointer({
joint: (_this.hand === RIGHT_HAND) ? "RightHand" : "LeftHand",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_INCLUDE_INVISIBLE,
filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE,
faceAvatar: true,
centerEndY: false,
renderStates: teleportRenderStates
});
this.teleportRayHeadVisible = LaserPointers.createLaserPointer({
joint: "Avatar",
filter: RayPick.PICK_ENTITIES,
filter: Picks.PICK_ENTITIES,
faceAvatar: true,
centerEndY: false,
renderStates: teleportRenderStates,
@ -172,7 +172,7 @@ Script.include("/~/system/libraries/controllers.js");
});
this.teleportRayHeadInvisible = LaserPointers.createLaserPointer({
joint: "Avatar",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_INCLUDE_INVISIBLE,
filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE,
faceAvatar: true,
centerEndY: false,
renderStates: teleportRenderStates
@ -397,7 +397,7 @@ Script.include("/~/system/libraries/controllers.js");
// you can't teleport there.
var MAX_ANGLE_FROM_UP_TO_TELEPORT = 70;
function getTeleportTargetType(result) {
if (result.type === RayPick.INTERSECTED_NONE) {
if (result.type === Picks.INTERSECTED_NONE) {
return TARGET.NONE;
}

View file

@ -386,7 +386,7 @@ Script.include("/~/system/libraries/controllers.js");
var entityProperty = Entities.getEntityProperties(intersection.objectID);
var entityType = entityProperty.type;
if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web")) {
if ((intersection.type === Picks.INTERSECTED_ENTITY && entityType === "Web")) {
return true;
}
return false;
@ -454,7 +454,7 @@ Script.include("/~/system/libraries/controllers.js");
this.laserPointer = LaserPointers.createLaserPointer({
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_ENTITIES,
filter: Picks.PICK_ENTITIES,
maxDistance: PICK_MAX_DISTANCE,
posOffset: getGrabPointSphereOffset(this.handToController(), true),
renderStates: renderStates,

View file

@ -260,14 +260,14 @@ function Grabber() {
this.mouseRayOverlays = RayPick.createRayPick({
joint: "Mouse",
filter: RayPick.PICK_OVERLAYS,
filter: Picks.PICK_OVERLAYS,
enabled: true
});
RayPick.setIncludeItems(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]);
var renderStates = [{name: "grabbed", end: beacon}];
this.mouseRayEntities = LaserPointers.createLaserPointer({
joint: "Mouse",
filter: RayPick.PICK_ENTITIES,
filter: Picks.PICK_ENTITIES,
faceAvatar: true,
enabled: true,
renderStates: renderStates
@ -321,12 +321,12 @@ Grabber.prototype.pressEvent = function(event) {
}
var overlayResult = RayPick.getPrevRayPickResult(this.mouseRayOverlays);
if (overlayResult.type != RayPick.INTERSECTED_NONE) {
if (overlayResult.type != Picks.INTERSECTED_NONE) {
return;
}
var pickResults = LaserPointers.getPrevRayPickResult(this.mouseRayEntities);
if (pickResults.type == RayPick.INTERSECTED_NONE) {
if (pickResults.type == Picks.INTERSECTED_NONE) {
LaserPointers.setRenderState(this.mouseRayEntities, "");
return;
}

View file

@ -130,7 +130,7 @@ function sendTouchMoveEventToTouchTarget(hand, touchTarget) {
}
function composeTouchTargetFromIntersection(intersection) {
var isEntity = (intersection.type === RayPick.INTERSECTED_ENTITY);
var isEntity = (intersection.type === Picks.INTERSECTED_ENTITY);
var objectID = intersection.objectID;
var worldPos = intersection.intersection;
var props = null;