Merge pull request #11612 from highfidelity/pointers

Fix tablet intersection bug and start of Pointer migration work (WIP)
This commit is contained in:
Brad Hefta-Gaub 2017-10-20 13:53:52 -07:00 committed by GitHub
commit 26ea8bea6a
27 changed files with 545 additions and 533 deletions

View file

@ -210,6 +210,7 @@ endif()
# link required hifi libraries
link_hifi_libraries(
shared octree ktx gpu gl gpu-gl procedural model render
pointers
recording fbx networking model-networking entities avatars trackers
audio audio-client animation script-engine physics
render-utils entities-renderer avatars-renderer ui auto-updater midi

View file

@ -10,7 +10,6 @@
//
#include "JointRayPick.h"
#include "DependencyManager.h"
#include "avatar/AvatarManager.h"
JointRayPick::JointRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled) :

View file

@ -11,7 +11,7 @@
#ifndef hifi_JointRayPick_h
#define hifi_JointRayPick_h
#include "RayPick.h"
#include <pointers/rays/RayPick.h>
class JointRayPick : public RayPick {

View file

@ -11,8 +11,8 @@
#include "LaserPointer.h"
#include "Application.h"
#include "ui/overlays/Overlay.h"
#include "avatar/AvatarManager.h"
#include "RayPickScriptingInterface.h"
LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates,
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled) :
@ -22,9 +22,10 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende
_faceAvatar(faceAvatar),
_centerEndY(centerEndY),
_lockEnd(lockEnd),
_distanceScaleEnd(distanceScaleEnd)
_distanceScaleEnd(distanceScaleEnd),
_rayPickUID(DependencyManager::get<RayPickScriptingInterface>()->createRayPick(rayProps))
{
_rayPickUID = DependencyManager::get<RayPickScriptingInterface>()->createRayPick(rayProps);
for (auto& state : _renderStates) {
if (!enabled || state.first != _currentRenderState) {
@ -39,7 +40,7 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende
}
LaserPointer::~LaserPointer() {
DependencyManager::get<RayPickScriptingInterface>()->removeRayPick(_rayPickUID);
qApp->getRayPickManager().removeRayPick(_rayPickUID);
for (auto& renderState : _renderStates) {
renderState.second.deleteOverlays();
@ -50,47 +51,51 @@ LaserPointer::~LaserPointer() {
}
void LaserPointer::enable() {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->enableRayPick(_rayPickUID);
_renderingEnabled = true;
qApp->getRayPickManager().enableRayPick(_rayPickUID);
withWriteLock([&] {
_renderingEnabled = true;
});
}
void LaserPointer::disable() {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->disableRayPick(_rayPickUID);
_renderingEnabled = false;
if (!_currentRenderState.empty()) {
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
disableRenderState(_renderStates[_currentRenderState]);
qApp->getRayPickManager().disableRayPick(_rayPickUID);
withWriteLock([&] {
_renderingEnabled = false;
if (!_currentRenderState.empty()) {
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
disableRenderState(_renderStates[_currentRenderState]);
}
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
disableRenderState(_defaultRenderStates[_currentRenderState].second);
}
}
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
disableRenderState(_defaultRenderStates[_currentRenderState].second);
}
}
});
}
void LaserPointer::setRenderState(const std::string& state) {
QWriteLocker lock(getLock());
if (!_currentRenderState.empty() && state != _currentRenderState) {
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
disableRenderState(_renderStates[_currentRenderState]);
withWriteLock([&] {
if (!_currentRenderState.empty() && state != _currentRenderState) {
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
disableRenderState(_renderStates[_currentRenderState]);
}
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
disableRenderState(_defaultRenderStates[_currentRenderState].second);
}
}
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
disableRenderState(_defaultRenderStates[_currentRenderState].second);
}
}
_currentRenderState = state;
_currentRenderState = state;
});
}
void LaserPointer::editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
QWriteLocker lock(getLock());
updateRenderStateOverlay(_renderStates[state].getStartID(), startProps);
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
QVariant endDim = endProps.toMap()["dimensions"];
if (endDim.isValid()) {
_renderStates[state].setEndDim(vec3FromVariant(endDim));
}
withWriteLock([&] {
updateRenderStateOverlay(_renderStates[state].getStartID(), startProps);
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
QVariant endDim = endProps.toMap()["dimensions"];
if (endDim.isValid()) {
_renderStates[state].setEndDim(vec3FromVariant(endDim));
}
});
}
void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& props) {
@ -102,8 +107,7 @@ void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant&
}
const RayPickResult LaserPointer::getPrevRayPickResult() {
QReadLocker lock(getLock());
return DependencyManager::get<RayPickScriptingInterface>()->getPrevRayPickResult(_rayPickUID);
return qApp->getRayPickManager().getPrevRayPickResult(_rayPickUID);
}
void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState) {
@ -202,65 +206,45 @@ void LaserPointer::disableRenderState(const RenderState& renderState) {
void LaserPointer::update() {
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
QReadLocker lock(getLock());
RayPickResult prevRayPickResult = DependencyManager::get<RayPickScriptingInterface>()->getPrevRayPickResult(_rayPickUID);
if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() &&
withReadLock([&] {
RayPickResult prevRayPickResult = qApp->getRayPickManager().getPrevRayPickResult(_rayPickUID);
if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() &&
(prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) {
float distance = _laserLength > 0.0f ? _laserLength : prevRayPickResult.distance;
updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, distance, prevRayPickResult.objectID, prevRayPickResult.searchRay, false);
disableRenderState(_defaultRenderStates[_currentRenderState].second);
} else if (_renderingEnabled && !_currentRenderState.empty() && _defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
disableRenderState(_renderStates[_currentRenderState]);
updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), prevRayPickResult.searchRay, true);
} else if (!_currentRenderState.empty()) {
disableRenderState(_renderStates[_currentRenderState]);
disableRenderState(_defaultRenderStates[_currentRenderState].second);
}
float distance = _laserLength > 0.0f ? _laserLength : prevRayPickResult.distance;
updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, distance, prevRayPickResult.objectID, prevRayPickResult.searchRay, false);
disableRenderState(_defaultRenderStates[_currentRenderState].second);
} else if (_renderingEnabled && !_currentRenderState.empty() && _defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
disableRenderState(_renderStates[_currentRenderState]);
updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), prevRayPickResult.searchRay, true);
} else if (!_currentRenderState.empty()) {
disableRenderState(_renderStates[_currentRenderState]);
disableRenderState(_defaultRenderStates[_currentRenderState].second);
}
});
}
void LaserPointer::setPrecisionPicking(const bool precisionPicking) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setPrecisionPicking(_rayPickUID, precisionPicking);
qApp->getRayPickManager().setPrecisionPicking(_rayPickUID, precisionPicking);
}
void LaserPointer::setLaserLength(const float laserLength) {
QWriteLocker lock(getLock());
_laserLength = laserLength;
withWriteLock([&] {
_laserLength = laserLength;
});
}
void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay) {
QWriteLocker lock(getLock());
_objectLockEnd = std::pair<QUuid, bool>(objectID, isOverlay);
withWriteLock([&] {
_objectLockEnd = std::pair<QUuid, bool>(objectID, isOverlay);
});
}
void LaserPointer::setIgnoreEntities(const QScriptValue& ignoreEntities) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreEntities(_rayPickUID, ignoreEntities);
void LaserPointer::setIgnoreItems(const QVector<QUuid>& ignoreItems) const {
qApp->getRayPickManager().setIgnoreItems(_rayPickUID, ignoreItems);
}
void LaserPointer::setIncludeEntities(const QScriptValue& includeEntities) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIncludeEntities(_rayPickUID, includeEntities);
}
void LaserPointer::setIgnoreOverlays(const QScriptValue& ignoreOverlays) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreOverlays(_rayPickUID, ignoreOverlays);
}
void LaserPointer::setIncludeOverlays(const QScriptValue& includeOverlays) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIncludeOverlays(_rayPickUID, includeOverlays);
}
void LaserPointer::setIgnoreAvatars(const QScriptValue& ignoreAvatars) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreAvatars(_rayPickUID, ignoreAvatars);
}
void LaserPointer::setIncludeAvatars(const QScriptValue& includeAvatars) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIncludeAvatars(_rayPickUID, includeAvatars);
void LaserPointer::setIncludeItems(const QVector<QUuid>& includeItems) const {
qApp->getRayPickManager().setIncludeItems(_rayPickUID, includeItems);
}
RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) :
@ -288,4 +272,4 @@ void RenderState::deleteOverlays() {
if (!_endID.isNull()) {
qApp->getOverlays().deleteOverlay(_endID);
}
}
}

View file

@ -12,10 +12,12 @@
#define hifi_LaserPointer_h
#include <QString>
#include "glm/glm.hpp"
#include <glm/glm.hpp>
#include <DependencyManager.h>
#include "raypick/RayPickScriptingInterface.h"
#include <shared/ReadWriteLockable.h>
#include "ui/overlays/Overlay.h"
class RayPickResult;
@ -49,9 +51,10 @@ private:
};
class LaserPointer {
class LaserPointer : public ReadWriteLockable {
public:
using Pointer = std::shared_ptr<LaserPointer>;
typedef std::unordered_map<std::string, RenderState> RenderStateMap;
typedef std::unordered_map<std::string, std::pair<float, RenderState>> DefaultRenderStateMap;
@ -73,14 +76,8 @@ public:
void setLaserLength(const float laserLength);
void setLockEndUUID(QUuid objectID, const bool isOverlay);
void setIgnoreEntities(const QScriptValue& ignoreEntities);
void setIncludeEntities(const QScriptValue& includeEntities);
void setIgnoreOverlays(const QScriptValue& ignoreOverlays);
void setIncludeOverlays(const QScriptValue& includeOverlays);
void setIgnoreAvatars(const QScriptValue& ignoreAvatars);
void setIncludeAvatars(const QScriptValue& includeAvatars);
QReadWriteLock* getLock() { return &_lock; }
void setIgnoreItems(const QVector<QUuid>& ignoreItems) const;
void setIncludeItems(const QVector<QUuid>& includeItems) const;
void update();
@ -96,8 +93,7 @@ private:
bool _distanceScaleEnd;
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
QUuid _rayPickUID;
QReadWriteLock _lock;
const QUuid _rayPickUID;
void updateRenderStateOverlay(const OverlayID& id, const QVariant& props);
void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState);

View file

@ -12,138 +12,110 @@
QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled) {
QUuid result;
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled);
if (!laserPointer->getRayUID().isNull()) {
QWriteLocker containsLock(&_containsLock);
QUuid id = QUuid::createUuid();
_laserPointers[id] = laserPointer;
return id;
result = QUuid::createUuid();
withWriteLock([&] { _laserPointers[result] = laserPointer; });
}
return QUuid();
return result;
}
void LaserPointerManager::removeLaserPointer(const QUuid uid) {
QWriteLocker lock(&_containsLock);
_laserPointers.remove(uid);
LaserPointer::Pointer LaserPointerManager::find(const QUuid& uid) const {
return resultWithReadLock<LaserPointer::Pointer>([&] {
auto itr = _laserPointers.find(uid);
if (itr != _laserPointers.end()) {
return *itr;
}
return LaserPointer::Pointer();
});
}
void LaserPointerManager::enableLaserPointer(const QUuid uid) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->enable();
void LaserPointerManager::removeLaserPointer(const QUuid& uid) {
withWriteLock([&] {
_laserPointers.remove(uid);
});
}
void LaserPointerManager::enableLaserPointer(const QUuid& uid) const {
auto laserPointer = find(uid);
if (laserPointer) {
laserPointer->enable();
}
}
void LaserPointerManager::disableLaserPointer(const QUuid uid) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->disable();
void LaserPointerManager::disableLaserPointer(const QUuid& uid) const {
auto laserPointer = find(uid);
if (laserPointer) {
laserPointer->disable();
}
}
void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderState) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->setRenderState(renderState);
void LaserPointerManager::setRenderState(const QUuid& uid, const std::string& renderState) const {
auto laserPointer = find(uid);
if (laserPointer) {
laserPointer->setRenderState(renderState);
}
}
void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->editRenderState(state, startProps, pathProps, endProps);
void LaserPointerManager::editRenderState(const QUuid& uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) const {
auto laserPointer = find(uid);
if (laserPointer) {
laserPointer->editRenderState(state, startProps, pathProps, endProps);
}
}
const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
return laserPointer.value()->getPrevRayPickResult();
const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid& uid) const {
auto laserPointer = find(uid);
if (laserPointer) {
return laserPointer->getPrevRayPickResult();
}
return RayPickResult();
}
void LaserPointerManager::update() {
QReadLocker lock(&_containsLock);
for (QUuid& uid : _laserPointers.keys()) {
auto laserPointer = _laserPointers.find(uid);
laserPointer.value()->update();
auto cachedLaserPointers = resultWithReadLock<QList<std::shared_ptr<LaserPointer>>>([&] {
return _laserPointers.values();
});
for (const auto& laserPointer : cachedLaserPointers) {
laserPointer->update();
}
}
void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->setPrecisionPicking(precisionPicking);
void LaserPointerManager::setPrecisionPicking(const QUuid& uid, const bool precisionPicking) const {
auto laserPointer = find(uid);
if (laserPointer) {
laserPointer->setPrecisionPicking(precisionPicking);
}
}
void LaserPointerManager::setLaserLength(QUuid uid, const float laserLength) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->setLaserLength(laserLength);
void LaserPointerManager::setLaserLength(const QUuid& uid, const float laserLength) const {
auto laserPointer = find(uid);
if (laserPointer) {
laserPointer->setLaserLength(laserLength);
}
}
void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->setIgnoreEntities(ignoreEntities);
void LaserPointerManager::setIgnoreItems(const QUuid& uid, const QVector<QUuid>& ignoreEntities) const {
auto laserPointer = find(uid);
if (laserPointer) {
laserPointer->setIgnoreItems(ignoreEntities);
}
}
void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->setIncludeEntities(includeEntities);
void LaserPointerManager::setIncludeItems(const QUuid& uid, const QVector<QUuid>& includeEntities) const {
auto laserPointer = find(uid);
if (laserPointer) {
laserPointer->setIncludeItems(includeEntities);
}
}
void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->setIgnoreOverlays(ignoreOverlays);
}
}
void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->setIncludeOverlays(includeOverlays);
}
}
void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->setIgnoreAvatars(ignoreAvatars);
}
}
void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->setIncludeAvatars(includeAvatars);
}
}
void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) {
QReadLocker lock(&_containsLock);
auto laserPointer = _laserPointers.find(uid);
if (laserPointer != _laserPointers.end()) {
laserPointer.value()->setLockEndUUID(objectID, isOverlay);
void LaserPointerManager::setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const {
auto laserPointer = find(uid);
if (laserPointer) {
laserPointer->setLockEndUUID(objectID, isOverlay);
}
}

View file

@ -14,39 +14,38 @@
#include <memory>
#include <glm/glm.hpp>
#include <shared/ReadWriteLockable.h>
#include "LaserPointer.h"
class RayPickResult;
class LaserPointerManager {
class LaserPointerManager : protected ReadWriteLockable {
public:
QUuid createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled);
void removeLaserPointer(const QUuid uid);
void enableLaserPointer(const QUuid uid);
void disableLaserPointer(const QUuid uid);
void setRenderState(QUuid uid, const std::string& renderState);
void editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
const RayPickResult getPrevRayPickResult(const QUuid uid);
void setPrecisionPicking(QUuid uid, const bool precisionPicking);
void setLaserLength(QUuid uid, const float laserLength);
void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities);
void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities);
void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays);
void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays);
void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars);
void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars);
void removeLaserPointer(const QUuid& uid);
void enableLaserPointer(const QUuid& uid) const;
void disableLaserPointer(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 RayPickResult getPrevRayPickResult(const QUuid& uid) const;
void setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay);
void setPrecisionPicking(const QUuid& uid, const bool precisionPicking) const;
void setLaserLength(const QUuid& uid, const float laserLength) const;
void setIgnoreItems(const QUuid& uid, const QVector<QUuid>& ignoreEntities) const;
void setIncludeItems(const QUuid& uid, const QVector<QUuid>& includeEntities) const;
void setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const;
void update();
private:
LaserPointer::Pointer find(const QUuid& uid) const;
QHash<QUuid, std::shared_ptr<LaserPointer>> _laserPointers;
QReadWriteLock _containsLock;
};
#endif // hifi_LaserPointerManager_h

View file

@ -11,10 +11,19 @@
#include "LaserPointerScriptingInterface.h"
#include <QVariant>
#include "GLMHelpers.h"
#include <QtCore/QVariant>
QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) {
#include <GLMHelpers.h>
#include <RegisteredMetaTypes.h>
void LaserPointerScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) const {
qApp->getLaserPointerManager().setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems));
}
void LaserPointerScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) const {
qApp->getLaserPointerManager().setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems));
}
QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) const {
QVariantMap propertyMap = properties.toMap();
bool faceAvatar = false;
@ -74,7 +83,7 @@ QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& propert
return qApp->getLaserPointerManager().createLaserPointer(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled);
}
void LaserPointerScriptingInterface::editRenderState(QUuid uid, const QString& renderState, const QVariant& properties) {
void LaserPointerScriptingInterface::editRenderState(const QUuid& uid, const QString& renderState, const QVariant& properties) const {
QVariantMap propMap = properties.toMap();
QVariant startProps;
@ -95,7 +104,7 @@ void LaserPointerScriptingInterface::editRenderState(QUuid uid, const QString& r
qApp->getLaserPointerManager().editRenderState(uid, renderState.toStdString(), startProps, pathProps, endProps);
}
const RenderState LaserPointerScriptingInterface::buildRenderState(const QVariantMap& propMap) {
RenderState LaserPointerScriptingInterface::buildRenderState(const QVariantMap& propMap) {
QUuid startID;
if (propMap["start"].isValid()) {
QVariantMap startMap = propMap["start"].toMap();

View file

@ -22,27 +22,23 @@ class LaserPointerScriptingInterface : public QObject, public Dependency {
SINGLETON_DEPENDENCY
public slots:
Q_INVOKABLE QUuid createLaserPointer(const QVariant& properties);
Q_INVOKABLE void enableLaserPointer(QUuid uid) { qApp->getLaserPointerManager().enableLaserPointer(uid); }
Q_INVOKABLE void disableLaserPointer(QUuid uid) { qApp->getLaserPointerManager().disableLaserPointer(uid); }
Q_INVOKABLE void removeLaserPointer(QUuid uid) { qApp->getLaserPointerManager().removeLaserPointer(uid); }
Q_INVOKABLE void editRenderState(QUuid uid, const QString& renderState, const QVariant& properties);
Q_INVOKABLE void setRenderState(QUuid uid, const QString& renderState) { qApp->getLaserPointerManager().setRenderState(uid, renderState.toStdString()); }
Q_INVOKABLE RayPickResult getPrevRayPickResult(QUuid uid) { return qApp->getLaserPointerManager().getPrevRayPickResult(uid); }
Q_INVOKABLE QUuid createLaserPointer(const QVariant& properties) const;
Q_INVOKABLE void enableLaserPointer(const QUuid& uid) const { qApp->getLaserPointerManager().enableLaserPointer(uid); }
Q_INVOKABLE void disableLaserPointer(const QUuid& uid) const { qApp->getLaserPointerManager().disableLaserPointer(uid); }
Q_INVOKABLE void removeLaserPointer(const QUuid& uid) const { qApp->getLaserPointerManager().removeLaserPointer(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 { qApp->getLaserPointerManager().setRenderState(uid, renderState.toStdString()); }
Q_INVOKABLE RayPickResult getPrevRayPickResult(QUuid uid) const { return qApp->getLaserPointerManager().getPrevRayPickResult(uid); }
Q_INVOKABLE void setPrecisionPicking(QUuid uid, const bool precisionPicking) { qApp->getLaserPointerManager().setPrecisionPicking(uid, precisionPicking); }
Q_INVOKABLE void setLaserLength(QUuid uid, const float laserLength) { qApp->getLaserPointerManager().setLaserLength(uid, laserLength); }
Q_INVOKABLE void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { qApp->getLaserPointerManager().setIgnoreEntities(uid, ignoreEntities); }
Q_INVOKABLE void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { qApp->getLaserPointerManager().setIncludeEntities(uid, includeEntities); }
Q_INVOKABLE void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { qApp->getLaserPointerManager().setIgnoreOverlays(uid, ignoreOverlays); }
Q_INVOKABLE void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { qApp->getLaserPointerManager().setIncludeOverlays(uid, includeOverlays); }
Q_INVOKABLE void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { qApp->getLaserPointerManager().setIgnoreAvatars(uid, ignoreAvatars); }
Q_INVOKABLE void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { qApp->getLaserPointerManager().setIncludeAvatars(uid, includeAvatars); }
Q_INVOKABLE void setPrecisionPicking(const QUuid& uid, bool precisionPicking) const { qApp->getLaserPointerManager().setPrecisionPicking(uid, precisionPicking); }
Q_INVOKABLE void setLaserLength(const QUuid& uid, float laserLength) const { qApp->getLaserPointerManager().setLaserLength(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(QUuid uid, QUuid objectID, const bool isOverlay) { qApp->getLaserPointerManager().setLockEndUUID(uid, objectID, isOverlay); }
Q_INVOKABLE void setLockEndUUID(const QUuid& uid, const QUuid& objectID, bool isOverlay) const { qApp->getLaserPointerManager().setLockEndUUID(uid, objectID, isOverlay); }
private:
const RenderState buildRenderState(const QVariantMap& propMap);
static RenderState buildRenderState(const QVariantMap& propMap);
};

View file

@ -11,7 +11,7 @@
#ifndef hifi_MouseRayPick_h
#define hifi_MouseRayPick_h
#include "RayPick.h"
#include <pointers/rays/RayPick.h>
class MouseRayPick : public RayPick {

View file

@ -1,62 +0,0 @@
//
// RayPick.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 "RayPick.h"
RayPick::RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) :
_filter(filter),
_maxDistance(maxDistance),
_enabled(enabled)
{
}
void RayPick::enable() {
QWriteLocker lock(getLock());
_enabled = true;
}
void RayPick::disable() {
QWriteLocker lock(getLock());
_enabled = false;
}
const RayPickResult& RayPick::getPrevRayPickResult() {
QReadLocker lock(getLock());
return _prevResult;
}
void RayPick::setIgnoreEntities(const QScriptValue& ignoreEntities) {
QWriteLocker lock(getLock());
_ignoreEntities = qVectorEntityItemIDFromScriptValue(ignoreEntities);
}
void RayPick::setIncludeEntities(const QScriptValue& includeEntities) {
QWriteLocker lock(getLock());
_includeEntities = qVectorEntityItemIDFromScriptValue(includeEntities);
}
void RayPick::setIgnoreOverlays(const QScriptValue& ignoreOverlays) {
QWriteLocker lock(getLock());
_ignoreOverlays = qVectorOverlayIDFromScriptValue(ignoreOverlays);
}
void RayPick::setIncludeOverlays(const QScriptValue& includeOverlays) {
QWriteLocker lock(getLock());
_includeOverlays = qVectorOverlayIDFromScriptValue(includeOverlays);
}
void RayPick::setIgnoreAvatars(const QScriptValue& ignoreAvatars) {
QWriteLocker lock(getLock());
_ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars);
}
void RayPick::setIncludeAvatars(const QScriptValue& includeAvatars) {
QWriteLocker lock(getLock());
_includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars);
}

View file

@ -10,6 +10,8 @@
//
#include "RayPickManager.h"
#include <pointers/rays/StaticRayPick.h>
#include "Application.h"
#include "EntityScriptingInterface.h"
#include "ui/overlays/Overlays.h"
@ -18,45 +20,50 @@
#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, const RayPickFilter::Flags& mask) {
if (cache.contains(ray) && cache[ray].find(mask) != cache[ray].end()) {
if (cache[ray][mask].distance < res.distance) {
res = cache[ray][mask];
bool RayPickManager::checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, const RayCacheKey& key) {
if (cache.contains(ray) && cache[ray].find(key) != cache[ray].end()) {
if (cache[ray][key].distance < res.distance) {
res = cache[ray][key];
}
return true;
}
return false;
}
void RayPickManager::cacheResult(const bool intersects, const RayPickResult& resTemp, const RayPickFilter::Flags& mask, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache) {
void RayPickManager::cacheResult(const bool intersects, const RayPickResult& resTemp, const RayCacheKey& key, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache) {
if (intersects) {
cache[ray][mask] = resTemp;
cache[ray][key] = resTemp;
if (resTemp.distance < res.distance) {
res = resTemp;
}
} else {
cache[ray][mask] = RayPickResult(res.searchRay);
cache[ray][key] = RayPickResult(res.searchRay);
}
}
void RayPickManager::update() {
QReadLocker lock(&_containsLock);
RayPickCache results;
for (auto& uid : _rayPicks.keys()) {
std::shared_ptr<RayPick> rayPick = _rayPicks[uid];
QWriteLocker lock(rayPick->getLock());
QHash<QUuid, RayPick::Pointer> cachedRayPicks;
withReadLock([&] {
cachedRayPicks = _rayPicks;
});
for (const auto& uid : cachedRayPicks.keys()) {
std::shared_ptr<RayPick> rayPick = cachedRayPicks[uid];
if (!rayPick->isEnabled() || rayPick->getFilter().doesPickNothing() || rayPick->getMaxDistance() < 0.0f) {
continue;
}
bool valid;
PickRay ray = rayPick->getPickRay(valid);
PickRay ray;
if (!valid) {
continue;
{
bool valid;
ray = rayPick->getPickRay(valid);
if (!valid) {
continue;
}
}
QPair<glm::vec3, glm::vec3> rayKey = QPair<glm::vec3, glm::vec3>(ray.origin, ray.direction);
@ -67,16 +74,16 @@ void RayPickManager::update() {
bool fromCache = true;
bool invisible = rayPick->getFilter().doesPickInvisible();
bool nonCollidable = rayPick->getFilter().doesPickNonCollidable();
RayPickFilter::Flags entityMask = rayPick->getFilter().getEntityFlags();
if (!checkAndCompareCachedResults(rayKey, results, res, entityMask)) {
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCourse(),
rayPick->getIncludeEntites(), rayPick->getIgnoreEntites(), !invisible, !nonCollidable);
RayCacheKey entityKey = { rayPick->getFilter().getEntityFlags(), rayPick->getIncludeItems(), rayPick->getIgnoreItems() };
if (!checkAndCompareCachedResults(rayKey, results, res, entityKey)) {
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCoarse(),
rayPick->getIncludeItemsAs<EntityItemID>(), rayPick->getIgnoreItemsAs<EntityItemID>(), !invisible, !nonCollidable);
fromCache = false;
}
if (!fromCache) {
cacheResult(entityRes.intersects, RayPickResult(IntersectionType::ENTITY, entityRes.entityID, entityRes.distance, entityRes.intersection, ray, entityRes.surfaceNormal),
entityMask, res, rayKey, results);
entityKey, res, rayKey, results);
}
}
@ -85,33 +92,34 @@ void RayPickManager::update() {
bool fromCache = true;
bool invisible = rayPick->getFilter().doesPickInvisible();
bool nonCollidable = rayPick->getFilter().doesPickNonCollidable();
RayPickFilter::Flags overlayMask = rayPick->getFilter().getOverlayFlags();
if (!checkAndCompareCachedResults(rayKey, results, res, overlayMask)) {
overlayRes = qApp->getOverlays().findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCourse(),
rayPick->getIncludeOverlays(), rayPick->getIgnoreOverlays(), !invisible, !nonCollidable);
RayCacheKey overlayKey = { rayPick->getFilter().getOverlayFlags(), rayPick->getIncludeItems(), rayPick->getIgnoreItems() };
if (!checkAndCompareCachedResults(rayKey, results, res, overlayKey)) {
overlayRes = qApp->getOverlays().findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCoarse(),
rayPick->getIncludeItemsAs<OverlayID>(), rayPick->getIgnoreItemsAs<OverlayID>(), !invisible, !nonCollidable);
fromCache = false;
}
if (!fromCache) {
cacheResult(overlayRes.intersects, RayPickResult(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, ray, overlayRes.surfaceNormal),
overlayMask, res, rayKey, results);
overlayKey, res, rayKey, results);
}
}
if (rayPick->getFilter().doesPickAvatars()) {
RayPickFilter::Flags avatarMask = rayPick->getFilter().getAvatarFlags();
if (!checkAndCompareCachedResults(rayKey, results, res, avatarMask)) {
RayToAvatarIntersectionResult avatarRes = DependencyManager::get<AvatarManager>()->findRayIntersectionVector(ray, rayPick->getIncludeAvatars(), rayPick->getIgnoreAvatars());
cacheResult(avatarRes.intersects, RayPickResult(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection, ray), avatarMask, res, rayKey, results);
RayCacheKey avatarKey = { rayPick->getFilter().getAvatarFlags(), rayPick->getIncludeItems(), rayPick->getIgnoreItems() };
if (!checkAndCompareCachedResults(rayKey, results, res, avatarKey)) {
RayToAvatarIntersectionResult avatarRes = DependencyManager::get<AvatarManager>()->findRayIntersectionVector(ray,
rayPick->getIncludeItemsAs<EntityItemID>(), rayPick->getIgnoreItemsAs<EntityItemID>());
cacheResult(avatarRes.intersects, RayPickResult(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection, ray), avatarKey, res, rayKey, results);
}
}
// Can't intersect with HUD in desktop mode
if (rayPick->getFilter().doesPickHUD() && DependencyManager::get<HMDScriptingInterface>()->isHMDMode()) {
RayPickFilter::Flags hudMask = rayPick->getFilter().getHUDFlags();
if (!checkAndCompareCachedResults(rayKey, results, res, hudMask)) {
RayCacheKey hudKey = { rayPick->getFilter().getHUDFlags(), QVector<QUuid>(), QVector<QUuid>() };
if (!checkAndCompareCachedResults(rayKey, results, res, hudKey)) {
glm::vec3 hudRes = DependencyManager::get<HMDScriptingInterface>()->calculateRayUICollisionPoint(ray.origin, ray.direction);
cacheResult(true, RayPickResult(IntersectionType::HUD, 0, glm::distance(ray.origin, hudRes), hudRes, ray), hudMask, res, rayKey, results);
cacheResult(true, RayPickResult(IntersectionType::HUD, 0, glm::distance(ray.origin, hudRes), hudRes, ray), hudKey, res, rayKey, results);
}
}
@ -123,109 +131,87 @@ void RayPickManager::update() {
}
}
QUuid RayPickManager::createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled) {
QWriteLocker lock(&_containsLock);
QUuid RayPickManager::createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, float maxDistance, bool enabled) {
auto newRayPick = std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled);
QUuid id = QUuid::createUuid();
_rayPicks[id] = std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled);
withWriteLock([&] {
_rayPicks[id] = newRayPick;
});
return id;
}
QUuid RayPickManager::createRayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) {
QWriteLocker lock(&_containsLock);
QUuid RayPickManager::createRayPick(const RayPickFilter& filter, float maxDistance, bool enabled) {
QUuid id = QUuid::createUuid();
_rayPicks[id] = std::make_shared<MouseRayPick>(filter, maxDistance, enabled);
auto newRayPick = std::make_shared<MouseRayPick>(filter, maxDistance, enabled);
withWriteLock([&] {
_rayPicks[id] = newRayPick;
});
return id;
}
QUuid RayPickManager::createRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance, const bool enabled) {
QWriteLocker lock(&_containsLock);
QUuid RayPickManager::createRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, float maxDistance, bool enabled) {
QUuid id = QUuid::createUuid();
_rayPicks[id] = std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled);
auto newRayPick = std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled);
withWriteLock([&] {
_rayPicks[id] = newRayPick;
});
return id;
}
void RayPickManager::removeRayPick(const QUuid uid) {
QWriteLocker lock(&_containsLock);
_rayPicks.remove(uid);
void RayPickManager::removeRayPick(const QUuid& uid) {
withWriteLock([&] {
_rayPicks.remove(uid);
});
}
void RayPickManager::enableRayPick(const QUuid uid) {
QReadLocker containsLock(&_containsLock);
auto rayPick = _rayPicks.find(uid);
if (rayPick != _rayPicks.end()) {
rayPick.value()->enable();
RayPick::Pointer RayPickManager::findRayPick(const QUuid& uid) const {
return resultWithReadLock<RayPick::Pointer>([&] {
if (_rayPicks.contains(uid)) {
return _rayPicks[uid];
}
return RayPick::Pointer();
});
}
void RayPickManager::enableRayPick(const QUuid& uid) const {
auto rayPick = findRayPick(uid);
if (rayPick) {
rayPick->enable();
}
}
void RayPickManager::disableRayPick(const QUuid uid) {
QReadLocker containsLock(&_containsLock);
auto rayPick = _rayPicks.find(uid);
if (rayPick != _rayPicks.end()) {
rayPick.value()->disable();
void RayPickManager::disableRayPick(const QUuid& uid) const {
auto rayPick = findRayPick(uid);
if (rayPick) {
rayPick->disable();
}
}
const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) {
QReadLocker containsLock(&_containsLock);
auto rayPick = _rayPicks.find(uid);
if (rayPick != _rayPicks.end()) {
return rayPick.value()->getPrevRayPickResult();
RayPickResult RayPickManager::getPrevRayPickResult(const QUuid& uid) const {
auto rayPick = findRayPick(uid);
if (rayPick) {
return rayPick->getPrevRayPickResult();
}
return RayPickResult();
}
void RayPickManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) {
QReadLocker containsLock(&_containsLock);
auto rayPick = _rayPicks.find(uid);
if (rayPick != _rayPicks.end()) {
rayPick.value()->setPrecisionPicking(precisionPicking);
void RayPickManager::setPrecisionPicking(const QUuid& uid, bool precisionPicking) const {
auto rayPick = findRayPick(uid);
if (rayPick) {
rayPick->setPrecisionPicking(precisionPicking);
}
}
void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
QReadLocker containsLock(&_containsLock);
auto rayPick = _rayPicks.find(uid);
if (rayPick != _rayPicks.end()) {
rayPick.value()->setIgnoreEntities(ignoreEntities);
void RayPickManager::setIgnoreItems(const QUuid& uid, const QVector<QUuid>& ignore) const {
auto rayPick = findRayPick(uid);
if (rayPick) {
rayPick->setIgnoreItems(ignore);
}
}
void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
QReadLocker containsLock(&_containsLock);
auto rayPick = _rayPicks.find(uid);
if (rayPick != _rayPicks.end()) {
rayPick.value()->setIncludeEntities(includeEntities);
void RayPickManager::setIncludeItems(const QUuid& uid, const QVector<QUuid>& include) const {
auto rayPick = findRayPick(uid);
if (rayPick) {
rayPick->setIncludeItems(include);
}
}
void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
QReadLocker containsLock(&_containsLock);
auto rayPick = _rayPicks.find(uid);
if (rayPick != _rayPicks.end()) {
rayPick.value()->setIgnoreOverlays(ignoreOverlays);
}
}
void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
QReadLocker containsLock(&_containsLock);
auto rayPick = _rayPicks.find(uid);
if (rayPick != _rayPicks.end()) {
rayPick.value()->setIncludeOverlays(includeOverlays);
}
}
void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
QReadLocker containsLock(&_containsLock);
auto rayPick = _rayPicks.find(uid);
if (rayPick != _rayPicks.end()) {
rayPick.value()->setIgnoreAvatars(ignoreAvatars);
}
}
void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
QReadLocker containsLock(&_containsLock);
auto rayPick = _rayPicks.find(uid);
if (rayPick != _rayPicks.end()) {
rayPick.value()->setIncludeAvatars(includeAvatars);
}
}

View file

@ -11,19 +11,39 @@
#ifndef hifi_RayPickManager_h
#define hifi_RayPickManager_h
#include "RayPick.h"
#include <memory>
#include <QtCore/QObject>
#include "RegisteredMetaTypes.h"
#include <unordered_map>
#include <queue>
#include <QtCore/QObject>
#include <RegisteredMetaTypes.h>
#include <pointers/rays/RayPick.h>
class RayPickResult;
class RayPickManager {
typedef struct RayCacheKey {
RayPickFilter::Flags mask;
QVector<QUuid> include;
QVector<QUuid> ignore;
bool operator==(const RayCacheKey& other) const {
return (mask == other.mask && include == other.include && ignore == other.ignore);
}
} RayCacheKey;
namespace std {
template <>
struct hash<RayCacheKey> {
size_t operator()(const RayCacheKey& k) const {
return ((hash<RayPickFilter::Flags>()(k.mask) ^ (qHash(k.include) << 1)) >> 1) ^ (qHash(k.ignore) << 1);
}
};
}
class RayPickManager : protected ReadWriteLockable {
public:
void update();
@ -31,28 +51,24 @@ public:
QUuid createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled);
QUuid createRayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled);
QUuid createRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance, const bool enabled);
void removeRayPick(const QUuid uid);
void enableRayPick(const QUuid uid);
void disableRayPick(const QUuid uid);
const RayPickResult getPrevRayPickResult(const QUuid uid);
void removeRayPick(const QUuid& uid);
void enableRayPick(const QUuid& uid) const;
void disableRayPick(const QUuid& uid) const;
RayPickResult getPrevRayPickResult(const QUuid& uid) const;
void setPrecisionPicking(QUuid uid, const bool precisionPicking);
void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities);
void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities);
void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays);
void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays);
void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars);
void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars);
void setPrecisionPicking(const QUuid& uid, bool precisionPicking) const;
void setIgnoreItems(const QUuid& uid, const QVector<QUuid>& ignore) const;
void setIncludeItems(const QUuid& uid, const QVector<QUuid>& include) const;
private:
QHash<QUuid, std::shared_ptr<RayPick>> _rayPicks;
QReadWriteLock _containsLock;
RayPick::Pointer findRayPick(const QUuid& uid) const;
QHash<QUuid, RayPick::Pointer> _rayPicks;
typedef QHash<QPair<glm::vec3, glm::vec3>, std::unordered_map<RayPickFilter::Flags, RayPickResult>> RayPickCache;
typedef QHash<QPair<glm::vec3, glm::vec3>, std::unordered_map<RayCacheKey, RayPickResult>> RayPickCache;
// Returns true if this ray exists in the cache, and if it does, update res if the cached result is closer
bool checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, const RayPickFilter::Flags& mask);
void cacheResult(const bool intersects, const RayPickResult& resTemp, const RayPickFilter::Flags& mask, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache);
bool checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, const RayCacheKey& key);
void cacheResult(const bool intersects, const RayPickResult& resTemp, const RayCacheKey& key, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache);
};
#endif // hifi_RayPickManager_h

View file

@ -66,46 +66,30 @@ QUuid RayPickScriptingInterface::createRayPick(const QVariant& properties) {
return QUuid();
}
void RayPickScriptingInterface::enableRayPick(QUuid uid) {
void RayPickScriptingInterface::enableRayPick(const QUuid& uid) {
qApp->getRayPickManager().enableRayPick(uid);
}
void RayPickScriptingInterface::disableRayPick(QUuid uid) {
void RayPickScriptingInterface::disableRayPick(const QUuid& uid) {
qApp->getRayPickManager().disableRayPick(uid);
}
void RayPickScriptingInterface::removeRayPick(QUuid uid) {
void RayPickScriptingInterface::removeRayPick(const QUuid& uid) {
qApp->getRayPickManager().removeRayPick(uid);
}
RayPickResult RayPickScriptingInterface::getPrevRayPickResult(QUuid uid) {
RayPickResult RayPickScriptingInterface::getPrevRayPickResult(const QUuid& uid) {
return qApp->getRayPickManager().getPrevRayPickResult(uid);
}
void RayPickScriptingInterface::setPrecisionPicking(QUuid uid, const bool precisionPicking) {
void RayPickScriptingInterface::setPrecisionPicking(const QUuid& uid, const bool precisionPicking) {
qApp->getRayPickManager().setPrecisionPicking(uid, precisionPicking);
}
void RayPickScriptingInterface::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
qApp->getRayPickManager().setIgnoreEntities(uid, ignoreEntities);
void RayPickScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) {
qApp->getRayPickManager().setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems));
}
void RayPickScriptingInterface::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
qApp->getRayPickManager().setIncludeEntities(uid, includeEntities);
}
void RayPickScriptingInterface::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
qApp->getRayPickManager().setIgnoreOverlays(uid, ignoreOverlays);
}
void RayPickScriptingInterface::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
qApp->getRayPickManager().setIncludeOverlays(uid, includeOverlays);
}
void RayPickScriptingInterface::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
qApp->getRayPickManager().setIgnoreAvatars(uid, ignoreAvatars);
}
void RayPickScriptingInterface::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
qApp->getRayPickManager().setIncludeAvatars(uid, includeAvatars);
void RayPickScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) {
qApp->getRayPickManager().setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems));
}

View file

@ -13,10 +13,9 @@
#include <QtCore/QObject>
#include "RegisteredMetaTypes.h"
#include "DependencyManager.h"
#include "RayPick.h"
#include <RegisteredMetaTypes.h>
#include <DependencyManager.h>
#include <pointers/rays/RayPick.h>
class RayPickScriptingInterface : public QObject, public Dependency {
Q_OBJECT
@ -25,7 +24,7 @@ class RayPickScriptingInterface : public QObject, public Dependency {
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_COURSE READ PICK_COURSE 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)
@ -38,25 +37,21 @@ class RayPickScriptingInterface : public QObject, public Dependency {
public slots:
Q_INVOKABLE QUuid createRayPick(const QVariant& properties);
Q_INVOKABLE void enableRayPick(QUuid uid);
Q_INVOKABLE void disableRayPick(QUuid uid);
Q_INVOKABLE void removeRayPick(QUuid uid);
Q_INVOKABLE RayPickResult getPrevRayPickResult(QUuid uid);
Q_INVOKABLE void enableRayPick(const QUuid& uid);
Q_INVOKABLE void disableRayPick(const QUuid& uid);
Q_INVOKABLE void removeRayPick(const QUuid& uid);
Q_INVOKABLE RayPickResult getPrevRayPickResult(const QUuid& uid);
Q_INVOKABLE void setPrecisionPicking(QUuid uid, const bool precisionPicking);
Q_INVOKABLE void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities);
Q_INVOKABLE void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities);
Q_INVOKABLE void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays);
Q_INVOKABLE void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays);
Q_INVOKABLE void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars);
Q_INVOKABLE void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars);
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);
unsigned int PICK_NOTHING() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_NOTHING); }
unsigned int PICK_NOTHING() { return 0; }
unsigned int PICK_ENTITIES() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_ENTITIES); }
unsigned int PICK_OVERLAYS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_OVERLAYS); }
unsigned int PICK_AVATARS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_AVATARS); }
unsigned int PICK_HUD() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_HUD); }
unsigned int PICK_COURSE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_COURSE); }
unsigned int PICK_COARSE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_COARSE); }
unsigned int PICK_INCLUDE_INVISIBLE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_INCLUDE_INVISIBLE); }
unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_INCLUDE_NONCOLLIDABLE); }
unsigned int PICK_ALL_INTERSECTIONS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_ALL_INTERSECTIONS); }

View file

@ -0,0 +1,5 @@
set(TARGET_NAME pointers)
setup_hifi_library()
GroupSources(src)
link_hifi_libraries(shared)

View file

@ -0,0 +1,6 @@
#include "PointerManager.h"
PointerManager::PointerManager() {
}

View file

@ -0,0 +1,30 @@
//
// Created by Bradley Austin Davis on 2017/10/16
// Copyright 2013-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_pointers_PointerManager_h
#define hifi_pointers_PointerManager_h
#include <DependencyManager.h>
#include <PointerEvent.h>
class PointerManager : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public:
PointerManager();
signals:
void triggerBegin(const QUuid& id, const PointerEvent& pointerEvent);
void triggerContinue(const QUuid& id, const PointerEvent& pointerEvent);
void triggerEnd(const QUuid& id, const PointerEvent& pointerEvent);
void hoverEnter(const QUuid& id, const PointerEvent& pointerEvent);
void hoverOver(const QUuid& id, const PointerEvent& pointerEvent);
void hoverLeave(const QUuid& id, const PointerEvent& pointerEvent);
};
#endif // hifi_pointers_PointerManager_h

View file

@ -0,0 +1,81 @@
//
// 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 "RayPick.h"
const RayPickFilter RayPickFilter::NOTHING;
RayPick::RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) :
_filter(filter),
_maxDistance(maxDistance),
_enabled(enabled)
{
}
void RayPick::enable(bool enabled) {
withWriteLock([&] {
_enabled = enabled;
});
}
RayPickFilter RayPick::getFilter() const {
return resultWithReadLock<RayPickFilter>([&] {
return _filter;
});
}
float RayPick::getMaxDistance() const {
return _maxDistance;
}
bool RayPick::isEnabled() const {
return resultWithReadLock<bool>([&] {
return _enabled;
});
}
void RayPick::setPrecisionPicking(bool precisionPicking) {
withWriteLock([&]{
_filter.setFlag(RayPickFilter::PICK_COARSE, !precisionPicking);
});
}
void RayPick::setRayPickResult(const RayPickResult& rayPickResult) {
withWriteLock([&] {
_prevResult = rayPickResult;
});
}
QVector<QUuid> RayPick::getIgnoreItems() const {
return resultWithReadLock<QVector<QUuid>>([&] {
return _ignoreItems;
});
}
QVector<QUuid> RayPick::getIncludeItems() const {
return resultWithReadLock<QVector<QUuid>>([&] {
return _includeItems;
});
}
RayPickResult RayPick::getPrevRayPickResult() const {
return resultWithReadLock<RayPickResult>([&] {
return _prevResult;
});
}
void RayPick::setIgnoreItems(const QVector<QUuid>& ignoreItems) {
withWriteLock([&] {
_ignoreItems = ignoreItems;
});
}
void RayPick::setIncludeItems(const QVector<QUuid>& includeItems) {
withWriteLock([&] {
_includeItems = includeItems;
});
}

View file

@ -1,7 +1,4 @@
//
// RayPick.h
// interface/src/raypick
//
// Created by Sam Gondelman 7/11/2017
// Copyright 2017 High Fidelity, Inc.
//
@ -12,22 +9,22 @@
#define hifi_RayPick_h
#include <stdint.h>
#include "RegisteredMetaTypes.h"
#include <bitset>
#include "EntityItemID.h"
#include "ui/overlays/Overlay.h"
#include <QReadWriteLock>
#include <QtCore/QUuid>
#include <RegisteredMetaTypes.h>
#include <shared/ReadWriteLockable.h>
class RayPickFilter {
public:
enum FlagBit {
PICK_NOTHING = 0,
PICK_ENTITIES,
PICK_ENTITIES = 0,
PICK_OVERLAYS,
PICK_AVATARS,
PICK_HUD,
PICK_COURSE, // if not set, does precise intersection, otherwise, doesn't
PICK_COARSE, // if not set, does precise intersection, otherwise, doesn't
PICK_INCLUDE_INVISIBLE, // if not set, will not intersect invisible elements, otherwise, intersects both visible and invisible elements
PICK_INCLUDE_NONCOLLIDABLE, // if not set, will not intersect noncollidable elements, otherwise, intersects both collidable and noncollidable elements
@ -42,7 +39,7 @@ public:
// The key is the Flags
Flags _flags;
RayPickFilter() : _flags(getBitMask(PICK_NOTHING)) {}
RayPickFilter() {}
RayPickFilter(const Flags& flags) : _flags(flags) {}
bool operator== (const RayPickFilter& rhs) const { return _flags == rhs._flags; }
@ -50,13 +47,13 @@ public:
void setFlag(FlagBit flag, bool value) { _flags[flag] = value; }
bool doesPickNothing() const { return _flags[PICK_NOTHING]; }
bool doesPickNothing() const { return _flags == NOTHING._flags; }
bool doesPickEntities() const { return _flags[PICK_ENTITIES]; }
bool doesPickOverlays() const { return _flags[PICK_OVERLAYS]; }
bool doesPickAvatars() const { return _flags[PICK_AVATARS]; }
bool doesPickHUD() const { return _flags[PICK_HUD]; }
bool doesPickCourse() const { return _flags[PICK_COURSE]; }
bool doesPickCoarse() const { return _flags[PICK_COARSE]; }
bool doesPickInvisible() const { return _flags[PICK_INCLUDE_INVISIBLE]; }
bool doesPickNonCollidable() const { return _flags[PICK_INCLUDE_NONCOLLIDABLE]; }
@ -71,8 +68,8 @@ public:
if (doesPickNonCollidable()) {
toReturn |= getBitMask(PICK_INCLUDE_NONCOLLIDABLE);
}
if (doesPickCourse()) {
toReturn |= getBitMask(PICK_COURSE);
if (doesPickCoarse()) {
toReturn |= getBitMask(PICK_COARSE);
}
return Flags(toReturn);
}
@ -84,66 +81,76 @@ public:
if (doesPickNonCollidable()) {
toReturn |= getBitMask(PICK_INCLUDE_NONCOLLIDABLE);
}
if (doesPickCourse()) {
toReturn |= getBitMask(PICK_COURSE);
if (doesPickCoarse()) {
toReturn |= getBitMask(PICK_COARSE);
}
return Flags(toReturn);
}
Flags getAvatarFlags() const { return Flags(getBitMask(PICK_AVATARS)); }
Flags getHUDFlags() const { return Flags(getBitMask(PICK_HUD)); }
static unsigned int getBitMask(FlagBit bit) { return 1 << bit; }
static constexpr unsigned int getBitMask(FlagBit bit) { return 1 << bit; }
static const RayPickFilter NOTHING;
};
class RayPick {
class RayPick : protected ReadWriteLockable {
public:
using Pointer = std::shared_ptr<RayPick>;
RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled);
virtual const PickRay getPickRay(bool& valid) const = 0;
void enable();
void disable();
void enable(bool enabled = true);
void disable() { enable(false); }
const RayPickFilter& getFilter() { return _filter; }
float getMaxDistance() { return _maxDistance; }
bool isEnabled() { return _enabled; }
const RayPickResult& getPrevRayPickResult();
RayPickFilter getFilter() const;
float getMaxDistance() const;
bool isEnabled() const;
RayPickResult getPrevRayPickResult() const;
void setPrecisionPicking(bool precisionPicking) { _filter.setFlag(RayPickFilter::PICK_COURSE, !precisionPicking); }
void setPrecisionPicking(bool precisionPicking);
void setRayPickResult(const RayPickResult& rayPickResult) { _prevResult = rayPickResult; }
void setRayPickResult(const RayPickResult& rayPickResult);
const QVector<EntityItemID>& getIgnoreEntites() { return _ignoreEntities; }
const QVector<EntityItemID>& getIncludeEntites() { return _includeEntities; }
const QVector<OverlayID>& getIgnoreOverlays() { return _ignoreOverlays; }
const QVector<OverlayID>& getIncludeOverlays() { return _includeOverlays; }
const QVector<EntityItemID>& getIgnoreAvatars() { return _ignoreAvatars; }
const QVector<EntityItemID>& getIncludeAvatars() { return _includeAvatars; }
void setIgnoreEntities(const QScriptValue& ignoreEntities);
void setIncludeEntities(const QScriptValue& includeEntities);
void setIgnoreOverlays(const QScriptValue& ignoreOverlays);
void setIncludeOverlays(const QScriptValue& includeOverlays);
void setIgnoreAvatars(const QScriptValue& ignoreAvatars);
void setIncludeAvatars(const QScriptValue& includeAvatars);
QVector<QUuid> getIgnoreItems() const;
QVector<QUuid> getIncludeItems() const;
QReadWriteLock* getLock() { return &_lock; }
template <typename T>
QVector<T> getIgnoreItemsAs() const {
QVector<T> result;
withReadLock([&] {
for (const auto& uid : _ignoreItems) {
result.push_back(uid);
}
});
return result;
}
template <typename T>
QVector<T> getIncludeItemsAs() const {
QVector<T> result;
withReadLock([&] {
for (const auto& uid : _includeItems) {
result.push_back(uid);
}
});
return result;
}
void setIgnoreItems(const QVector<QUuid>& items);
void setIncludeItems(const QVector<QUuid>& items);
private:
RayPickFilter _filter;
float _maxDistance;
const float _maxDistance;
bool _enabled;
RayPickResult _prevResult;
QVector<EntityItemID> _ignoreEntities;
QVector<EntityItemID> _includeEntities;
QVector<OverlayID> _ignoreOverlays;
QVector<OverlayID> _includeOverlays;
QVector<EntityItemID> _ignoreAvatars;
QVector<EntityItemID> _includeAvatars;
QReadWriteLock _lock;
QVector<QUuid> _ignoreItems;
QVector<QUuid> _includeItems;
};
#endif // hifi_RayPick_h

View file

@ -1,7 +1,4 @@
//
// StaticRayPick.cpp
// interface/src/raypick
//
// Created by Sam Gondelman 7/11/2017
// Copyright 2017 High Fidelity, Inc.
//

View file

@ -1,7 +1,4 @@
//
// StaticRayPick.h
// interface/src/raypick
//
// Created by Sam Gondelman 7/11/2017
// Copyright 2017 High Fidelity, Inc.
//

View file

@ -141,8 +141,11 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
};
this.setIgnoreTablet = function() {
RayPick.setIgnoreOverlays(_this.leftControllerRayPick, [HMD.tabletID]);
RayPick.setIgnoreOverlays(_this.rightControllerRayPick, [HMD.tabletID]);
if (HMD.tabletID !== this.tabletID) {
this.tabletID = HMD.tabletID;
RayPick.setIgnoreItems(_this.leftControllerRayPick, _this.blacklist.concat([HMD.tabletID]));
RayPick.setIgnoreItems(_this.rightControllerRayPick, _this.blacklist.concat([HMD.tabletID]));
}
};
this.update = function () {
@ -367,9 +370,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
};
this.setBlacklist = function() {
RayPick.setIgnoreEntities(_this.leftControllerRayPick, this.blacklist);
RayPick.setIgnoreEntities(_this.rightControllerRayPick, this.blacklist);
RayPick.setIgnoreItems(_this.leftControllerRayPick, this.blacklist.concat(HMD.tabletID));
RayPick.setIgnoreItems(_this.rightControllerRayPick, this.blacklist.concat(HMD.tabletID));
};
var MAPPING_NAME = "com.highfidelity.controllerDispatcher";

View file

@ -127,6 +127,13 @@ Script.include("/~/system/libraries/utils.js");
this.updateLaserPointer = function(controllerData) {
LaserPointers.enableLaserPointer(this.laserPointer);
LaserPointers.setRenderState(this.laserPointer, this.mode);
if (HMD.tabletID !== this.tabletID || HMD.tabletButtonID !== this.tabletButtonID || HMD.tabletScreenID !== this.tabletScreenID) {
this.tabletID = HMD.tabletID;
this.tabletButtonID = HMD.tabletButtonID;
this.tabletScreenID = HMD.tabletScreenID;
LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]);
}
};
this.pointingAtTablet = function(objectID) {
@ -233,7 +240,7 @@ Script.include("/~/system/libraries/utils.js");
defaultRenderStates: defaultRenderStates
});
LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]);
LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]);
}
var leftHandInEditMode = new InEditMode(LEFT_HAND);

View file

@ -177,6 +177,11 @@ Script.include("/~/system/libraries/controllers.js");
this.updateLaserPointer = function(controllerData) {
LaserPointers.enableLaserPointer(this.laserPointer);
LaserPointers.setRenderState(this.laserPointer, this.mode);
if (HMD.tabletID !== this.tabletID) {
this.tabletID = HMD.tabletID;
LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID]);
}
};
this.processControllerTriggers = function(controllerData) {
@ -369,7 +374,7 @@ Script.include("/~/system/libraries/controllers.js");
defaultRenderStates: defaultRenderStates
});
LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID]);
LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID]);
}
var leftOverlayLaserInput = new OverlayLaserInput(LEFT_HAND);

View file

@ -349,10 +349,10 @@ Script.include("/~/system/libraries/controllers.js");
};
this.setIgnoreEntities = function(entitiesToIgnore) {
LaserPointers.setIgnoreEntities(this.teleportRayHandVisible, entitiesToIgnore);
LaserPointers.setIgnoreEntities(this.teleportRayHandInvisible, entitiesToIgnore);
LaserPointers.setIgnoreEntities(this.teleportRayHeadVisible, entitiesToIgnore);
LaserPointers.setIgnoreEntities(this.teleportRayHeadInvisible, entitiesToIgnore);
LaserPointers.setIgnoreItems(this.teleportRayHandVisible, entitiesToIgnore);
LaserPointers.setIgnoreItems(this.teleportRayHandInvisible, entitiesToIgnore);
LaserPointers.setIgnoreItems(this.teleportRayHeadVisible, entitiesToIgnore);
LaserPointers.setIgnoreItems(this.teleportRayHeadInvisible, entitiesToIgnore);
};
}

View file

@ -263,7 +263,7 @@ function Grabber() {
filter: RayPick.PICK_OVERLAYS,
enabled: true
});
RayPick.setIncludeOverlays(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]);
RayPick.setIncludeItems(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]);
var renderStates = [{name: "grabbed", end: beacon}];
this.mouseRayEntities = LaserPointers.createLaserPointer({
joint: "Mouse",