ignore/include by ID, simplified caching logic

This commit is contained in:
SamGondelman 2017-07-20 12:15:06 -07:00
parent bf243d6025
commit d156680bc8
9 changed files with 190 additions and 53 deletions

View file

@ -65,6 +65,13 @@ public:
void setRenderState(const QString& state);
void editRenderState(const QString& 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); }
void setIgnoreOverlays(const QScriptValue& ignoreOverlays) { DependencyManager::get<RayPickManager>()->setIgnoreOverlays(_rayPickUID, ignoreOverlays); }
void setIncludeOverlays(const QScriptValue& includeOverlays) { DependencyManager::get<RayPickManager>()->setIncludeOverlays(_rayPickUID, includeOverlays); }
void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { DependencyManager::get<RayPickManager>()->setIgnoreAvatars(_rayPickUID, ignoreAvatars); }
void setIncludeAvatars(const QScriptValue& includeAvatars) { DependencyManager::get<RayPickManager>()->setIncludeAvatars(_rayPickUID, includeAvatars); }
void update();
private:

View file

@ -16,7 +16,9 @@ unsigned int LaserPointerManager::createLaserPointer(const QString& jointName, c
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(jointName, posOffset, dirOffset, filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
unsigned int uid = laserPointer->getUID();
QWriteLocker lock(&_lock);
_laserPointers[uid] = laserPointer;
_laserPointerLocks[uid] = std::make_shared<QReadWriteLock>();
return uid;
}
@ -24,7 +26,9 @@ unsigned int LaserPointerManager::createLaserPointer(const glm::vec3& position,
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(position, direction, filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
unsigned int uid = laserPointer->getUID();
QWriteLocker lock(&_lock);
_laserPointers[uid] = laserPointer;
_laserPointerLocks[uid] = std::make_shared<QReadWriteLock>();
return uid;
}
@ -32,43 +36,112 @@ unsigned int LaserPointerManager::createLaserPointer(const uint16_t filter, cons
const bool centerEndY, const bool lockEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(filter, maxDistance, renderStates, faceAvatar, centerEndY, lockEnd, enabled);
unsigned int uid = laserPointer->getUID();
QWriteLocker lock(&_lock);
_laserPointers[uid] = laserPointer;
_laserPointerLocks[uid] = std::make_shared<QReadWriteLock>();
return uid;
}
void LaserPointerManager::removeLaserPointer(const unsigned int uid) {
QWriteLocker lock(&_lock);
_laserPointers.remove(uid);
_laserPointerLocks.remove(uid);
}
void LaserPointerManager::enableLaserPointer(const unsigned int uid) {
QReadLocker lock(&_lock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->enable();
}
}
void LaserPointerManager::disableLaserPointer(const unsigned int uid) {
QReadLocker lock(&_lock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->disable();
}
}
void LaserPointerManager::setRenderState(unsigned int uid, const QString & renderState) {
QReadLocker lock(&_lock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setRenderState(renderState);
}
}
void LaserPointerManager::editRenderState(unsigned int uid, const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
QReadLocker lock(&_lock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->editRenderState(state, startProps, pathProps, endProps);
}
}
const RayPickResult LaserPointerManager::getPrevRayPickResult(const unsigned int uid) {
QReadLocker lock(&_lock);
if (_laserPointers.contains(uid)) {
QReadLocker laserLock(_laserPointerLocks[uid].get());
return _laserPointers[uid]->getPrevRayPickResult();
}
return RayPickResult();
}
void LaserPointerManager::update() {
for (auto& laserPointer : _laserPointers) {
laserPointer->update();
QReadLocker lock(&_lock);
for (unsigned int uid : _laserPointers.keys()) {
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
QReadLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->update();
}
}
void LaserPointerManager::setIgnoreEntities(unsigned int uid, const QScriptValue& ignoreEntities) {
QReadLocker lock(&_lock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIgnoreEntities(ignoreEntities);
}
}
void LaserPointerManager::setIncludeEntities(unsigned int uid, const QScriptValue& includeEntities) {
QReadLocker lock(&_lock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIncludeEntities(includeEntities);
}
}
void LaserPointerManager::setIgnoreOverlays(unsigned int uid, const QScriptValue& ignoreOverlays) {
QReadLocker lock(&_lock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIgnoreOverlays(ignoreOverlays);
}
}
void LaserPointerManager::setIncludeOverlays(unsigned int uid, const QScriptValue& includeOverlays) {
QReadLocker lock(&_lock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIncludeOverlays(includeOverlays);
}
}
void LaserPointerManager::setIgnoreAvatars(unsigned int uid, const QScriptValue& ignoreAvatars) {
QReadLocker lock(&_lock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIgnoreAvatars(ignoreAvatars);
}
}
void LaserPointerManager::setIncludeAvatars(unsigned int uid, const QScriptValue& includeAvatars) {
QReadLocker lock(&_lock);
if (_laserPointers.contains(uid)) {
QWriteLocker laserLock(_laserPointerLocks[uid].get());
_laserPointers[uid]->setIncludeAvatars(includeAvatars);
}
}

View file

@ -31,17 +31,26 @@ public:
const QHash<QString, RenderState>& renderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
unsigned int createLaserPointer(const uint16_t filter, const float maxDistance, const QHash<QString, RenderState>& renderStates, const bool faceAvatar,
const bool centerEndY, const bool lockEnd, const bool enabled);
void removeLaserPointer(const unsigned int uid) { _laserPointers.remove(uid); }
void removeLaserPointer(const unsigned int uid);
void enableLaserPointer(const unsigned int uid);
void disableLaserPointer(const unsigned int uid);
void setRenderState(unsigned int uid, const QString& renderState);
void editRenderState(unsigned int uid, const QString& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
const RayPickResult getPrevRayPickResult(const unsigned int uid);
void setIgnoreEntities(unsigned int uid, const QScriptValue& ignoreEntities);
void setIncludeEntities(unsigned int uid, const QScriptValue& includeEntities);
void setIgnoreOverlays(unsigned int uid, const QScriptValue& ignoreOverlays);
void setIncludeOverlays(unsigned int uid, const QScriptValue& includeOverlays);
void setIgnoreAvatars(unsigned int uid, const QScriptValue& ignoreAvatars);
void setIncludeAvatars(unsigned int uid, const QScriptValue& includeAvatars);
void update();
private:
QHash<unsigned int, std::shared_ptr<LaserPointer>> _laserPointers;
QReadWriteLock _lock;
QHash<unsigned int, std::shared_ptr<QReadWriteLock>> _laserPointerLocks;
};

View file

@ -30,6 +30,13 @@ public slots:
Q_INVOKABLE void setRenderState(unsigned int uid, const QString& renderState) { DependencyManager::get<LaserPointerManager>()->setRenderState(uid, renderState); }
Q_INVOKABLE RayPickResult getPrevRayPickResult(unsigned int uid) { return DependencyManager::get<LaserPointerManager>()->getPrevRayPickResult(uid); }
Q_INVOKABLE void setIgnoreEntities(unsigned int uid, const QScriptValue& ignoreEntities) { DependencyManager::get<LaserPointerManager>()->setIgnoreEntities(uid, ignoreEntities); }
Q_INVOKABLE void setIncludeEntities(unsigned int uid, const QScriptValue& includeEntities) { DependencyManager::get<LaserPointerManager>()->setIncludeEntities(uid, includeEntities); }
Q_INVOKABLE void setIgnoreOverlays(unsigned int uid, const QScriptValue& ignoreOverlays) { DependencyManager::get<LaserPointerManager>()->setIgnoreOverlays(uid, ignoreOverlays); }
Q_INVOKABLE void setIncludeOverlays(unsigned int uid, const QScriptValue& includeOverlays) { DependencyManager::get<LaserPointerManager>()->setIncludeOverlays(uid, includeOverlays); }
Q_INVOKABLE void setIgnoreAvatars(unsigned int uid, const QScriptValue& ignoreAvatars) { DependencyManager::get<LaserPointerManager>()->setIgnoreAvatars(uid, ignoreAvatars); }
Q_INVOKABLE void setIncludeAvatars(unsigned int uid, const QScriptValue& includeAvatars) { DependencyManager::get<LaserPointerManager>()->setIncludeAvatars(uid, includeAvatars); }
private:
const RenderState buildRenderState(const QVariantMap & propMap);

View file

@ -13,8 +13,6 @@
#include "RayPick.h"
#include <QString>
class MouseRayPick : public RayPick {
public:

View file

@ -31,12 +31,31 @@ public:
void setRayPickResult(const RayPickResult& rayPickResult) { _prevResult = rayPickResult; }
const QScriptValue& getIgnoreEntites() { return _ignoreEntities; }
const QScriptValue& getIncludeEntites() { return _includeEntities; }
const QScriptValue& getIgnoreOverlays() { return _ignoreOverlays; }
const QScriptValue& getIncludeOverlays() { return _includeOverlays; }
const QScriptValue& getIgnoreAvatars() { return _ignoreAvatars; }
const QScriptValue& getIncludeAvatars() { return _includeAvatars; }
void setIgnoreEntities(const QScriptValue& ignoreEntities) { _ignoreEntities = ignoreEntities; }
void setIncludeEntities(const QScriptValue& includeEntities) { _includeEntities = includeEntities; }
void setIgnoreOverlays(const QScriptValue& ignoreOverlays) { _ignoreOverlays = ignoreOverlays; }
void setIncludeOverlays(const QScriptValue& includeOverlays) { _includeOverlays = includeOverlays; }
void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { _ignoreAvatars = ignoreAvatars; }
void setIncludeAvatars(const QScriptValue& includeAvatars) { _includeAvatars = includeAvatars; }
private:
uint16_t _filter;
float _maxDistance;
bool _enabled;
RayPickResult _prevResult;
QScriptValue _ignoreEntities;
QScriptValue _includeEntities;
QScriptValue _ignoreOverlays;
QScriptValue _includeOverlays;
QScriptValue _ignoreAvatars;
QScriptValue _includeAvatars;
};
#endif // hifi_RayPick_h

View file

@ -63,70 +63,40 @@ void RayPickManager::update() {
if (rayPick->getFilter() & RayPickMask::PICK_ENTITIES) {
RayToEntityIntersectionResult entityRes;
bool fromCache = true;
if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE && rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_ENTITIES | RayPickMask::PICK_INCLUDE_INVISIBLE | RayPickMask::PICK_INCLUDE_NONCOLLIDABLE)) {
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, QScriptValue(), QScriptValue(), false, false);
fromCache = false;
}
} else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE) {
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_ENTITIES | RayPickMask::PICK_INCLUDE_INVISIBLE)) {
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, QScriptValue(), QScriptValue(), false, true);
fromCache = false;
}
} else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_ENTITIES | RayPickMask::PICK_INCLUDE_NONCOLLIDABLE)) {
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, false);
fromCache = false;
}
} else {
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_ENTITIES)) {
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, true);
fromCache = false;
}
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;
if (!checkAndCompareCachedResults(rayKey, results, res, entityMask)) {
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, rayPick->getIncludeEntites(), rayPick->getIgnoreEntites(), !invisible, !noncollidable);
fromCache = false;
}
if (!fromCache) {
unsigned int mask = (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE) | (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE);
cacheResult(entityRes.intersects, RayPickResult(IntersectionType::ENTITY, entityRes.entityID, entityRes.distance, entityRes.intersection, entityRes.surfaceNormal),
RayPickMask::PICK_ENTITIES | mask, res, rayKey, results);
entityMask, res, rayKey, results);
}
}
if (rayPick->getFilter() & RayPickMask::PICK_OVERLAYS) {
RayToOverlayIntersectionResult overlayRes;
bool fromCache = true;
if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE && rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_OVERLAYS | RayPickMask::PICK_INCLUDE_INVISIBLE | RayPickMask::PICK_INCLUDE_NONCOLLIDABLE)) {
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, QScriptValue(), QScriptValue(), false, false);
fromCache = false;
}
} else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE) {
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_OVERLAYS | RayPickMask::PICK_INCLUDE_INVISIBLE)) {
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, QScriptValue(), QScriptValue(), false, true);
fromCache = false;
}
} else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_OVERLAYS | RayPickMask::PICK_INCLUDE_NONCOLLIDABLE)) {
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, false);
fromCache = false;
}
} else {
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_OVERLAYS)) {
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, true);
fromCache = false;
}
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;
if (!checkAndCompareCachedResults(rayKey, results, res, overlayMask)) {
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, rayPick->getIncludeOverlays(), rayPick->getIgnoreOverlays(), !invisible, !noncollidable);
fromCache = false;
}
if (!fromCache) {
unsigned int mask = (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE) | (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE);
cacheResult(overlayRes.intersects, RayPickResult(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, overlayRes.surfaceNormal),
RayPickMask::PICK_OVERLAYS | mask, res, rayKey, results);
overlayMask, res, rayKey, results);
}
}
if (rayPick->getFilter() & RayPickMask::PICK_AVATARS) {
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_AVATARS)) {
RayToAvatarIntersectionResult avatarRes = DependencyManager::get<AvatarManager>()->findRayIntersection(ray, QScriptValue(), QScriptValue());
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);
}
}
@ -214,3 +184,51 @@ const RayPickResult RayPickManager::getPrevRayPickResult(const unsigned int uid)
}
return RayPickResult();
}
void RayPickManager::setIgnoreEntities(unsigned int uid, const QScriptValue& ignoreEntities) {
QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) {
QWriteLocker lock(_rayPickLocks[uid].get());
_rayPicks[uid]->setIgnoreEntities(ignoreEntities);
}
}
void RayPickManager::setIncludeEntities(unsigned int uid, const QScriptValue& includeEntities) {
QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) {
QWriteLocker lock(_rayPickLocks[uid].get());
_rayPicks[uid]->setIncludeEntities(includeEntities);
}
}
void RayPickManager::setIgnoreOverlays(unsigned int uid, const QScriptValue& ignoreOverlays) {
QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) {
QWriteLocker lock(_rayPickLocks[uid].get());
_rayPicks[uid]->setIgnoreOverlays(ignoreOverlays);
}
}
void RayPickManager::setIncludeOverlays(unsigned int uid, const QScriptValue& includeOverlays) {
QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) {
QWriteLocker lock(_rayPickLocks[uid].get());
_rayPicks[uid]->setIncludeOverlays(includeOverlays);
}
}
void RayPickManager::setIgnoreAvatars(unsigned int uid, const QScriptValue& ignoreAvatars) {
QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) {
QWriteLocker lock(_rayPickLocks[uid].get());
_rayPicks[uid]->setIgnoreAvatars(ignoreAvatars);
}
}
void RayPickManager::setIncludeAvatars(unsigned int uid, const QScriptValue& includeAvatars) {
QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) {
QWriteLocker lock(_rayPickLocks[uid].get());
_rayPicks[uid]->setIncludeAvatars(includeAvatars);
}
}

View file

@ -65,6 +65,13 @@ public:
const PickRay getPickRay(const unsigned int uid);
const RayPickResult getPrevRayPickResult(const unsigned int uid);
void setIgnoreEntities(unsigned int uid, const QScriptValue& ignoreEntities);
void setIncludeEntities(unsigned int uid, const QScriptValue& includeEntities);
void setIgnoreOverlays(unsigned int uid, const QScriptValue& ignoreOverlays);
void setIncludeOverlays(unsigned int uid, const QScriptValue& includeOverlays);
void setIgnoreAvatars(unsigned int uid, const QScriptValue& ignoreAvatars);
void setIncludeAvatars(unsigned int uid, const QScriptValue& includeAvatars);
private:
QHash<unsigned int, std::shared_ptr<RayPick>> _rayPicks;
QHash<unsigned int, std::shared_ptr<QReadWriteLock>> _rayPickLocks;

View file

@ -262,6 +262,7 @@ function Grabber() {
filter: RayPick.PICK_OVERLAYS,
enabled: true
});
LaserPointers.setIncludeOverlays(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]);
this.mouseRayEntities = LaserPointers.createLaserPointer({
joint: "Mouse",
filter: RayPick.PICK_ENTITIES,
@ -319,9 +320,7 @@ Grabber.prototype.pressEvent = function(event) {
var overlayResult = LaserPointers.getPrevRayPickResult(this.mouseRayOverlays);
if (overlayResult.type != RayPick.INTERSECTED_NONE) {
if (overlayResult.objectID == HMD.tabletID || overlayResult.objectID == HMD.tabletScreenID || overlayResult.objectID == HMD.homeButtonID) {
return;
}
return;
}
var pickResults = LaserPointers.getPrevRayPickResult(this.mouseRayEntities);