expanded RayPick JS API

This commit is contained in:
SamGondelman 2017-07-20 13:53:39 -07:00
parent d156680bc8
commit c7f0f03fce
8 changed files with 129 additions and 158 deletions

View file

@ -10,56 +10,17 @@
//
#include "LaserPointer.h"
#include "JointRayPick.h"
#include "StaticRayPick.h"
#include "MouseRayPick.h"
#include "Application.h"
#include "avatar/AvatarManager.h"
LaserPointer::LaserPointer(const QString& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) :
LaserPointer::LaserPointer(const QVariantMap& rayProps, const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) :
_renderingEnabled(enabled),
_renderStates(renderStates),
_faceAvatar(faceAvatar),
_centerEndY(centerEndY),
_lockEnd(lockEnd)
{
_rayPickUID = DependencyManager::get<RayPickManager>()->addRayPick(std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled));
for (auto& state : _renderStates.keys()) {
if (!enabled || state != _currentRenderState) {
disableRenderState(state);
}
}
}
LaserPointer::LaserPointer(const glm::vec3& position, const glm::vec3& direction, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) :
_renderingEnabled(enabled),
_renderStates(renderStates),
_faceAvatar(faceAvatar),
_centerEndY(centerEndY),
_lockEnd(lockEnd)
{
_rayPickUID = DependencyManager::get<RayPickManager>()->addRayPick(std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled));
for (auto& state : _renderStates.keys()) {
if (!enabled || state != _currentRenderState) {
disableRenderState(state);
}
}
}
LaserPointer::LaserPointer(const uint16_t filter, const float maxDistance, const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY,
const bool lockEnd, const bool enabled) :
_renderingEnabled(enabled),
_renderStates(renderStates),
_faceAvatar(faceAvatar),
_centerEndY(centerEndY),
_lockEnd(lockEnd)
{
_rayPickUID = DependencyManager::get<RayPickManager>()->addRayPick(std::make_shared<MouseRayPick>(filter, maxDistance, enabled));
_rayPickUID = DependencyManager::get<RayPickManager>()->createRayPick(rayProps);
for (auto& state : _renderStates.keys()) {
if (!enabled || state != _currentRenderState) {

View file

@ -49,15 +49,11 @@ private:
class LaserPointer {
public:
LaserPointer(const QString& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
LaserPointer(const glm::vec3& position, const glm::vec3& direction, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
LaserPointer(const uint16_t filter, const float maxDistance, const QHash<QString, RenderState>& renderStates, const bool faceAvatar,
const bool centerEndY, const bool lockEnd, const bool enabled);
LaserPointer::LaserPointer(const QVariantMap& rayProps, const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY,
const bool lockEnd, const bool enabled);
~LaserPointer();
unsigned int getUID() { return _rayPickUID; }
unsigned int getRayUID() { return _rayPickUID; }
void enable();
void disable();
const RayPickResult getPrevRayPickResult() { return DependencyManager::get<RayPickManager>()->getPrevRayPickResult(_rayPickUID); }

View file

@ -12,44 +12,24 @@
#include "LaserPointer.h"
#include "RayPick.h"
unsigned int LaserPointerManager::createLaserPointer(const QString& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(jointName, posOffset, dirOffset, filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
unsigned int uid = laserPointer->getUID();
QWriteLocker lock(&_lock);
_laserPointers[uid] = laserPointer;
_laserPointerLocks[uid] = std::make_shared<QReadWriteLock>();
return uid;
}
unsigned int LaserPointerManager::createLaserPointer(const glm::vec3& position, const glm::vec3& direction, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(position, direction, filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
unsigned int uid = laserPointer->getUID();
QWriteLocker lock(&_lock);
_laserPointers[uid] = laserPointer;
_laserPointerLocks[uid] = std::make_shared<QReadWriteLock>();
return uid;
}
unsigned int LaserPointerManager::createLaserPointer(const uint16_t filter, const float maxDistance, const QHash<QString, RenderState>& renderStates, const bool faceAvatar,
const bool centerEndY, const bool lockEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
unsigned int uid = laserPointer->getUID();
QWriteLocker lock(&_lock);
_laserPointers[uid] = laserPointer;
_laserPointerLocks[uid] = std::make_shared<QReadWriteLock>();
return uid;
unsigned int LaserPointerManager::createLaserPointer(const QVariantMap& rayProps, const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY,
const bool lockEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
if (laserPointer->getRayUID() != 0) {
QWriteLocker lock(&_addLock);
_laserPointersToAdd.enqueue(QPair<unsigned int, std::shared_ptr<LaserPointer>>(_nextUID, laserPointer));
return _nextUID++;
}
return 0;
}
void LaserPointerManager::removeLaserPointer(const unsigned int uid) {
QWriteLocker lock(&_lock);
_laserPointers.remove(uid);
_laserPointerLocks.remove(uid);
QWriteLocker lock(&_removeLock);
_laserPointersToRemove.enqueue(uid);
}
void LaserPointerManager::enableLaserPointer(const unsigned int uid) {
QReadLocker lock(&_lock);
QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->enable();
@ -57,7 +37,7 @@ void LaserPointerManager::enableLaserPointer(const unsigned int uid) {
}
void LaserPointerManager::disableLaserPointer(const unsigned int uid) {
QReadLocker lock(&_lock);
QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->disable();
@ -65,7 +45,7 @@ void LaserPointerManager::disableLaserPointer(const unsigned int uid) {
}
void LaserPointerManager::setRenderState(unsigned int uid, const QString & renderState) {
QReadLocker lock(&_lock);
QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setRenderState(renderState);
@ -73,7 +53,7 @@ void LaserPointerManager::setRenderState(unsigned int uid, const QString & rende
}
void LaserPointerManager::editRenderState(unsigned int uid, const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
QReadLocker lock(&_lock);
QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->editRenderState(state, startProps, pathProps, endProps);
@ -81,7 +61,7 @@ void LaserPointerManager::editRenderState(unsigned int uid, const QString& state
}
const RayPickResult LaserPointerManager::getPrevRayPickResult(const unsigned int uid) {
QReadLocker lock(&_lock);
QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) {
QReadLocker laserLock(_laserPointerLocks[uid].get());
return _laserPointers[uid]->getPrevRayPickResult();
@ -90,16 +70,34 @@ const RayPickResult LaserPointerManager::getPrevRayPickResult(const unsigned int
}
void LaserPointerManager::update() {
QReadLocker lock(&_lock);
for (unsigned int uid : _laserPointers.keys()) {
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
QReadLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->update();
}
QWriteLocker containsLock(&_containsLock);
{
QWriteLocker lock(&_addLock);
while (!_laserPointersToAdd.isEmpty()) {
QPair<unsigned int, std::shared_ptr<LaserPointer>> laserPointerToAdd = _laserPointersToAdd.dequeue();
_laserPointers[laserPointerToAdd.first] = laserPointerToAdd.second;
_laserPointerLocks[laserPointerToAdd.first] = std::make_shared<QReadWriteLock>();
}
}
{
QWriteLocker lock(&_removeLock);
while (!_laserPointersToRemove.isEmpty()) {
unsigned int uid = _laserPointersToRemove.dequeue();
_laserPointers.remove(uid);
_laserPointerLocks.remove(uid);
}
}
}
void LaserPointerManager::setIgnoreEntities(unsigned int uid, const QScriptValue& ignoreEntities) {
QReadLocker lock(&_lock);
QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIgnoreEntities(ignoreEntities);
@ -107,7 +105,7 @@ void LaserPointerManager::setIgnoreEntities(unsigned int uid, const QScriptValue
}
void LaserPointerManager::setIncludeEntities(unsigned int uid, const QScriptValue& includeEntities) {
QReadLocker lock(&_lock);
QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIncludeEntities(includeEntities);
@ -115,7 +113,7 @@ void LaserPointerManager::setIncludeEntities(unsigned int uid, const QScriptValu
}
void LaserPointerManager::setIgnoreOverlays(unsigned int uid, const QScriptValue& ignoreOverlays) {
QReadLocker lock(&_lock);
QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIgnoreOverlays(ignoreOverlays);
@ -123,7 +121,7 @@ void LaserPointerManager::setIgnoreOverlays(unsigned int uid, const QScriptValue
}
void LaserPointerManager::setIncludeOverlays(unsigned int uid, const QScriptValue& includeOverlays) {
QReadLocker lock(&_lock);
QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIncludeOverlays(includeOverlays);
@ -131,7 +129,7 @@ void LaserPointerManager::setIncludeOverlays(unsigned int uid, const QScriptValu
}
void LaserPointerManager::setIgnoreAvatars(unsigned int uid, const QScriptValue& ignoreAvatars) {
QReadLocker lock(&_lock);
QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIgnoreAvatars(ignoreAvatars);
@ -139,7 +137,7 @@ void LaserPointerManager::setIgnoreAvatars(unsigned int uid, const QScriptValue&
}
void LaserPointerManager::setIncludeAvatars(unsigned int uid, const QScriptValue& includeAvatars) {
QReadLocker lock(&_lock);
QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIncludeAvatars(includeAvatars);

View file

@ -25,12 +25,8 @@ class LaserPointerManager : public Dependency {
SINGLETON_DEPENDENCY
public:
unsigned int createLaserPointer(const QString& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
unsigned int createLaserPointer(const glm::vec3& position, const glm::vec3& direction, const uint16_t filter, const float maxDistance,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
unsigned int createLaserPointer(const uint16_t filter, const float maxDistance, const QHash<QString, RenderState>& renderStates, const bool faceAvatar,
const bool centerEndY, const bool lockEnd, const bool enabled);
unsigned int createLaserPointer(const QVariantMap& rayProps, const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY,
const bool lockEnd, const bool enabled);
void removeLaserPointer(const unsigned int uid);
void enableLaserPointer(const unsigned int uid);
void disableLaserPointer(const unsigned int uid);
@ -49,8 +45,13 @@ public:
private:
QHash<unsigned int, std::shared_ptr<LaserPointer>> _laserPointers;
QReadWriteLock _lock;
QHash<unsigned int, std::shared_ptr<QReadWriteLock>> _laserPointerLocks;
unsigned int _nextUID{ 1 }; // 0 is invalid
QReadWriteLock _addLock;
QQueue<QPair<unsigned int, std::shared_ptr<LaserPointer>>> _laserPointersToAdd;
QReadWriteLock _removeLock;
QQueue<unsigned int> _laserPointersToRemove;
QReadWriteLock _containsLock;
};

View file

@ -20,16 +20,6 @@
uint32_t LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) {
QVariantMap propertyMap = properties.toMap();
uint16_t filter = 0;
if (propertyMap["filter"].isValid()) {
filter = propertyMap["filter"].toUInt();
}
float maxDistance = 0.0f;
if (propertyMap["maxDistance"].isValid()) {
maxDistance = propertyMap["maxDistance"].toFloat();
}
bool faceAvatar = false;
if (propertyMap["faceAvatar"].isValid()) {
faceAvatar = propertyMap["faceAvatar"].toBool();
@ -64,37 +54,7 @@ uint32_t LaserPointerScriptingInterface::createLaserPointer(const QVariant& prop
}
}
if (propertyMap["joint"].isValid()) {
QString jointName = propertyMap["joint"].toString();
if (jointName != "Mouse") {
// x = upward, y = forward, z = lateral
glm::vec3 posOffset = Vectors::ZERO;
if (propertyMap["posOffset"].isValid()) {
posOffset = vec3FromVariant(propertyMap["posOffset"]);
}
glm::vec3 dirOffset = Vectors::UP;
if (propertyMap["dirOffset"].isValid()) {
dirOffset = vec3FromVariant(propertyMap["dirOffset"]);
}
return DependencyManager::get<LaserPointerManager>()->createLaserPointer(jointName, posOffset, dirOffset, filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
} else {
return DependencyManager::get<LaserPointerManager>()->createLaserPointer(filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
}
} else if (propertyMap["position"].isValid()) {
glm::vec3 position = vec3FromVariant(propertyMap["position"]);
glm::vec3 direction = -Vectors::UP;
if (propertyMap["direction"].isValid()) {
direction = vec3FromVariant(propertyMap["direction"]);
}
return DependencyManager::get<LaserPointerManager>()->createLaserPointer(position, direction, filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
}
return 0;
return DependencyManager::get<LaserPointerManager>()->createLaserPointer(propertyMap, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
}
void LaserPointerScriptingInterface::editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) {

View file

@ -19,6 +19,10 @@
#include "scripting/HMDScriptingInterface.h"
#include "DependencyManager.h"
#include "JointRayPick.h"
#include "StaticRayPick.h"
#include "MouseRayPick.h"
bool RayPickManager::checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, unsigned int mask) {
if (cache.contains(ray) && cache[ray].contains(mask)) {
if (cache[ray][mask].distance < res.distance) {
@ -137,10 +141,59 @@ void RayPickManager::update() {
}
}
unsigned int RayPickManager::addRayPick(std::shared_ptr<RayPick> rayPick) {
QWriteLocker lock(&_addLock);
_rayPicksToAdd.enqueue(QPair<unsigned int, std::shared_ptr<RayPick>>(_nextUID, rayPick));
return _nextUID++;
unsigned int RayPickManager::createRayPick(const QVariantMap& rayProps) {
bool enabled = false;
if (rayProps["enabled"].isValid()) {
enabled = rayProps["enabled"].toBool();
}
uint16_t filter = 0;
if (rayProps["filter"].isValid()) {
filter = rayProps["filter"].toUInt();
}
float maxDistance = 0.0f;
if (rayProps["maxDistance"].isValid()) {
maxDistance = rayProps["maxDistance"].toFloat();
}
if (rayProps["joint"].isValid()) {
QString jointName = rayProps["joint"].toString();
if (jointName != "Mouse") {
// x = upward, y = forward, z = lateral
glm::vec3 posOffset = Vectors::ZERO;
if (rayProps["posOffset"].isValid()) {
posOffset = vec3FromVariant(rayProps["posOffset"]);
}
glm::vec3 dirOffset = Vectors::UP;
if (rayProps["dirOffset"].isValid()) {
dirOffset = vec3FromVariant(rayProps["dirOffset"]);
}
QWriteLocker lock(&_addLock);
_rayPicksToAdd.enqueue(QPair<unsigned int, std::shared_ptr<RayPick>>(_nextUID, std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled)));
return _nextUID++;
} else {
QWriteLocker lock(&_addLock);
_rayPicksToAdd.enqueue(QPair<unsigned int, std::shared_ptr<RayPick>>(_nextUID, std::make_shared<MouseRayPick>(filter, maxDistance, enabled)));
return _nextUID++;
}
} else if (rayProps["position"].isValid()) {
glm::vec3 position = vec3FromVariant(rayProps["position"]);
glm::vec3 direction = -Vectors::UP;
if (rayProps["direction"].isValid()) {
direction = vec3FromVariant(rayProps["direction"]);
}
QWriteLocker lock(&_addLock);
_rayPicksToAdd.enqueue(QPair<unsigned int, std::shared_ptr<RayPick>>(_nextUID, std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled)));
return _nextUID++;
}
return 0;
}
void RayPickManager::removeRayPick(const unsigned int uid) {

View file

@ -58,19 +58,21 @@ class RayPickManager : public QObject, public Dependency {
public:
void update();
unsigned int addRayPick(std::shared_ptr<RayPick> rayPick);
void removeRayPick(const unsigned int uid);
void enableRayPick(const unsigned int uid);
void disableRayPick(const unsigned int uid);
const PickRay getPickRay(const unsigned int uid);
const RayPickResult getPrevRayPickResult(const unsigned int uid);
void setIgnoreEntities(unsigned int uid, const QScriptValue& ignoreEntities);
void setIncludeEntities(unsigned int uid, const QScriptValue& includeEntities);
void setIgnoreOverlays(unsigned int uid, const QScriptValue& ignoreOverlays);
void setIncludeOverlays(unsigned int uid, const QScriptValue& includeOverlays);
void setIgnoreAvatars(unsigned int uid, const QScriptValue& ignoreAvatars);
void setIncludeAvatars(unsigned int uid, const QScriptValue& includeAvatars);
public slots:
Q_INVOKABLE unsigned int createRayPick(const QVariantMap& rayProps);
Q_INVOKABLE void removeRayPick(const unsigned int uid);
Q_INVOKABLE void enableRayPick(const unsigned int uid);
Q_INVOKABLE void disableRayPick(const unsigned int uid);
Q_INVOKABLE const RayPickResult getPrevRayPickResult(const unsigned int uid);
Q_INVOKABLE void setIgnoreEntities(unsigned int uid, const QScriptValue& ignoreEntities);
Q_INVOKABLE void setIncludeEntities(unsigned int uid, const QScriptValue& includeEntities);
Q_INVOKABLE void setIgnoreOverlays(unsigned int uid, const QScriptValue& ignoreOverlays);
Q_INVOKABLE void setIncludeOverlays(unsigned int uid, const QScriptValue& includeOverlays);
Q_INVOKABLE void setIgnoreAvatars(unsigned int uid, const QScriptValue& ignoreAvatars);
Q_INVOKABLE void setIncludeAvatars(unsigned int uid, const QScriptValue& includeAvatars);
private:
QHash<unsigned int, std::shared_ptr<RayPick>> _rayPicks;

View file

@ -257,12 +257,12 @@ function Grabber() {
this.liftKey = false; // SHIFT
this.rotateKey = false; // CONTROL
this.mouseRayOverlays = LaserPointers.createLaserPointer({
this.mouseRayOverlays = RayPick.createRayPick({
joint: "Mouse",
filter: RayPick.PICK_OVERLAYS,
enabled: true
});
LaserPointers.setIncludeOverlays(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]);
RayPick.setIncludeOverlays(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]);
this.mouseRayEntities = LaserPointers.createLaserPointer({
joint: "Mouse",
filter: RayPick.PICK_ENTITIES,
@ -318,7 +318,7 @@ Grabber.prototype.pressEvent = function(event) {
return;
}
var overlayResult = LaserPointers.getPrevRayPickResult(this.mouseRayOverlays);
var overlayResult = RayPick.getPrevRayPickResult(this.mouseRayOverlays);
if (overlayResult.type != RayPick.INTERSECTED_NONE) {
return;
}
@ -572,7 +572,7 @@ Grabber.prototype.keyPressEvent = function(event) {
Grabber.prototype.cleanup = function() {
LaserPointers.removeLaserPointer(this.mouseRayEntities);
LaserPointers.removeLaserPointer(this.mouseRayOverlays);
RayPick.removeRayPick(this.mouseRayOverlays);
};
var grabber = new Grabber();