mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 18:55:01 +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 "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),
|
||||
_jointName(jointName),
|
||||
_posOffset(posOffset),
|
||||
|
@ -23,7 +23,7 @@ JointRayPick::JointRayPick(const QString& jointName, const glm::vec3& posOffset,
|
|||
|
||||
const PickRay JointRayPick::getPickRay(bool& valid) const {
|
||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
int jointIndex = myAvatar->getJointIndex(_jointName);
|
||||
int jointIndex = myAvatar->getJointIndex(QString::fromStdString(_jointName));
|
||||
bool useAvatarHead = _jointName == "Avatar";
|
||||
const int INVALID_JOINT = -1;
|
||||
if (jointIndex != INVALID_JOINT || useAvatarHead) {
|
||||
|
|
|
@ -13,17 +13,15 @@
|
|||
|
||||
#include "RayPick.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class JointRayPick : public RayPick {
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
QString _jointName;
|
||||
std::string _jointName;
|
||||
glm::vec3 _posOffset;
|
||||
glm::vec3 _dirOffset;
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "Application.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) :
|
||||
_renderingEnabled(enabled),
|
||||
_renderStates(renderStates),
|
||||
|
@ -24,14 +24,14 @@ LaserPointer::LaserPointer(const QVariantMap& rayProps, const QHash<QString, Ren
|
|||
{
|
||||
_rayPickUID = DependencyManager::get<RayPickManager>()->createRayPick(rayProps);
|
||||
|
||||
for (QString& state : _renderStates.keys()) {
|
||||
if (!enabled || state != _currentRenderState) {
|
||||
disableRenderState(_renderStates[state]);
|
||||
for (auto& state : _renderStates) {
|
||||
if (!enabled || state.first != _currentRenderState) {
|
||||
disableRenderState(state.second);
|
||||
}
|
||||
}
|
||||
for (QString& state : _defaultRenderStates.keys()) {
|
||||
if (!enabled || state != _currentRenderState) {
|
||||
disableRenderState(_defaultRenderStates[state].second);
|
||||
for (auto& state : _defaultRenderStates) {
|
||||
if (!enabled || state.first != _currentRenderState) {
|
||||
disableRenderState(state.second.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,12 +39,12 @@ LaserPointer::LaserPointer(const QVariantMap& rayProps, const QHash<QString, Ren
|
|||
LaserPointer::~LaserPointer() {
|
||||
DependencyManager::get<RayPickManager>()->removeRayPick(_rayPickUID);
|
||||
|
||||
for (RenderState& renderState : _renderStates) {
|
||||
renderState.deleteOverlays();
|
||||
}
|
||||
for (QPair<float, RenderState>& renderState : _defaultRenderStates) {
|
||||
for (auto& renderState : _renderStates) {
|
||||
renderState.second.deleteOverlays();
|
||||
}
|
||||
for (auto& renderState : _defaultRenderStates) {
|
||||
renderState.second.second.deleteOverlays();
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointer::enable() {
|
||||
|
@ -55,29 +55,29 @@ void LaserPointer::enable() {
|
|||
void LaserPointer::disable() {
|
||||
DependencyManager::get<RayPickManager>()->disableRayPick(_rayPickUID);
|
||||
_renderingEnabled = false;
|
||||
if (!_currentRenderState.isEmpty()) {
|
||||
if (_renderStates.contains(_currentRenderState)) {
|
||||
if (!_currentRenderState.empty()) {
|
||||
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
|
||||
disableRenderState(_renderStates[_currentRenderState]);
|
||||
}
|
||||
if (_defaultRenderStates.contains(_currentRenderState)) {
|
||||
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
|
||||
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointer::setRenderState(const QString& state) {
|
||||
if (!_currentRenderState.isEmpty() && state != _currentRenderState) {
|
||||
if (_renderStates.contains(_currentRenderState)) {
|
||||
void LaserPointer::setRenderState(const std::string& state) {
|
||||
if (!_currentRenderState.empty() && state != _currentRenderState) {
|
||||
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
|
||||
disableRenderState(_renderStates[_currentRenderState]);
|
||||
}
|
||||
if (_defaultRenderStates.contains(_currentRenderState)) {
|
||||
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
|
||||
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
||||
}
|
||||
}
|
||||
_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].getPathID(), pathProps);
|
||||
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
|
||||
|
@ -181,13 +181,13 @@ void LaserPointer::disableRenderState(const RenderState& renderState) {
|
|||
|
||||
void LaserPointer::update() {
|
||||
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);
|
||||
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]);
|
||||
updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), true);
|
||||
} else if (!_currentRenderState.isEmpty()) {
|
||||
} else if (!_currentRenderState.empty()) {
|
||||
disableRenderState(_renderStates[_currentRenderState]);
|
||||
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,11 @@ private:
|
|||
class LaserPointer {
|
||||
|
||||
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);
|
||||
~LaserPointer();
|
||||
|
||||
|
@ -57,9 +61,9 @@ public:
|
|||
void disable();
|
||||
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.
|
||||
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 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 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();
|
||||
|
||||
private:
|
||||
bool _renderingEnabled;
|
||||
QString _currentRenderState { "" };
|
||||
QHash<QString, RenderState> _renderStates;
|
||||
QHash<QString, QPair<float, RenderState>> _defaultRenderStates;
|
||||
std::string _currentRenderState { "" };
|
||||
RenderStateMap _renderStates;
|
||||
DefaultRenderStateMap _defaultRenderStates;
|
||||
bool _faceAvatar;
|
||||
bool _centerEndY;
|
||||
bool _lockEnd;
|
||||
QPair<QUuid, bool> _objectLockEnd { QPair<QUuid, bool>(QUuid(), false)};
|
||||
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
|
||||
|
||||
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 bool defaultState);
|
||||
void disableRenderState(const RenderState& renderState);
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_LaserPointer_h
|
||||
|
|
|
@ -11,85 +11,87 @@
|
|||
#include "LaserPointerManager.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) {
|
||||
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled);
|
||||
if (!laserPointer->getRayUID().isNull()) {
|
||||
QWriteLocker lock(&_addLock);
|
||||
WriteLock lock(_addLock);
|
||||
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 QUuid();
|
||||
}
|
||||
|
||||
void LaserPointerManager::removeLaserPointer(const QUuid uid) {
|
||||
QWriteLocker lock(&_removeLock);
|
||||
_laserPointersToRemove.enqueue(uid);
|
||||
WriteLock lock(_removeLock);
|
||||
_laserPointersToRemove.push(uid);
|
||||
}
|
||||
|
||||
void LaserPointerManager::enableLaserPointer(const QUuid uid) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->enable();
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::disableLaserPointer(const QUuid uid) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->disable();
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setRenderState(QUuid uid, const QString & renderState) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderState) {
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->setRenderState(renderState);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::editRenderState(QUuid uid, const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->editRenderState(state, startProps, pathProps, endProps);
|
||||
}
|
||||
}
|
||||
|
||||
const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QReadLocker laserLock(_laserPointerLocks[uid].get());
|
||||
ReadLock laserLock(*_laserPointerLocks[uid]);
|
||||
return _laserPointers[uid]->getPrevRayPickResult();
|
||||
}
|
||||
return RayPickResult();
|
||||
}
|
||||
|
||||
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
|
||||
QReadLocker laserLock(_laserPointerLocks[uid].get());
|
||||
ReadLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->update();
|
||||
}
|
||||
|
||||
QWriteLocker containsLock(&_containsLock);
|
||||
WriteLock containsLock(_containsLock);
|
||||
{
|
||||
QWriteLocker lock(&_addLock);
|
||||
while (!_laserPointersToAdd.isEmpty()) {
|
||||
QPair<QUuid, std::shared_ptr<LaserPointer>> laserPointerToAdd = _laserPointersToAdd.dequeue();
|
||||
WriteLock lock(_addLock);
|
||||
while (!_laserPointersToAdd.empty()) {
|
||||
std::pair<QUuid, std::shared_ptr<LaserPointer>> laserPointerToAdd = _laserPointersToAdd.front();
|
||||
_laserPointersToAdd.pop();
|
||||
_laserPointers[laserPointerToAdd.first] = laserPointerToAdd.second;
|
||||
_laserPointerLocks[laserPointerToAdd.first] = std::make_shared<QReadWriteLock>();
|
||||
_laserPointerLocks[laserPointerToAdd.first] = std::make_shared<std::shared_mutex>();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
QWriteLocker lock(&_removeLock);
|
||||
while (!_laserPointersToRemove.isEmpty()) {
|
||||
QUuid uid = _laserPointersToRemove.dequeue();
|
||||
WriteLock lock(_removeLock);
|
||||
while (!_laserPointersToRemove.empty()) {
|
||||
QUuid uid = _laserPointersToRemove.front();
|
||||
_laserPointersToRemove.pop();
|
||||
_laserPointers.remove(uid);
|
||||
_laserPointerLocks.remove(uid);
|
||||
}
|
||||
|
@ -97,57 +99,57 @@ void LaserPointerManager::update() {
|
|||
}
|
||||
|
||||
void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->setIgnoreEntities(ignoreEntities);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->setIncludeEntities(includeEntities);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->setIgnoreOverlays(ignoreOverlays);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->setIncludeOverlays(includeOverlays);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->setIgnoreAvatars(ignoreAvatars);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->setIncludeAvatars(includeAvatars);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
ReadLock lock(_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
WriteLock laserLock(*_laserPointerLocks[uid]);
|
||||
_laserPointers[uid]->setLockEndUUID(objectID, isOverlay);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,8 @@
|
|||
#ifndef hifi_LaserPointerManager_h
|
||||
#define hifi_LaserPointerManager_h
|
||||
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
#include <memory>
|
||||
#include <shared_mutex>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "LaserPointer.h"
|
||||
|
@ -23,13 +22,13 @@ class RayPickResult;
|
|||
class LaserPointerManager {
|
||||
|
||||
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);
|
||||
void removeLaserPointer(const QUuid uid);
|
||||
void enableLaserPointer(const QUuid uid);
|
||||
void disableLaserPointer(const QUuid uid);
|
||||
void setRenderState(QUuid uid, const QString& renderState);
|
||||
void editRenderState(QUuid uid, const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
|
||||
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 setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities);
|
||||
|
@ -45,12 +44,15 @@ public:
|
|||
|
||||
private:
|
||||
QHash<QUuid, std::shared_ptr<LaserPointer>> _laserPointers;
|
||||
QHash<QUuid, std::shared_ptr<QReadWriteLock>> _laserPointerLocks;
|
||||
QReadWriteLock _addLock;
|
||||
QQueue<QPair<QUuid, std::shared_ptr<LaserPointer>>> _laserPointersToAdd;
|
||||
QReadWriteLock _removeLock;
|
||||
QQueue<QUuid> _laserPointersToRemove;
|
||||
QReadWriteLock _containsLock;
|
||||
QHash<QUuid, std::shared_ptr<std::shared_mutex>> _laserPointerLocks;
|
||||
std::shared_mutex _addLock;
|
||||
std::queue<std::pair<QUuid, std::shared_ptr<LaserPointer>>> _laserPointersToAdd;
|
||||
std::shared_mutex _removeLock;
|
||||
std::queue<QUuid> _laserPointersToRemove;
|
||||
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();
|
||||
}
|
||||
|
||||
QHash<QString, RenderState> renderStates;
|
||||
LaserPointer::RenderStateMap renderStates;
|
||||
if (propertyMap["renderStates"].isValid()) {
|
||||
QList<QVariant> renderStateVariants = propertyMap["renderStates"].toList();
|
||||
for (QVariant& renderStateVariant : renderStateVariants) {
|
||||
if (renderStateVariant.isValid()) {
|
||||
QVariantMap renderStateMap = renderStateVariant.toMap();
|
||||
if (renderStateMap["name"].isValid()) {
|
||||
QString name = renderStateMap["name"].toString();
|
||||
std::string name = renderStateMap["name"].toString().toStdString();
|
||||
renderStates[name] = buildRenderState(renderStateMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, QPair<float, RenderState>> defaultRenderStates;
|
||||
LaserPointer::DefaultRenderStateMap defaultRenderStates;
|
||||
if (propertyMap["defaultRenderStates"].isValid()) {
|
||||
QList<QVariant> renderStateVariants = propertyMap["defaultRenderStates"].toList();
|
||||
for (QVariant& renderStateVariant : renderStateVariants) {
|
||||
if (renderStateVariant.isValid()) {
|
||||
QVariantMap renderStateMap = renderStateVariant.toMap();
|
||||
if (renderStateMap["name"].isValid() && renderStateMap["distance"].isValid()) {
|
||||
QString name = renderStateMap["name"].toString();
|
||||
std::string name = renderStateMap["name"].toString().toStdString();
|
||||
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"];
|
||||
}
|
||||
|
||||
qApp->getLaserPointerManager().editRenderState(uid, renderState, startProps, pathProps, endProps);
|
||||
qApp->getLaserPointerManager().editRenderState(uid, renderState.toStdString(), startProps, pathProps, endProps);
|
||||
}
|
||||
|
||||
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 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); }
|
||||
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 void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { qApp->getLaserPointerManager().setIgnoreEntities(uid, ignoreEntities); }
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "Application.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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
class MouseRayPick : public RayPick {
|
||||
|
||||
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;
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
//
|
||||
#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),
|
||||
_maxDistance(maxDistance),
|
||||
_enabled(enabled)
|
||||
|
|
|
@ -17,17 +17,87 @@
|
|||
#include "EntityItemID.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 {
|
||||
|
||||
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;
|
||||
|
||||
void enable() { _enabled = true; }
|
||||
void disable() { _enabled = false; }
|
||||
|
||||
const uint16_t& getFilter() { return _filter; }
|
||||
const RayPickFilter& getFilter() { return _filter; }
|
||||
const float& getMaxDistance() { return _maxDistance; }
|
||||
const bool& isEnabled() { return _enabled; }
|
||||
const RayPickResult& getPrevRayPickResult() { return _prevResult; }
|
||||
|
@ -48,7 +118,7 @@ public:
|
|||
void setIncludeAvatars(const QScriptValue& includeAvatars) { _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); }
|
||||
|
||||
private:
|
||||
uint16_t _filter;
|
||||
RayPickFilter _filter;
|
||||
float _maxDistance;
|
||||
bool _enabled;
|
||||
RayPickResult _prevResult;
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
//
|
||||
#include "RayPickManager.h"
|
||||
|
||||
#include "RayPick.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "EntityScriptingInterface.h"
|
||||
#include "ui/overlays/Overlays.h"
|
||||
|
@ -23,8 +21,8 @@
|
|||
#include "StaticRayPick.h"
|
||||
#include "MouseRayPick.h"
|
||||
|
||||
bool RayPickManager::checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, unsigned int mask) {
|
||||
if (cache.contains(ray) && cache[ray].contains(mask)) {
|
||||
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];
|
||||
}
|
||||
|
@ -33,7 +31,7 @@ bool RayPickManager::checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& r
|
|||
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) {
|
||||
cache[ray][mask] = resTemp;
|
||||
if (resTemp.distance < res.distance) {
|
||||
|
@ -48,7 +46,7 @@ void RayPickManager::update() {
|
|||
RayPickCache results;
|
||||
for (auto& uid : _rayPicks.keys()) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -62,12 +60,12 @@ void RayPickManager::update() {
|
|||
QPair<glm::vec3, glm::vec3> rayKey = QPair<glm::vec3, glm::vec3>(ray.origin, ray.direction);
|
||||
RayPickResult res;
|
||||
|
||||
if (rayPick->getFilter() & RayPickMask::PICK_ENTITIES) {
|
||||
if (rayPick->getFilter().doesPickEntities()) {
|
||||
RayToEntityIntersectionResult entityRes;
|
||||
bool fromCache = true;
|
||||
unsigned int invisible = rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE;
|
||||
unsigned int noncollidable = rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE;
|
||||
unsigned int entityMask = RayPickMask::PICK_ENTITIES | invisible | noncollidable;
|
||||
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>()->findRayIntersection(ray, true, rayPick->getIncludeEntites(), rayPick->getIgnoreEntites(), !invisible, !noncollidable);
|
||||
fromCache = false;
|
||||
|
@ -79,12 +77,12 @@ void RayPickManager::update() {
|
|||
}
|
||||
}
|
||||
|
||||
if (rayPick->getFilter() & RayPickMask::PICK_OVERLAYS) {
|
||||
if (rayPick->getFilter().doesPickOverlays()) {
|
||||
RayToOverlayIntersectionResult overlayRes;
|
||||
bool fromCache = true;
|
||||
unsigned int invisible = rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE;
|
||||
unsigned int noncollidable = rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE;
|
||||
unsigned int overlayMask = RayPickMask::PICK_OVERLAYS | invisible | noncollidable;
|
||||
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().findRayIntersection(ray, true, rayPick->getIncludeOverlays(), rayPick->getIgnoreOverlays(), !invisible, !noncollidable);
|
||||
fromCache = false;
|
||||
|
@ -96,22 +94,24 @@ void RayPickManager::update() {
|
|||
}
|
||||
}
|
||||
|
||||
if (rayPick->getFilter() & RayPickMask::PICK_AVATARS) {
|
||||
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_AVATARS)) {
|
||||
if (rayPick->getFilter().doesPickAvatars()) {
|
||||
RayPickFilter::Flags avatarMask = rayPick->getFilter().getAvatarFlags();
|
||||
if (!checkAndCompareCachedResults(rayKey, results, res, avatarMask)) {
|
||||
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
|
||||
if (rayPick->getFilter() & RayPickMask::PICK_HUD && DependencyManager::get<HMDScriptingInterface>()->isHMDMode()) {
|
||||
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_HUD)) {
|
||||
if (rayPick->getFilter().doesPickHUD() && DependencyManager::get<HMDScriptingInterface>()->isHMDMode()) {
|
||||
RayPickFilter::Flags hudMask = rayPick->getFilter().getHUDFlags();
|
||||
if (!checkAndCompareCachedResults(rayKey, results, res, hudMask)) {
|
||||
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())) {
|
||||
rayPick->setRayPickResult(res);
|
||||
} else {
|
||||
|
@ -119,20 +119,22 @@ void RayPickManager::update() {
|
|||
}
|
||||
}
|
||||
|
||||
QWriteLocker containsLock(&_containsLock);
|
||||
WriteLock containsLock(_containsLock);
|
||||
{
|
||||
QWriteLocker lock(&_addLock);
|
||||
while (!_rayPicksToAdd.isEmpty()) {
|
||||
QPair<QUuid, std::shared_ptr<RayPick>> rayPickToAdd = _rayPicksToAdd.dequeue();
|
||||
WriteLock lock(_addLock);
|
||||
while (!_rayPicksToAdd.empty()) {
|
||||
std::pair<QUuid, std::shared_ptr<RayPick>> rayPickToAdd = _rayPicksToAdd.front();
|
||||
_rayPicksToAdd.pop();
|
||||
_rayPicks[rayPickToAdd.first] = rayPickToAdd.second;
|
||||
_rayPickLocks[rayPickToAdd.first] = std::make_shared<QReadWriteLock>();
|
||||
_rayPickLocks[rayPickToAdd.first] = std::make_shared<std::shared_mutex>();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
QWriteLocker lock(&_removeLock);
|
||||
while (!_rayPicksToRemove.isEmpty()) {
|
||||
QUuid uid = _rayPicksToRemove.dequeue();
|
||||
WriteLock lock(_removeLock);
|
||||
while (!_rayPicksToRemove.empty()) {
|
||||
QUuid uid = _rayPicksToRemove.front();
|
||||
_rayPicksToRemove.pop();
|
||||
_rayPicks.remove(uid);
|
||||
_rayPickLocks.remove(uid);
|
||||
}
|
||||
|
@ -145,9 +147,9 @@ QUuid RayPickManager::createRayPick(const QVariantMap& rayProps) {
|
|||
enabled = rayProps["enabled"].toBool();
|
||||
}
|
||||
|
||||
uint16_t filter = 0;
|
||||
RayPickFilter filter = RayPickFilter();
|
||||
if (rayProps["filter"].isValid()) {
|
||||
filter = rayProps["filter"].toUInt();
|
||||
filter = RayPickFilter(rayProps["filter"].toUInt());
|
||||
}
|
||||
|
||||
float maxDistance = 0.0f;
|
||||
|
@ -156,7 +158,7 @@ QUuid RayPickManager::createRayPick(const QVariantMap& rayProps) {
|
|||
}
|
||||
|
||||
if (rayProps["joint"].isValid()) {
|
||||
QString jointName = rayProps["joint"].toString();
|
||||
std::string jointName = rayProps["joint"].toString().toStdString();
|
||||
|
||||
if (jointName != "Mouse") {
|
||||
// x = upward, y = forward, z = lateral
|
||||
|
@ -170,14 +172,14 @@ QUuid RayPickManager::createRayPick(const QVariantMap& rayProps) {
|
|||
dirOffset = vec3FromVariant(rayProps["dirOffset"]);
|
||||
}
|
||||
|
||||
QWriteLocker lock(&_addLock);
|
||||
WriteLock lock(_addLock);
|
||||
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;
|
||||
} else {
|
||||
QWriteLocker lock(&_addLock);
|
||||
WriteLock lock(_addLock);
|
||||
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;
|
||||
}
|
||||
} else if (rayProps["position"].isValid()) {
|
||||
|
@ -188,9 +190,9 @@ QUuid RayPickManager::createRayPick(const QVariantMap& rayProps) {
|
|||
direction = vec3FromVariant(rayProps["direction"]);
|
||||
}
|
||||
|
||||
QWriteLocker lock(&_addLock);
|
||||
WriteLock lock(_addLock);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -198,28 +200,28 @@ QUuid RayPickManager::createRayPick(const QVariantMap& rayProps) {
|
|||
}
|
||||
|
||||
void RayPickManager::removeRayPick(const QUuid uid) {
|
||||
QWriteLocker lock(&_removeLock);
|
||||
_rayPicksToRemove.enqueue(uid);
|
||||
WriteLock lock(_removeLock);
|
||||
_rayPicksToRemove.push(uid);
|
||||
}
|
||||
|
||||
void RayPickManager::enableRayPick(const QUuid uid) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
ReadLock containsLock(_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker rayPickLock(_rayPickLocks[uid].get());
|
||||
WriteLock rayPickLock(*_rayPickLocks[uid]);
|
||||
_rayPicks[uid]->enable();
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::disableRayPick(const QUuid uid) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
ReadLock containsLock(_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker rayPickLock(_rayPickLocks[uid].get());
|
||||
WriteLock rayPickLock(*_rayPickLocks[uid]);
|
||||
_rayPicks[uid]->disable();
|
||||
}
|
||||
}
|
||||
|
||||
const PickRay RayPickManager::getPickRay(const QUuid uid) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
ReadLock containsLock(_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
bool 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) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
ReadLock containsLock(_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QReadLocker lock(_rayPickLocks[uid].get());
|
||||
ReadLock lock(*_rayPickLocks[uid]);
|
||||
return _rayPicks[uid]->getPrevRayPickResult();
|
||||
}
|
||||
return RayPickResult();
|
||||
}
|
||||
|
||||
void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
ReadLock containsLock(_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
WriteLock lock(*_rayPickLocks[uid]);
|
||||
_rayPicks[uid]->setIgnoreEntities(ignoreEntities);
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
ReadLock containsLock(_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
WriteLock lock(*_rayPickLocks[uid]);
|
||||
_rayPicks[uid]->setIncludeEntities(includeEntities);
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
ReadLock containsLock(_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
WriteLock lock(*_rayPickLocks[uid]);
|
||||
_rayPicks[uid]->setIgnoreOverlays(ignoreOverlays);
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
ReadLock containsLock(_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
WriteLock lock(*_rayPickLocks[uid]);
|
||||
_rayPicks[uid]->setIncludeOverlays(includeOverlays);
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
ReadLock containsLock(_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
WriteLock lock(*_rayPickLocks[uid]);
|
||||
_rayPicks[uid]->setIgnoreAvatars(ignoreAvatars);
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
ReadLock containsLock(_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
WriteLock lock(*_rayPickLocks[uid]);
|
||||
_rayPicks[uid]->setIncludeAvatars(includeAvatars);
|
||||
}
|
||||
}
|
|
@ -11,35 +11,20 @@
|
|||
#ifndef hifi_RayPickManager_h
|
||||
#define hifi_RayPickManager_h
|
||||
|
||||
#include <QHash>
|
||||
#include <QQueue>
|
||||
#include <QReadWriteLock>
|
||||
#include "RayPick.h"
|
||||
|
||||
#include <memory>
|
||||
#include <shared_mutex>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "RegisteredMetaTypes.h"
|
||||
#include "DependencyManager.h"
|
||||
|
||||
class RayPick;
|
||||
#include <unordered_map>
|
||||
#include <queue>
|
||||
|
||||
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 {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(unsigned int PICK_NOTHING READ PICK_NOTHING CONSTANT)
|
||||
|
@ -78,34 +63,37 @@ public slots:
|
|||
|
||||
private:
|
||||
QHash<QUuid, std::shared_ptr<RayPick>> _rayPicks;
|
||||
QHash<QUuid, std::shared_ptr<QReadWriteLock>> _rayPickLocks;
|
||||
QReadWriteLock _addLock;
|
||||
QQueue<QPair<QUuid, std::shared_ptr<RayPick>>> _rayPicksToAdd;
|
||||
QReadWriteLock _removeLock;
|
||||
QQueue<QUuid> _rayPicksToRemove;
|
||||
QReadWriteLock _containsLock;
|
||||
QHash<QUuid, std::shared_ptr<std::shared_mutex>> _rayPickLocks;
|
||||
std::shared_mutex _addLock;
|
||||
std::queue<std::pair<QUuid, std::shared_ptr<RayPick>>> _rayPicksToAdd;
|
||||
std::shared_mutex _removeLock;
|
||||
std::queue<QUuid> _rayPicksToRemove;
|
||||
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
|
||||
bool checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, unsigned int mask);
|
||||
void cacheResult(const bool intersects, const RayPickResult& resTemp, unsigned int mask, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache);
|
||||
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);
|
||||
|
||||
unsigned int PICK_NOTHING() { return RayPickMask::PICK_NOTHING; }
|
||||
unsigned int PICK_ENTITIES() { return RayPickMask::PICK_ENTITIES; }
|
||||
unsigned int PICK_OVERLAYS() { return RayPickMask::PICK_OVERLAYS; }
|
||||
unsigned int PICK_AVATARS() { return RayPickMask::PICK_AVATARS; }
|
||||
unsigned int PICK_HUD() { return RayPickMask::PICK_HUD; }
|
||||
unsigned int PICK_BOUNDING_BOX() { return RayPickMask::PICK_BOUNDING_BOX; }
|
||||
unsigned int PICK_INCLUDE_INVISIBLE() { return RayPickMask::PICK_INCLUDE_INVISIBLE; }
|
||||
unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return RayPickMask::PICK_INCLUDE_NONCOLLIDABLE; }
|
||||
unsigned int PICK_ALL_INTERSECTIONS() { return RayPickMask::PICK_ALL_INTERSECTIONS; }
|
||||
unsigned int PICK_NOTHING() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_NOTHING); }
|
||||
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_BOUNDING_BOX() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_COURSE); }
|
||||
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); }
|
||||
unsigned int INTERSECTED_NONE() { return IntersectionType::NONE; }
|
||||
unsigned int INTERSECTED_ENTITY() { return IntersectionType::ENTITY; }
|
||||
unsigned int INTERSECTED_OVERLAY() { return IntersectionType::OVERLAY; }
|
||||
unsigned int INTERSECTED_AVATAR() { return IntersectionType::AVATAR; }
|
||||
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
|
|
@ -10,7 +10,7 @@
|
|||
//
|
||||
#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),
|
||||
_pickRay(position, direction)
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
class StaticRayPick : public RayPick {
|
||||
|
||||
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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue