mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 20:36:24 +02:00
switch to stl wherever possible, use bitset instead of unsigned ints
This commit is contained in:
parent
85c3f94976
commit
d0d5ac8dd1
16 changed files with 268 additions and 201 deletions
|
@ -13,7 +13,7 @@
|
||||||
#include "DependencyManager.h"
|
#include "DependencyManager.h"
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
|
|
||||||
JointRayPick::JointRayPick(const QString& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const uint16_t filter, const float maxDistance, const bool enabled) :
|
JointRayPick::JointRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled) :
|
||||||
RayPick(filter, maxDistance, enabled),
|
RayPick(filter, maxDistance, enabled),
|
||||||
_jointName(jointName),
|
_jointName(jointName),
|
||||||
_posOffset(posOffset),
|
_posOffset(posOffset),
|
||||||
|
@ -23,7 +23,7 @@ JointRayPick::JointRayPick(const QString& jointName, const glm::vec3& posOffset,
|
||||||
|
|
||||||
const PickRay JointRayPick::getPickRay(bool& valid) const {
|
const PickRay JointRayPick::getPickRay(bool& valid) const {
|
||||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
int jointIndex = myAvatar->getJointIndex(_jointName);
|
int jointIndex = myAvatar->getJointIndex(QString::fromStdString(_jointName));
|
||||||
bool useAvatarHead = _jointName == "Avatar";
|
bool useAvatarHead = _jointName == "Avatar";
|
||||||
const int INVALID_JOINT = -1;
|
const int INVALID_JOINT = -1;
|
||||||
if (jointIndex != INVALID_JOINT || useAvatarHead) {
|
if (jointIndex != INVALID_JOINT || useAvatarHead) {
|
||||||
|
|
|
@ -13,17 +13,15 @@
|
||||||
|
|
||||||
#include "RayPick.h"
|
#include "RayPick.h"
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
class JointRayPick : public RayPick {
|
class JointRayPick : public RayPick {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JointRayPick(const QString& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const uint16_t filter, const float maxDistance = 0.0f, const bool enabled = false);
|
JointRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance = 0.0f, const bool enabled = false);
|
||||||
|
|
||||||
const PickRay getPickRay(bool& valid) const override;
|
const PickRay getPickRay(bool& valid) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _jointName;
|
std::string _jointName;
|
||||||
glm::vec3 _posOffset;
|
glm::vec3 _posOffset;
|
||||||
glm::vec3 _dirOffset;
|
glm::vec3 _dirOffset;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
|
|
||||||
LaserPointer::LaserPointer(const QVariantMap& rayProps, const QHash<QString, RenderState>& renderStates, QHash<QString, QPair<float, RenderState>>& defaultRenderStates,
|
LaserPointer::LaserPointer(const QVariantMap& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates,
|
||||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) :
|
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) :
|
||||||
_renderingEnabled(enabled),
|
_renderingEnabled(enabled),
|
||||||
_renderStates(renderStates),
|
_renderStates(renderStates),
|
||||||
|
@ -24,14 +24,14 @@ LaserPointer::LaserPointer(const QVariantMap& rayProps, const QHash<QString, Ren
|
||||||
{
|
{
|
||||||
_rayPickUID = DependencyManager::get<RayPickManager>()->createRayPick(rayProps);
|
_rayPickUID = DependencyManager::get<RayPickManager>()->createRayPick(rayProps);
|
||||||
|
|
||||||
for (QString& state : _renderStates.keys()) {
|
for (auto& state : _renderStates) {
|
||||||
if (!enabled || state != _currentRenderState) {
|
if (!enabled || state.first != _currentRenderState) {
|
||||||
disableRenderState(_renderStates[state]);
|
disableRenderState(state.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (QString& state : _defaultRenderStates.keys()) {
|
for (auto& state : _defaultRenderStates) {
|
||||||
if (!enabled || state != _currentRenderState) {
|
if (!enabled || state.first != _currentRenderState) {
|
||||||
disableRenderState(_defaultRenderStates[state].second);
|
disableRenderState(state.second.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,12 @@ LaserPointer::LaserPointer(const QVariantMap& rayProps, const QHash<QString, Ren
|
||||||
LaserPointer::~LaserPointer() {
|
LaserPointer::~LaserPointer() {
|
||||||
DependencyManager::get<RayPickManager>()->removeRayPick(_rayPickUID);
|
DependencyManager::get<RayPickManager>()->removeRayPick(_rayPickUID);
|
||||||
|
|
||||||
for (RenderState& renderState : _renderStates) {
|
for (auto& renderState : _renderStates) {
|
||||||
renderState.deleteOverlays();
|
|
||||||
}
|
|
||||||
for (QPair<float, RenderState>& renderState : _defaultRenderStates) {
|
|
||||||
renderState.second.deleteOverlays();
|
renderState.second.deleteOverlays();
|
||||||
}
|
}
|
||||||
|
for (auto& renderState : _defaultRenderStates) {
|
||||||
|
renderState.second.second.deleteOverlays();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::enable() {
|
void LaserPointer::enable() {
|
||||||
|
@ -55,29 +55,29 @@ void LaserPointer::enable() {
|
||||||
void LaserPointer::disable() {
|
void LaserPointer::disable() {
|
||||||
DependencyManager::get<RayPickManager>()->disableRayPick(_rayPickUID);
|
DependencyManager::get<RayPickManager>()->disableRayPick(_rayPickUID);
|
||||||
_renderingEnabled = false;
|
_renderingEnabled = false;
|
||||||
if (!_currentRenderState.isEmpty()) {
|
if (!_currentRenderState.empty()) {
|
||||||
if (_renderStates.contains(_currentRenderState)) {
|
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
|
||||||
disableRenderState(_renderStates[_currentRenderState]);
|
disableRenderState(_renderStates[_currentRenderState]);
|
||||||
}
|
}
|
||||||
if (_defaultRenderStates.contains(_currentRenderState)) {
|
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
|
||||||
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::setRenderState(const QString& state) {
|
void LaserPointer::setRenderState(const std::string& state) {
|
||||||
if (!_currentRenderState.isEmpty() && state != _currentRenderState) {
|
if (!_currentRenderState.empty() && state != _currentRenderState) {
|
||||||
if (_renderStates.contains(_currentRenderState)) {
|
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
|
||||||
disableRenderState(_renderStates[_currentRenderState]);
|
disableRenderState(_renderStates[_currentRenderState]);
|
||||||
}
|
}
|
||||||
if (_defaultRenderStates.contains(_currentRenderState)) {
|
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
|
||||||
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_currentRenderState = state;
|
_currentRenderState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::editRenderState(const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
|
void LaserPointer::editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
|
||||||
updateRenderStateOverlay(_renderStates[state].getStartID(), startProps);
|
updateRenderStateOverlay(_renderStates[state].getStartID(), startProps);
|
||||||
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
|
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
|
||||||
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
|
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
|
||||||
|
@ -181,13 +181,13 @@ void LaserPointer::disableRenderState(const RenderState& renderState) {
|
||||||
|
|
||||||
void LaserPointer::update() {
|
void LaserPointer::update() {
|
||||||
RayPickResult prevRayPickResult = DependencyManager::get<RayPickManager>()->getPrevRayPickResult(_rayPickUID);
|
RayPickResult prevRayPickResult = DependencyManager::get<RayPickManager>()->getPrevRayPickResult(_rayPickUID);
|
||||||
if (_renderingEnabled && !_currentRenderState.isEmpty() && _renderStates.contains(_currentRenderState) && prevRayPickResult.type != IntersectionType::NONE) {
|
if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && prevRayPickResult.type != IntersectionType::NONE) {
|
||||||
updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, prevRayPickResult.distance, prevRayPickResult.objectID, false);
|
updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, prevRayPickResult.distance, prevRayPickResult.objectID, false);
|
||||||
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
||||||
} else if (_renderingEnabled && !_currentRenderState.isEmpty() && _defaultRenderStates.contains(_currentRenderState)) {
|
} else if (_renderingEnabled && !_currentRenderState.empty() && _defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
|
||||||
disableRenderState(_renderStates[_currentRenderState]);
|
disableRenderState(_renderStates[_currentRenderState]);
|
||||||
updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), true);
|
updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), true);
|
||||||
} else if (!_currentRenderState.isEmpty()) {
|
} else if (!_currentRenderState.empty()) {
|
||||||
disableRenderState(_renderStates[_currentRenderState]);
|
disableRenderState(_renderStates[_currentRenderState]);
|
||||||
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,11 @@ private:
|
||||||
class LaserPointer {
|
class LaserPointer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LaserPointer(const QVariantMap& rayProps, const QHash<QString, RenderState>& renderStates, QHash<QString, QPair<float, RenderState>>& defaultRenderStates,
|
|
||||||
|
typedef std::unordered_map<std::string, RenderState> RenderStateMap;
|
||||||
|
typedef std::unordered_map<std::string, std::pair<float, RenderState>> DefaultRenderStateMap;
|
||||||
|
|
||||||
|
LaserPointer(const QVariantMap& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates,
|
||||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
|
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
|
||||||
~LaserPointer();
|
~LaserPointer();
|
||||||
|
|
||||||
|
@ -57,9 +61,9 @@ public:
|
||||||
void disable();
|
void disable();
|
||||||
const RayPickResult getPrevRayPickResult() { return DependencyManager::get<RayPickManager>()->getPrevRayPickResult(_rayPickUID); }
|
const RayPickResult getPrevRayPickResult() { return DependencyManager::get<RayPickManager>()->getPrevRayPickResult(_rayPickUID); }
|
||||||
|
|
||||||
void setRenderState(const QString& state);
|
void setRenderState(const std::string& state);
|
||||||
// You cannot use editRenderState to change the overlay type of any part of the laser pointer. You can only edit the properties of the existing overlays.
|
// You cannot use editRenderState to change the overlay type of any part of the laser pointer. You can only edit the properties of the existing overlays.
|
||||||
void editRenderState(const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
|
void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
|
||||||
|
|
||||||
void setIgnoreEntities(const QScriptValue& ignoreEntities) { DependencyManager::get<RayPickManager>()->setIgnoreEntities(_rayPickUID, ignoreEntities); }
|
void setIgnoreEntities(const QScriptValue& ignoreEntities) { DependencyManager::get<RayPickManager>()->setIgnoreEntities(_rayPickUID, ignoreEntities); }
|
||||||
void setIncludeEntities(const QScriptValue& includeEntities) { DependencyManager::get<RayPickManager>()->setIncludeEntities(_rayPickUID, includeEntities); }
|
void setIncludeEntities(const QScriptValue& includeEntities) { DependencyManager::get<RayPickManager>()->setIncludeEntities(_rayPickUID, includeEntities); }
|
||||||
|
@ -68,25 +72,26 @@ public:
|
||||||
void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { DependencyManager::get<RayPickManager>()->setIgnoreAvatars(_rayPickUID, ignoreAvatars); }
|
void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { DependencyManager::get<RayPickManager>()->setIgnoreAvatars(_rayPickUID, ignoreAvatars); }
|
||||||
void setIncludeAvatars(const QScriptValue& includeAvatars) { DependencyManager::get<RayPickManager>()->setIncludeAvatars(_rayPickUID, includeAvatars); }
|
void setIncludeAvatars(const QScriptValue& includeAvatars) { DependencyManager::get<RayPickManager>()->setIncludeAvatars(_rayPickUID, includeAvatars); }
|
||||||
|
|
||||||
void setLockEndUUID(QUuid objectID, const bool isOverlay) { _objectLockEnd = QPair<QUuid, bool>(objectID, isOverlay); }
|
void setLockEndUUID(QUuid objectID, const bool isOverlay) { _objectLockEnd = std::pair<QUuid, bool>(objectID, isOverlay); }
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _renderingEnabled;
|
bool _renderingEnabled;
|
||||||
QString _currentRenderState { "" };
|
std::string _currentRenderState { "" };
|
||||||
QHash<QString, RenderState> _renderStates;
|
RenderStateMap _renderStates;
|
||||||
QHash<QString, QPair<float, RenderState>> _defaultRenderStates;
|
DefaultRenderStateMap _defaultRenderStates;
|
||||||
bool _faceAvatar;
|
bool _faceAvatar;
|
||||||
bool _centerEndY;
|
bool _centerEndY;
|
||||||
bool _lockEnd;
|
bool _lockEnd;
|
||||||
QPair<QUuid, bool> _objectLockEnd { QPair<QUuid, bool>(QUuid(), false)};
|
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
|
||||||
|
|
||||||
QUuid _rayPickUID;
|
QUuid _rayPickUID;
|
||||||
|
|
||||||
void updateRenderStateOverlay(const OverlayID& id, const QVariant& props);
|
void updateRenderStateOverlay(const OverlayID& id, const QVariant& props);
|
||||||
void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const bool defaultState);
|
void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const bool defaultState);
|
||||||
void disableRenderState(const RenderState& renderState);
|
void disableRenderState(const RenderState& renderState);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_LaserPointer_h
|
#endif // hifi_LaserPointer_h
|
||||||
|
|
|
@ -11,85 +11,87 @@
|
||||||
#include "LaserPointerManager.h"
|
#include "LaserPointerManager.h"
|
||||||
#include "RayPick.h"
|
#include "RayPick.h"
|
||||||
|
|
||||||
QUuid LaserPointerManager::createLaserPointer(const QVariantMap& rayProps, const QHash<QString, RenderState>& renderStates, QHash<QString, QPair<float, RenderState>>& defaultRenderStates,
|
QUuid LaserPointerManager::createLaserPointer(const QVariantMap& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
|
||||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) {
|
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) {
|
||||||
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled);
|
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled);
|
||||||
if (!laserPointer->getRayUID().isNull()) {
|
if (!laserPointer->getRayUID().isNull()) {
|
||||||
QWriteLocker lock(&_addLock);
|
WriteLock lock(_addLock);
|
||||||
QUuid id = QUuid::createUuid();
|
QUuid id = QUuid::createUuid();
|
||||||
_laserPointersToAdd.enqueue(QPair<QUuid, std::shared_ptr<LaserPointer>>(id, laserPointer));
|
_laserPointersToAdd.push(std::pair<QUuid, std::shared_ptr<LaserPointer>>(id, laserPointer));
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
return QUuid();
|
return QUuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::removeLaserPointer(const QUuid uid) {
|
void LaserPointerManager::removeLaserPointer(const QUuid uid) {
|
||||||
QWriteLocker lock(&_removeLock);
|
WriteLock lock(_removeLock);
|
||||||
_laserPointersToRemove.enqueue(uid);
|
_laserPointersToRemove.push(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::enableLaserPointer(const QUuid uid) {
|
void LaserPointerManager::enableLaserPointer(const QUuid uid) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->enable();
|
_laserPointers[uid]->enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::disableLaserPointer(const QUuid uid) {
|
void LaserPointerManager::disableLaserPointer(const QUuid uid) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->disable();
|
_laserPointers[uid]->disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setRenderState(QUuid uid, const QString & renderState) {
|
void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderState) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->setRenderState(renderState);
|
_laserPointers[uid]->setRenderState(renderState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::editRenderState(QUuid uid, const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
|
void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->editRenderState(state, startProps, pathProps, endProps);
|
_laserPointers[uid]->editRenderState(state, startProps, pathProps, endProps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) {
|
const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QReadLocker laserLock(_laserPointerLocks[uid].get());
|
ReadLock laserLock(*_laserPointerLocks[uid]);
|
||||||
return _laserPointers[uid]->getPrevRayPickResult();
|
return _laserPointers[uid]->getPrevRayPickResult();
|
||||||
}
|
}
|
||||||
return RayPickResult();
|
return RayPickResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::update() {
|
void LaserPointerManager::update() {
|
||||||
for (QUuid uid : _laserPointers.keys()) {
|
for (QUuid& 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
|
// 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());
|
ReadLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->update();
|
_laserPointers[uid]->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
QWriteLocker containsLock(&_containsLock);
|
WriteLock containsLock(_containsLock);
|
||||||
{
|
{
|
||||||
QWriteLocker lock(&_addLock);
|
WriteLock lock(_addLock);
|
||||||
while (!_laserPointersToAdd.isEmpty()) {
|
while (!_laserPointersToAdd.empty()) {
|
||||||
QPair<QUuid, std::shared_ptr<LaserPointer>> laserPointerToAdd = _laserPointersToAdd.dequeue();
|
std::pair<QUuid, std::shared_ptr<LaserPointer>> laserPointerToAdd = _laserPointersToAdd.front();
|
||||||
|
_laserPointersToAdd.pop();
|
||||||
_laserPointers[laserPointerToAdd.first] = laserPointerToAdd.second;
|
_laserPointers[laserPointerToAdd.first] = laserPointerToAdd.second;
|
||||||
_laserPointerLocks[laserPointerToAdd.first] = std::make_shared<QReadWriteLock>();
|
_laserPointerLocks[laserPointerToAdd.first] = std::make_shared<std::shared_mutex>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
QWriteLocker lock(&_removeLock);
|
WriteLock lock(_removeLock);
|
||||||
while (!_laserPointersToRemove.isEmpty()) {
|
while (!_laserPointersToRemove.empty()) {
|
||||||
QUuid uid = _laserPointersToRemove.dequeue();
|
QUuid uid = _laserPointersToRemove.front();
|
||||||
|
_laserPointersToRemove.pop();
|
||||||
_laserPointers.remove(uid);
|
_laserPointers.remove(uid);
|
||||||
_laserPointerLocks.remove(uid);
|
_laserPointerLocks.remove(uid);
|
||||||
}
|
}
|
||||||
|
@ -97,57 +99,57 @@ void LaserPointerManager::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
|
void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->setIgnoreEntities(ignoreEntities);
|
_laserPointers[uid]->setIgnoreEntities(ignoreEntities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
|
void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->setIncludeEntities(includeEntities);
|
_laserPointers[uid]->setIncludeEntities(includeEntities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
|
void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->setIgnoreOverlays(ignoreOverlays);
|
_laserPointers[uid]->setIgnoreOverlays(ignoreOverlays);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
|
void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->setIncludeOverlays(includeOverlays);
|
_laserPointers[uid]->setIncludeOverlays(includeOverlays);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
|
void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->setIgnoreAvatars(ignoreAvatars);
|
_laserPointers[uid]->setIgnoreAvatars(ignoreAvatars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
|
void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->setIncludeAvatars(includeAvatars);
|
_laserPointers[uid]->setIncludeAvatars(includeAvatars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) {
|
void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) {
|
||||||
QReadLocker lock(&_containsLock);
|
ReadLock lock(_containsLock);
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||||
_laserPointers[uid]->setLockEndUUID(objectID, isOverlay);
|
_laserPointers[uid]->setLockEndUUID(objectID, isOverlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,8 @@
|
||||||
#ifndef hifi_LaserPointerManager_h
|
#ifndef hifi_LaserPointerManager_h
|
||||||
#define hifi_LaserPointerManager_h
|
#define hifi_LaserPointerManager_h
|
||||||
|
|
||||||
#include <QHash>
|
|
||||||
#include <QString>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include "LaserPointer.h"
|
#include "LaserPointer.h"
|
||||||
|
@ -23,13 +22,13 @@ class RayPickResult;
|
||||||
class LaserPointerManager {
|
class LaserPointerManager {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QUuid createLaserPointer(const QVariantMap& rayProps, const QHash<QString, RenderState>& renderStates, QHash<QString, QPair<float, RenderState>>& defaultRenderStates,
|
QUuid createLaserPointer(const QVariantMap& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
|
||||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
|
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
|
||||||
void removeLaserPointer(const QUuid uid);
|
void removeLaserPointer(const QUuid uid);
|
||||||
void enableLaserPointer(const QUuid uid);
|
void enableLaserPointer(const QUuid uid);
|
||||||
void disableLaserPointer(const QUuid uid);
|
void disableLaserPointer(const QUuid uid);
|
||||||
void setRenderState(QUuid uid, const QString& renderState);
|
void setRenderState(QUuid uid, const std::string& renderState);
|
||||||
void editRenderState(QUuid uid, const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
|
void editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
|
||||||
const RayPickResult getPrevRayPickResult(const QUuid uid);
|
const RayPickResult getPrevRayPickResult(const QUuid uid);
|
||||||
|
|
||||||
void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities);
|
void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities);
|
||||||
|
@ -45,12 +44,15 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<QUuid, std::shared_ptr<LaserPointer>> _laserPointers;
|
QHash<QUuid, std::shared_ptr<LaserPointer>> _laserPointers;
|
||||||
QHash<QUuid, std::shared_ptr<QReadWriteLock>> _laserPointerLocks;
|
QHash<QUuid, std::shared_ptr<std::shared_mutex>> _laserPointerLocks;
|
||||||
QReadWriteLock _addLock;
|
std::shared_mutex _addLock;
|
||||||
QQueue<QPair<QUuid, std::shared_ptr<LaserPointer>>> _laserPointersToAdd;
|
std::queue<std::pair<QUuid, std::shared_ptr<LaserPointer>>> _laserPointersToAdd;
|
||||||
QReadWriteLock _removeLock;
|
std::shared_mutex _removeLock;
|
||||||
QQueue<QUuid> _laserPointersToRemove;
|
std::queue<QUuid> _laserPointersToRemove;
|
||||||
QReadWriteLock _containsLock;
|
std::shared_mutex _containsLock;
|
||||||
|
|
||||||
|
typedef std::lock_guard<std::shared_mutex> WriteLock;
|
||||||
|
typedef std::shared_lock<std::shared_mutex> ReadLock;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -40,30 +40,30 @@ QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& propert
|
||||||
enabled = propertyMap["enabled"].toBool();
|
enabled = propertyMap["enabled"].toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<QString, RenderState> renderStates;
|
LaserPointer::RenderStateMap renderStates;
|
||||||
if (propertyMap["renderStates"].isValid()) {
|
if (propertyMap["renderStates"].isValid()) {
|
||||||
QList<QVariant> renderStateVariants = propertyMap["renderStates"].toList();
|
QList<QVariant> renderStateVariants = propertyMap["renderStates"].toList();
|
||||||
for (QVariant& renderStateVariant : renderStateVariants) {
|
for (QVariant& renderStateVariant : renderStateVariants) {
|
||||||
if (renderStateVariant.isValid()) {
|
if (renderStateVariant.isValid()) {
|
||||||
QVariantMap renderStateMap = renderStateVariant.toMap();
|
QVariantMap renderStateMap = renderStateVariant.toMap();
|
||||||
if (renderStateMap["name"].isValid()) {
|
if (renderStateMap["name"].isValid()) {
|
||||||
QString name = renderStateMap["name"].toString();
|
std::string name = renderStateMap["name"].toString().toStdString();
|
||||||
renderStates[name] = buildRenderState(renderStateMap);
|
renderStates[name] = buildRenderState(renderStateMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<QString, QPair<float, RenderState>> defaultRenderStates;
|
LaserPointer::DefaultRenderStateMap defaultRenderStates;
|
||||||
if (propertyMap["defaultRenderStates"].isValid()) {
|
if (propertyMap["defaultRenderStates"].isValid()) {
|
||||||
QList<QVariant> renderStateVariants = propertyMap["defaultRenderStates"].toList();
|
QList<QVariant> renderStateVariants = propertyMap["defaultRenderStates"].toList();
|
||||||
for (QVariant& renderStateVariant : renderStateVariants) {
|
for (QVariant& renderStateVariant : renderStateVariants) {
|
||||||
if (renderStateVariant.isValid()) {
|
if (renderStateVariant.isValid()) {
|
||||||
QVariantMap renderStateMap = renderStateVariant.toMap();
|
QVariantMap renderStateMap = renderStateVariant.toMap();
|
||||||
if (renderStateMap["name"].isValid() && renderStateMap["distance"].isValid()) {
|
if (renderStateMap["name"].isValid() && renderStateMap["distance"].isValid()) {
|
||||||
QString name = renderStateMap["name"].toString();
|
std::string name = renderStateMap["name"].toString().toStdString();
|
||||||
float distance = renderStateMap["distance"].toFloat();
|
float distance = renderStateMap["distance"].toFloat();
|
||||||
defaultRenderStates[name] = QPair<float, RenderState>(distance, buildRenderState(renderStateMap));
|
defaultRenderStates[name] = std::pair<float, RenderState>(distance, buildRenderState(renderStateMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ void LaserPointerScriptingInterface::editRenderState(QUuid uid, const QString& r
|
||||||
endProps = propMap["end"];
|
endProps = propMap["end"];
|
||||||
}
|
}
|
||||||
|
|
||||||
qApp->getLaserPointerManager().editRenderState(uid, renderState, startProps, pathProps, endProps);
|
qApp->getLaserPointerManager().editRenderState(uid, renderState.toStdString(), startProps, pathProps, endProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
const RenderState LaserPointerScriptingInterface::buildRenderState(const QVariantMap& propMap) {
|
const RenderState LaserPointerScriptingInterface::buildRenderState(const QVariantMap& propMap) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ public slots:
|
||||||
Q_INVOKABLE void disableLaserPointer(QUuid uid) { qApp->getLaserPointerManager().disableLaserPointer(uid); }
|
Q_INVOKABLE void disableLaserPointer(QUuid uid) { qApp->getLaserPointerManager().disableLaserPointer(uid); }
|
||||||
Q_INVOKABLE void removeLaserPointer(QUuid uid) { qApp->getLaserPointerManager().removeLaserPointer(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 editRenderState(QUuid uid, const QString& renderState, const QVariant& properties);
|
||||||
Q_INVOKABLE void setRenderState(QUuid uid, const QString& renderState) { qApp->getLaserPointerManager().setRenderState(uid, renderState); }
|
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 RayPickResult getPrevRayPickResult(QUuid uid) { return qApp->getLaserPointerManager().getPrevRayPickResult(uid); }
|
||||||
|
|
||||||
Q_INVOKABLE void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { qApp->getLaserPointerManager().setIgnoreEntities(uid, ignoreEntities); }
|
Q_INVOKABLE void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { qApp->getLaserPointerManager().setIgnoreEntities(uid, ignoreEntities); }
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "display-plugins/CompositorHelper.h"
|
#include "display-plugins/CompositorHelper.h"
|
||||||
|
|
||||||
MouseRayPick::MouseRayPick(const uint16_t filter, const float maxDistance, const bool enabled) :
|
MouseRayPick::MouseRayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) :
|
||||||
RayPick(filter, maxDistance, enabled)
|
RayPick(filter, maxDistance, enabled)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
class MouseRayPick : public RayPick {
|
class MouseRayPick : public RayPick {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MouseRayPick(const uint16_t filter, const float maxDistance = 0.0f, const bool enabled = false);
|
MouseRayPick(const RayPickFilter& filter, const float maxDistance = 0.0f, const bool enabled = false);
|
||||||
|
|
||||||
const PickRay getPickRay(bool& valid) const override;
|
const PickRay getPickRay(bool& valid) const override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
//
|
//
|
||||||
#include "RayPick.h"
|
#include "RayPick.h"
|
||||||
|
|
||||||
RayPick::RayPick(const uint16_t filter, const float maxDistance, const bool enabled) :
|
RayPick::RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) :
|
||||||
_filter(filter),
|
_filter(filter),
|
||||||
_maxDistance(maxDistance),
|
_maxDistance(maxDistance),
|
||||||
_enabled(enabled)
|
_enabled(enabled)
|
||||||
|
|
|
@ -17,17 +17,87 @@
|
||||||
#include "EntityItemID.h"
|
#include "EntityItemID.h"
|
||||||
#include "ui/overlays/Overlay.h"
|
#include "ui/overlays/Overlay.h"
|
||||||
|
|
||||||
|
class RayPickFilter {
|
||||||
|
public:
|
||||||
|
enum FlagBit {
|
||||||
|
PICK_NOTHING = 0,
|
||||||
|
PICK_ENTITIES,
|
||||||
|
PICK_OVERLAYS,
|
||||||
|
PICK_AVATARS,
|
||||||
|
PICK_HUD,
|
||||||
|
|
||||||
|
PICK_COURSE, // 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
|
||||||
|
|
||||||
|
// NOT YET IMPLEMENTED
|
||||||
|
PICK_ALL_INTERSECTIONS, // if not set, returns closest intersection, otherwise, returns list of all intersections
|
||||||
|
|
||||||
|
NUM_FLAGS, // Not a valid flag
|
||||||
|
};
|
||||||
|
typedef std::bitset<NUM_FLAGS> Flags;
|
||||||
|
|
||||||
|
// The key is the Flags
|
||||||
|
Flags _flags;
|
||||||
|
|
||||||
|
RayPickFilter() : _flags(PICK_NOTHING) {}
|
||||||
|
RayPickFilter(const Flags& flags) : _flags(flags) {}
|
||||||
|
|
||||||
|
bool operator== (const RayPickFilter& rhs) const { return _flags == rhs._flags; }
|
||||||
|
bool operator!= (const RayPickFilter& rhs) const { return _flags != rhs._flags; }
|
||||||
|
|
||||||
|
bool doesPickNothing() const { return _flags[PICK_NOTHING]; }
|
||||||
|
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 doesPickInvisible() const { return _flags[PICK_INCLUDE_INVISIBLE]; }
|
||||||
|
bool doesPickNonCollidable() const { return _flags[PICK_INCLUDE_NONCOLLIDABLE]; }
|
||||||
|
|
||||||
|
bool doesWantAllIntersections() const { return _flags[PICK_ALL_INTERSECTIONS]; }
|
||||||
|
|
||||||
|
// Helpers for RayPickManager
|
||||||
|
Flags getEntityFlags() const {
|
||||||
|
Flags toReturn(PICK_ENTITIES);
|
||||||
|
if (doesPickInvisible()) {
|
||||||
|
toReturn |= Flags(PICK_INCLUDE_INVISIBLE);
|
||||||
|
}
|
||||||
|
if (doesPickNonCollidable()) {
|
||||||
|
toReturn |= Flags(PICK_INCLUDE_NONCOLLIDABLE);
|
||||||
|
}
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
Flags getOverlayFlags() const {
|
||||||
|
Flags toReturn(PICK_OVERLAYS);
|
||||||
|
if (doesPickInvisible()) {
|
||||||
|
toReturn |= Flags(PICK_INCLUDE_INVISIBLE);
|
||||||
|
}
|
||||||
|
if (doesPickNonCollidable()) {
|
||||||
|
toReturn |= Flags(PICK_INCLUDE_NONCOLLIDABLE);
|
||||||
|
}
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
Flags getAvatarFlags() const { return Flags(PICK_AVATARS); }
|
||||||
|
Flags getHUDFlags() const { return Flags(PICK_HUD); }
|
||||||
|
|
||||||
|
static unsigned int getBitMask(FlagBit bit) { return 1 << bit; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class RayPick {
|
class RayPick {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RayPick(const uint16_t filter, const float maxDistance, const bool enabled);
|
RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled);
|
||||||
|
|
||||||
virtual const PickRay getPickRay(bool& valid) const = 0;
|
virtual const PickRay getPickRay(bool& valid) const = 0;
|
||||||
|
|
||||||
void enable() { _enabled = true; }
|
void enable() { _enabled = true; }
|
||||||
void disable() { _enabled = false; }
|
void disable() { _enabled = false; }
|
||||||
|
|
||||||
const uint16_t& getFilter() { return _filter; }
|
const RayPickFilter& getFilter() { return _filter; }
|
||||||
const float& getMaxDistance() { return _maxDistance; }
|
const float& getMaxDistance() { return _maxDistance; }
|
||||||
const bool& isEnabled() { return _enabled; }
|
const bool& isEnabled() { return _enabled; }
|
||||||
const RayPickResult& getPrevRayPickResult() { return _prevResult; }
|
const RayPickResult& getPrevRayPickResult() { return _prevResult; }
|
||||||
|
@ -48,7 +118,7 @@ public:
|
||||||
void setIncludeAvatars(const QScriptValue& includeAvatars) { _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); }
|
void setIncludeAvatars(const QScriptValue& includeAvatars) { _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t _filter;
|
RayPickFilter _filter;
|
||||||
float _maxDistance;
|
float _maxDistance;
|
||||||
bool _enabled;
|
bool _enabled;
|
||||||
RayPickResult _prevResult;
|
RayPickResult _prevResult;
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
//
|
//
|
||||||
#include "RayPickManager.h"
|
#include "RayPickManager.h"
|
||||||
|
|
||||||
#include "RayPick.h"
|
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "EntityScriptingInterface.h"
|
#include "EntityScriptingInterface.h"
|
||||||
#include "ui/overlays/Overlays.h"
|
#include "ui/overlays/Overlays.h"
|
||||||
|
@ -23,8 +21,8 @@
|
||||||
#include "StaticRayPick.h"
|
#include "StaticRayPick.h"
|
||||||
#include "MouseRayPick.h"
|
#include "MouseRayPick.h"
|
||||||
|
|
||||||
bool RayPickManager::checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, unsigned int mask) {
|
bool RayPickManager::checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, const RayPickFilter::Flags& mask) {
|
||||||
if (cache.contains(ray) && cache[ray].contains(mask)) {
|
if (cache.contains(ray) && cache[ray].find(mask) != cache[ray].end()) {
|
||||||
if (cache[ray][mask].distance < res.distance) {
|
if (cache[ray][mask].distance < res.distance) {
|
||||||
res = cache[ray][mask];
|
res = cache[ray][mask];
|
||||||
}
|
}
|
||||||
|
@ -33,7 +31,7 @@ bool RayPickManager::checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& r
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::cacheResult(const bool intersects, const RayPickResult& resTemp, unsigned int mask, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache) {
|
void RayPickManager::cacheResult(const bool intersects, const RayPickResult& resTemp, const RayPickFilter::Flags& mask, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache) {
|
||||||
if (intersects) {
|
if (intersects) {
|
||||||
cache[ray][mask] = resTemp;
|
cache[ray][mask] = resTemp;
|
||||||
if (resTemp.distance < res.distance) {
|
if (resTemp.distance < res.distance) {
|
||||||
|
@ -48,7 +46,7 @@ void RayPickManager::update() {
|
||||||
RayPickCache results;
|
RayPickCache results;
|
||||||
for (auto& uid : _rayPicks.keys()) {
|
for (auto& uid : _rayPicks.keys()) {
|
||||||
std::shared_ptr<RayPick> rayPick = _rayPicks[uid];
|
std::shared_ptr<RayPick> rayPick = _rayPicks[uid];
|
||||||
if (!rayPick->isEnabled() || rayPick->getFilter() == RayPickMask::PICK_NOTHING || rayPick->getMaxDistance() < 0.0f) {
|
if (!rayPick->isEnabled() || rayPick->getFilter().doesPickNothing() || rayPick->getMaxDistance() < 0.0f) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,12 +60,12 @@ void RayPickManager::update() {
|
||||||
QPair<glm::vec3, glm::vec3> rayKey = QPair<glm::vec3, glm::vec3>(ray.origin, ray.direction);
|
QPair<glm::vec3, glm::vec3> rayKey = QPair<glm::vec3, glm::vec3>(ray.origin, ray.direction);
|
||||||
RayPickResult res;
|
RayPickResult res;
|
||||||
|
|
||||||
if (rayPick->getFilter() & RayPickMask::PICK_ENTITIES) {
|
if (rayPick->getFilter().doesPickEntities()) {
|
||||||
RayToEntityIntersectionResult entityRes;
|
RayToEntityIntersectionResult entityRes;
|
||||||
bool fromCache = true;
|
bool fromCache = true;
|
||||||
unsigned int invisible = rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE;
|
bool invisible = rayPick->getFilter().doesPickInvisible();
|
||||||
unsigned int noncollidable = rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE;
|
bool noncollidable = rayPick->getFilter().doesPickNonCollidable();
|
||||||
unsigned int entityMask = RayPickMask::PICK_ENTITIES | invisible | noncollidable;
|
RayPickFilter::Flags entityMask = rayPick->getFilter().getEntityFlags();
|
||||||
if (!checkAndCompareCachedResults(rayKey, results, res, entityMask)) {
|
if (!checkAndCompareCachedResults(rayKey, results, res, entityMask)) {
|
||||||
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, rayPick->getIncludeEntites(), rayPick->getIgnoreEntites(), !invisible, !noncollidable);
|
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, rayPick->getIncludeEntites(), rayPick->getIgnoreEntites(), !invisible, !noncollidable);
|
||||||
fromCache = false;
|
fromCache = false;
|
||||||
|
@ -79,12 +77,12 @@ void RayPickManager::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rayPick->getFilter() & RayPickMask::PICK_OVERLAYS) {
|
if (rayPick->getFilter().doesPickOverlays()) {
|
||||||
RayToOverlayIntersectionResult overlayRes;
|
RayToOverlayIntersectionResult overlayRes;
|
||||||
bool fromCache = true;
|
bool fromCache = true;
|
||||||
unsigned int invisible = rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE;
|
bool invisible = rayPick->getFilter().doesPickInvisible();
|
||||||
unsigned int noncollidable = rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE;
|
bool noncollidable = rayPick->getFilter().doesPickNonCollidable();
|
||||||
unsigned int overlayMask = RayPickMask::PICK_OVERLAYS | invisible | noncollidable;
|
RayPickFilter::Flags overlayMask = rayPick->getFilter().getOverlayFlags();
|
||||||
if (!checkAndCompareCachedResults(rayKey, results, res, overlayMask)) {
|
if (!checkAndCompareCachedResults(rayKey, results, res, overlayMask)) {
|
||||||
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, rayPick->getIncludeOverlays(), rayPick->getIgnoreOverlays(), !invisible, !noncollidable);
|
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, rayPick->getIncludeOverlays(), rayPick->getIgnoreOverlays(), !invisible, !noncollidable);
|
||||||
fromCache = false;
|
fromCache = false;
|
||||||
|
@ -96,22 +94,24 @@ void RayPickManager::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rayPick->getFilter() & RayPickMask::PICK_AVATARS) {
|
if (rayPick->getFilter().doesPickAvatars()) {
|
||||||
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_AVATARS)) {
|
RayPickFilter::Flags avatarMask = rayPick->getFilter().getAvatarFlags();
|
||||||
|
if (!checkAndCompareCachedResults(rayKey, results, res, avatarMask)) {
|
||||||
RayToAvatarIntersectionResult avatarRes = DependencyManager::get<AvatarManager>()->findRayIntersection(ray, rayPick->getIncludeAvatars(), rayPick->getIgnoreAvatars());
|
RayToAvatarIntersectionResult avatarRes = DependencyManager::get<AvatarManager>()->findRayIntersection(ray, rayPick->getIncludeAvatars(), rayPick->getIgnoreAvatars());
|
||||||
cacheResult(avatarRes.intersects, RayPickResult(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection), RayPickMask::PICK_AVATARS, res, rayKey, results);
|
cacheResult(avatarRes.intersects, RayPickResult(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection), avatarMask, res, rayKey, results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't intersect with HUD in desktop mode
|
// Can't intersect with HUD in desktop mode
|
||||||
if (rayPick->getFilter() & RayPickMask::PICK_HUD && DependencyManager::get<HMDScriptingInterface>()->isHMDMode()) {
|
if (rayPick->getFilter().doesPickHUD() && DependencyManager::get<HMDScriptingInterface>()->isHMDMode()) {
|
||||||
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_HUD)) {
|
RayPickFilter::Flags hudMask = rayPick->getFilter().getHUDFlags();
|
||||||
|
if (!checkAndCompareCachedResults(rayKey, results, res, hudMask)) {
|
||||||
glm::vec3 hudRes = DependencyManager::get<HMDScriptingInterface>()->calculateRayUICollisionPoint(ray.origin, ray.direction);
|
glm::vec3 hudRes = DependencyManager::get<HMDScriptingInterface>()->calculateRayUICollisionPoint(ray.origin, ray.direction);
|
||||||
cacheResult(true, RayPickResult(IntersectionType::HUD, 0, glm::distance(ray.origin, hudRes), hudRes), RayPickMask::PICK_HUD, res, rayKey, results);
|
cacheResult(true, RayPickResult(IntersectionType::HUD, 0, glm::distance(ray.origin, hudRes), hudRes), hudMask, res, rayKey, results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
WriteLock lock(*_rayPickLocks[uid]);
|
||||||
if (rayPick->getMaxDistance() == 0.0f || (rayPick->getMaxDistance() > 0.0f && res.distance < rayPick->getMaxDistance())) {
|
if (rayPick->getMaxDistance() == 0.0f || (rayPick->getMaxDistance() > 0.0f && res.distance < rayPick->getMaxDistance())) {
|
||||||
rayPick->setRayPickResult(res);
|
rayPick->setRayPickResult(res);
|
||||||
} else {
|
} else {
|
||||||
|
@ -119,20 +119,22 @@ void RayPickManager::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QWriteLocker containsLock(&_containsLock);
|
WriteLock containsLock(_containsLock);
|
||||||
{
|
{
|
||||||
QWriteLocker lock(&_addLock);
|
WriteLock lock(_addLock);
|
||||||
while (!_rayPicksToAdd.isEmpty()) {
|
while (!_rayPicksToAdd.empty()) {
|
||||||
QPair<QUuid, std::shared_ptr<RayPick>> rayPickToAdd = _rayPicksToAdd.dequeue();
|
std::pair<QUuid, std::shared_ptr<RayPick>> rayPickToAdd = _rayPicksToAdd.front();
|
||||||
|
_rayPicksToAdd.pop();
|
||||||
_rayPicks[rayPickToAdd.first] = rayPickToAdd.second;
|
_rayPicks[rayPickToAdd.first] = rayPickToAdd.second;
|
||||||
_rayPickLocks[rayPickToAdd.first] = std::make_shared<QReadWriteLock>();
|
_rayPickLocks[rayPickToAdd.first] = std::make_shared<std::shared_mutex>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
QWriteLocker lock(&_removeLock);
|
WriteLock lock(_removeLock);
|
||||||
while (!_rayPicksToRemove.isEmpty()) {
|
while (!_rayPicksToRemove.empty()) {
|
||||||
QUuid uid = _rayPicksToRemove.dequeue();
|
QUuid uid = _rayPicksToRemove.front();
|
||||||
|
_rayPicksToRemove.pop();
|
||||||
_rayPicks.remove(uid);
|
_rayPicks.remove(uid);
|
||||||
_rayPickLocks.remove(uid);
|
_rayPickLocks.remove(uid);
|
||||||
}
|
}
|
||||||
|
@ -145,9 +147,9 @@ QUuid RayPickManager::createRayPick(const QVariantMap& rayProps) {
|
||||||
enabled = rayProps["enabled"].toBool();
|
enabled = rayProps["enabled"].toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t filter = 0;
|
RayPickFilter filter = RayPickFilter();
|
||||||
if (rayProps["filter"].isValid()) {
|
if (rayProps["filter"].isValid()) {
|
||||||
filter = rayProps["filter"].toUInt();
|
filter = RayPickFilter(rayProps["filter"].toUInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
float maxDistance = 0.0f;
|
float maxDistance = 0.0f;
|
||||||
|
@ -156,7 +158,7 @@ QUuid RayPickManager::createRayPick(const QVariantMap& rayProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rayProps["joint"].isValid()) {
|
if (rayProps["joint"].isValid()) {
|
||||||
QString jointName = rayProps["joint"].toString();
|
std::string jointName = rayProps["joint"].toString().toStdString();
|
||||||
|
|
||||||
if (jointName != "Mouse") {
|
if (jointName != "Mouse") {
|
||||||
// x = upward, y = forward, z = lateral
|
// x = upward, y = forward, z = lateral
|
||||||
|
@ -170,14 +172,14 @@ QUuid RayPickManager::createRayPick(const QVariantMap& rayProps) {
|
||||||
dirOffset = vec3FromVariant(rayProps["dirOffset"]);
|
dirOffset = vec3FromVariant(rayProps["dirOffset"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWriteLocker lock(&_addLock);
|
WriteLock lock(_addLock);
|
||||||
QUuid id = QUuid::createUuid();
|
QUuid id = QUuid::createUuid();
|
||||||
_rayPicksToAdd.enqueue(QPair<QUuid, std::shared_ptr<RayPick>>(id, std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled)));
|
_rayPicksToAdd.push(std::pair<QUuid, std::shared_ptr<RayPick>>(id, std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled)));
|
||||||
return id;
|
return id;
|
||||||
} else {
|
} else {
|
||||||
QWriteLocker lock(&_addLock);
|
WriteLock lock(_addLock);
|
||||||
QUuid id = QUuid::createUuid();
|
QUuid id = QUuid::createUuid();
|
||||||
_rayPicksToAdd.enqueue(QPair<QUuid, std::shared_ptr<RayPick>>(id, std::make_shared<MouseRayPick>(filter, maxDistance, enabled)));
|
_rayPicksToAdd.push(std::pair<QUuid, std::shared_ptr<RayPick>>(id, std::make_shared<MouseRayPick>(filter, maxDistance, enabled)));
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
} else if (rayProps["position"].isValid()) {
|
} else if (rayProps["position"].isValid()) {
|
||||||
|
@ -188,9 +190,9 @@ QUuid RayPickManager::createRayPick(const QVariantMap& rayProps) {
|
||||||
direction = vec3FromVariant(rayProps["direction"]);
|
direction = vec3FromVariant(rayProps["direction"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWriteLocker lock(&_addLock);
|
WriteLock lock(_addLock);
|
||||||
QUuid id = QUuid::createUuid();
|
QUuid id = QUuid::createUuid();
|
||||||
_rayPicksToAdd.enqueue(QPair<QUuid, std::shared_ptr<RayPick>>(id, std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled)));
|
_rayPicksToAdd.push(std::pair<QUuid, std::shared_ptr<RayPick>>(id, std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled)));
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,28 +200,28 @@ QUuid RayPickManager::createRayPick(const QVariantMap& rayProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::removeRayPick(const QUuid uid) {
|
void RayPickManager::removeRayPick(const QUuid uid) {
|
||||||
QWriteLocker lock(&_removeLock);
|
WriteLock lock(_removeLock);
|
||||||
_rayPicksToRemove.enqueue(uid);
|
_rayPicksToRemove.push(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::enableRayPick(const QUuid uid) {
|
void RayPickManager::enableRayPick(const QUuid uid) {
|
||||||
QReadLocker containsLock(&_containsLock);
|
ReadLock containsLock(_containsLock);
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
QWriteLocker rayPickLock(_rayPickLocks[uid].get());
|
WriteLock rayPickLock(*_rayPickLocks[uid]);
|
||||||
_rayPicks[uid]->enable();
|
_rayPicks[uid]->enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::disableRayPick(const QUuid uid) {
|
void RayPickManager::disableRayPick(const QUuid uid) {
|
||||||
QReadLocker containsLock(&_containsLock);
|
ReadLock containsLock(_containsLock);
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
QWriteLocker rayPickLock(_rayPickLocks[uid].get());
|
WriteLock rayPickLock(*_rayPickLocks[uid]);
|
||||||
_rayPicks[uid]->disable();
|
_rayPicks[uid]->disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const PickRay RayPickManager::getPickRay(const QUuid uid) {
|
const PickRay RayPickManager::getPickRay(const QUuid uid) {
|
||||||
QReadLocker containsLock(&_containsLock);
|
ReadLock containsLock(_containsLock);
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
bool valid;
|
bool valid;
|
||||||
PickRay pickRay = _rayPicks[uid]->getPickRay(valid);
|
PickRay pickRay = _rayPicks[uid]->getPickRay(valid);
|
||||||
|
@ -231,58 +233,58 @@ const PickRay RayPickManager::getPickRay(const QUuid uid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) {
|
const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) {
|
||||||
QReadLocker containsLock(&_containsLock);
|
ReadLock containsLock(_containsLock);
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
QReadLocker lock(_rayPickLocks[uid].get());
|
ReadLock lock(*_rayPickLocks[uid]);
|
||||||
return _rayPicks[uid]->getPrevRayPickResult();
|
return _rayPicks[uid]->getPrevRayPickResult();
|
||||||
}
|
}
|
||||||
return RayPickResult();
|
return RayPickResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
|
void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
|
||||||
QReadLocker containsLock(&_containsLock);
|
ReadLock containsLock(_containsLock);
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
WriteLock lock(*_rayPickLocks[uid]);
|
||||||
_rayPicks[uid]->setIgnoreEntities(ignoreEntities);
|
_rayPicks[uid]->setIgnoreEntities(ignoreEntities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
|
void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
|
||||||
QReadLocker containsLock(&_containsLock);
|
ReadLock containsLock(_containsLock);
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
WriteLock lock(*_rayPickLocks[uid]);
|
||||||
_rayPicks[uid]->setIncludeEntities(includeEntities);
|
_rayPicks[uid]->setIncludeEntities(includeEntities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
|
void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
|
||||||
QReadLocker containsLock(&_containsLock);
|
ReadLock containsLock(_containsLock);
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
WriteLock lock(*_rayPickLocks[uid]);
|
||||||
_rayPicks[uid]->setIgnoreOverlays(ignoreOverlays);
|
_rayPicks[uid]->setIgnoreOverlays(ignoreOverlays);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
|
void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
|
||||||
QReadLocker containsLock(&_containsLock);
|
ReadLock containsLock(_containsLock);
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
WriteLock lock(*_rayPickLocks[uid]);
|
||||||
_rayPicks[uid]->setIncludeOverlays(includeOverlays);
|
_rayPicks[uid]->setIncludeOverlays(includeOverlays);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
|
void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
|
||||||
QReadLocker containsLock(&_containsLock);
|
ReadLock containsLock(_containsLock);
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
WriteLock lock(*_rayPickLocks[uid]);
|
||||||
_rayPicks[uid]->setIgnoreAvatars(ignoreAvatars);
|
_rayPicks[uid]->setIgnoreAvatars(ignoreAvatars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
|
void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
|
||||||
QReadLocker containsLock(&_containsLock);
|
ReadLock containsLock(_containsLock);
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
WriteLock lock(*_rayPickLocks[uid]);
|
||||||
_rayPicks[uid]->setIncludeAvatars(includeAvatars);
|
_rayPicks[uid]->setIncludeAvatars(includeAvatars);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,35 +11,20 @@
|
||||||
#ifndef hifi_RayPickManager_h
|
#ifndef hifi_RayPickManager_h
|
||||||
#define hifi_RayPickManager_h
|
#define hifi_RayPickManager_h
|
||||||
|
|
||||||
#include <QHash>
|
#include "RayPick.h"
|
||||||
#include <QQueue>
|
|
||||||
#include <QReadWriteLock>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
#include "RegisteredMetaTypes.h"
|
#include "RegisteredMetaTypes.h"
|
||||||
#include "DependencyManager.h"
|
#include "DependencyManager.h"
|
||||||
|
|
||||||
class RayPick;
|
#include <unordered_map>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
class RayPickResult;
|
class RayPickResult;
|
||||||
|
|
||||||
enum RayPickMask {
|
|
||||||
PICK_NOTHING = 0,
|
|
||||||
PICK_ENTITIES = 1 << 0,
|
|
||||||
PICK_OVERLAYS = 1 << 1,
|
|
||||||
PICK_AVATARS = 1 << 2,
|
|
||||||
PICK_HUD = 1 << 3,
|
|
||||||
|
|
||||||
// NOT YET IMPLEMENTED
|
|
||||||
PICK_BOUNDING_BOX = 1 << 4, // if not set, picks again physics mesh (can't pick against graphics mesh, yet)
|
|
||||||
|
|
||||||
PICK_INCLUDE_INVISIBLE = 1 << 5, // if not set, will not intersect invisible elements, otherwise, intersects both visible and invisible elements
|
|
||||||
PICK_INCLUDE_NONCOLLIDABLE = 1 << 6, // if not set, will not intersect noncollidable elements, otherwise, intersects both collidable and noncollidable elements
|
|
||||||
|
|
||||||
// NOT YET IMPLEMENTED
|
|
||||||
PICK_ALL_INTERSECTIONS = 1 << 7 // if not set, returns closest intersection, otherwise, returns list of all intersections
|
|
||||||
};
|
|
||||||
|
|
||||||
class RayPickManager : public QObject, public Dependency {
|
class RayPickManager : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(unsigned int PICK_NOTHING READ PICK_NOTHING CONSTANT)
|
Q_PROPERTY(unsigned int PICK_NOTHING READ PICK_NOTHING CONSTANT)
|
||||||
|
@ -78,34 +63,37 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<QUuid, std::shared_ptr<RayPick>> _rayPicks;
|
QHash<QUuid, std::shared_ptr<RayPick>> _rayPicks;
|
||||||
QHash<QUuid, std::shared_ptr<QReadWriteLock>> _rayPickLocks;
|
QHash<QUuid, std::shared_ptr<std::shared_mutex>> _rayPickLocks;
|
||||||
QReadWriteLock _addLock;
|
std::shared_mutex _addLock;
|
||||||
QQueue<QPair<QUuid, std::shared_ptr<RayPick>>> _rayPicksToAdd;
|
std::queue<std::pair<QUuid, std::shared_ptr<RayPick>>> _rayPicksToAdd;
|
||||||
QReadWriteLock _removeLock;
|
std::shared_mutex _removeLock;
|
||||||
QQueue<QUuid> _rayPicksToRemove;
|
std::queue<QUuid> _rayPicksToRemove;
|
||||||
QReadWriteLock _containsLock;
|
std::shared_mutex _containsLock;
|
||||||
|
|
||||||
typedef QHash<QPair<glm::vec3, glm::vec3>, QHash<unsigned int, RayPickResult>> RayPickCache;
|
typedef QHash<QPair<glm::vec3, glm::vec3>, std::unordered_map<RayPickFilter::Flags, RayPickResult>> RayPickCache;
|
||||||
|
|
||||||
// Returns true if this ray exists in the cache, and if it does, update res if the cached result is closer
|
// 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, unsigned int mask);
|
bool checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, const RayPickFilter::Flags& mask);
|
||||||
void cacheResult(const bool intersects, const RayPickResult& resTemp, unsigned int mask, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache);
|
void cacheResult(const bool intersects, const RayPickResult& resTemp, const RayPickFilter::Flags& mask, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache);
|
||||||
|
|
||||||
unsigned int PICK_NOTHING() { return RayPickMask::PICK_NOTHING; }
|
unsigned int PICK_NOTHING() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_NOTHING); }
|
||||||
unsigned int PICK_ENTITIES() { return RayPickMask::PICK_ENTITIES; }
|
unsigned int PICK_ENTITIES() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_ENTITIES); }
|
||||||
unsigned int PICK_OVERLAYS() { return RayPickMask::PICK_OVERLAYS; }
|
unsigned int PICK_OVERLAYS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_OVERLAYS); }
|
||||||
unsigned int PICK_AVATARS() { return RayPickMask::PICK_AVATARS; }
|
unsigned int PICK_AVATARS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_AVATARS); }
|
||||||
unsigned int PICK_HUD() { return RayPickMask::PICK_HUD; }
|
unsigned int PICK_HUD() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_HUD); }
|
||||||
unsigned int PICK_BOUNDING_BOX() { return RayPickMask::PICK_BOUNDING_BOX; }
|
unsigned int PICK_BOUNDING_BOX() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_COURSE); }
|
||||||
unsigned int PICK_INCLUDE_INVISIBLE() { return RayPickMask::PICK_INCLUDE_INVISIBLE; }
|
unsigned int PICK_INCLUDE_INVISIBLE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_INCLUDE_INVISIBLE); }
|
||||||
unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return RayPickMask::PICK_INCLUDE_NONCOLLIDABLE; }
|
unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_INCLUDE_NONCOLLIDABLE); }
|
||||||
unsigned int PICK_ALL_INTERSECTIONS() { return RayPickMask::PICK_ALL_INTERSECTIONS; }
|
unsigned int PICK_ALL_INTERSECTIONS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_ALL_INTERSECTIONS); }
|
||||||
unsigned int INTERSECTED_NONE() { return IntersectionType::NONE; }
|
unsigned int INTERSECTED_NONE() { return IntersectionType::NONE; }
|
||||||
unsigned int INTERSECTED_ENTITY() { return IntersectionType::ENTITY; }
|
unsigned int INTERSECTED_ENTITY() { return IntersectionType::ENTITY; }
|
||||||
unsigned int INTERSECTED_OVERLAY() { return IntersectionType::OVERLAY; }
|
unsigned int INTERSECTED_OVERLAY() { return IntersectionType::OVERLAY; }
|
||||||
unsigned int INTERSECTED_AVATAR() { return IntersectionType::AVATAR; }
|
unsigned int INTERSECTED_AVATAR() { return IntersectionType::AVATAR; }
|
||||||
unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; }
|
unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; }
|
||||||
|
|
||||||
|
typedef std::lock_guard<std::shared_mutex> WriteLock;
|
||||||
|
typedef std::shared_lock<std::shared_mutex> ReadLock;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_RayPickManager_h
|
#endif // hifi_RayPickManager_h
|
|
@ -10,7 +10,7 @@
|
||||||
//
|
//
|
||||||
#include "StaticRayPick.h"
|
#include "StaticRayPick.h"
|
||||||
|
|
||||||
StaticRayPick::StaticRayPick(const glm::vec3& position, const glm::vec3& direction, const uint16_t filter, const float maxDistance, const bool enabled) :
|
StaticRayPick::StaticRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance, const bool enabled) :
|
||||||
RayPick(filter, maxDistance, enabled),
|
RayPick(filter, maxDistance, enabled),
|
||||||
_pickRay(position, direction)
|
_pickRay(position, direction)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
class StaticRayPick : public RayPick {
|
class StaticRayPick : public RayPick {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StaticRayPick(const glm::vec3& position, const glm::vec3& direction, const uint16_t filter, const float maxDistance = 0.0f, const bool enabled = false);
|
StaticRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance = 0.0f, const bool enabled = false);
|
||||||
|
|
||||||
const PickRay getPickRay(bool& valid) const override;
|
const PickRay getPickRay(bool& valid) const override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue