mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 10:07:58 +02:00
added JS/C++ RayPickResult, working on RayPickManager::update
This commit is contained in:
parent
285705c934
commit
916a99c670
10 changed files with 137 additions and 66 deletions
|
@ -32,4 +32,8 @@ void LaserPointer::disable() {
|
||||||
RayPickManager::getInstance().disableRayPick(_rayPickUID);
|
RayPickManager::getInstance().disableRayPick(_rayPickUID);
|
||||||
// TODO:
|
// TODO:
|
||||||
// turn off rendering
|
// turn off rendering
|
||||||
|
}
|
||||||
|
|
||||||
|
const RayPickResult& LaserPointer::getPrevRayPickResult() {
|
||||||
|
return RayPickManager::getInstance().getPrevRayPickResult(_rayPickUID);
|
||||||
}
|
}
|
|
@ -14,6 +14,8 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include "glm/glm.hpp"
|
#include "glm/glm.hpp"
|
||||||
|
|
||||||
|
class RayPickResult;
|
||||||
|
|
||||||
class LaserPointer {
|
class LaserPointer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -27,6 +29,8 @@ public:
|
||||||
// void setRenderState(const QString& stateName);
|
// void setRenderState(const QString& stateName);
|
||||||
// void setRenderStateProperties(const QHash<QString, triplet of properties>& renderStateProperties);
|
// void setRenderStateProperties(const QHash<QString, triplet of properties>& renderStateProperties);
|
||||||
|
|
||||||
|
const RayPickResult& getPrevRayPickResult();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int _rayPickUID;
|
unsigned int _rayPickUID;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
#include "LaserPointerManager.h"
|
#include "LaserPointerManager.h"
|
||||||
#include "LaserPointer.h"
|
#include "LaserPointer.h"
|
||||||
|
#include "RayPick.h"
|
||||||
|
|
||||||
LaserPointerManager& LaserPointerManager::getInstance() {
|
LaserPointerManager& LaserPointerManager::getInstance() {
|
||||||
static LaserPointerManager instance;
|
static LaserPointerManager instance;
|
||||||
|
@ -33,4 +34,11 @@ void LaserPointerManager::disableLaserPointer(const unsigned int uid) {
|
||||||
if (_laserPointers.contains(uid)) {
|
if (_laserPointers.contains(uid)) {
|
||||||
_laserPointers[uid]->disable();
|
_laserPointers[uid]->disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RayPickResult& LaserPointerManager::getPrevRayPickResult(const unsigned int uid) {
|
||||||
|
if (_laserPointers.contains(uid)) {
|
||||||
|
return _laserPointers[uid]->getPrevRayPickResult();
|
||||||
|
}
|
||||||
|
return RayPickResult();
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
class LaserPointer;
|
class LaserPointer;
|
||||||
|
class RayPickResult;
|
||||||
|
|
||||||
class LaserPointerManager {
|
class LaserPointerManager {
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ public:
|
||||||
void removeLaserPointer(const unsigned int uid) { _laserPointers.remove(uid); }
|
void removeLaserPointer(const unsigned int uid) { _laserPointers.remove(uid); }
|
||||||
void enableLaserPointer(const unsigned int uid);
|
void enableLaserPointer(const unsigned int uid);
|
||||||
void disableLaserPointer(const unsigned int uid);
|
void disableLaserPointer(const unsigned int uid);
|
||||||
|
const RayPickResult& getPrevRayPickResult(const unsigned int uid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<unsigned int, std::shared_ptr<LaserPointer>> _laserPointers;
|
QHash<unsigned int, std::shared_ptr<LaserPointer>> _laserPointers;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
#include "LaserPointerManager.h"
|
#include "LaserPointerManager.h"
|
||||||
|
#include "RegisteredMetaTypes.h"
|
||||||
|
|
||||||
class LaserPointerScriptingInterface : public QObject {
|
class LaserPointerScriptingInterface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -26,7 +27,7 @@ public slots:
|
||||||
Q_INVOKABLE void enableLaserPointer(unsigned int uid) { LaserPointerManager::getInstance().enableLaserPointer(uid); }
|
Q_INVOKABLE void enableLaserPointer(unsigned int uid) { LaserPointerManager::getInstance().enableLaserPointer(uid); }
|
||||||
Q_INVOKABLE void disableLaserPointer(unsigned int uid) { LaserPointerManager::getInstance().disableLaserPointer(uid); }
|
Q_INVOKABLE void disableLaserPointer(unsigned int uid) { LaserPointerManager::getInstance().disableLaserPointer(uid); }
|
||||||
Q_INVOKABLE void removeLaserPointer(unsigned int uid) { LaserPointerManager::getInstance().removeLaserPointer(uid); }
|
Q_INVOKABLE void removeLaserPointer(unsigned int uid) { LaserPointerManager::getInstance().removeLaserPointer(uid); }
|
||||||
//Q_INVOKABLE IntersectionResults getLaserPointerCollisionResults(unsigned int uid) { LaserPointerManager::getInstance().getLaserPointerCollisionResults(uid); }
|
Q_INVOKABLE RayPickResult getPrevRayPickResult(unsigned int uid) { return LaserPointerManager::getInstance().getPrevRayPickResult(uid); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,15 +27,15 @@ public:
|
||||||
const uint16_t getFilter() { return _filter; }
|
const uint16_t getFilter() { return _filter; }
|
||||||
const float getMaxDistance() { return _maxDistance; }
|
const float getMaxDistance() { return _maxDistance; }
|
||||||
const bool isEnabled() { return _enabled; }
|
const bool isEnabled() { return _enabled; }
|
||||||
//const IntersectionResult& getLastIntersectionResult() { return _prevIntersectionResult; }
|
const RayPickResult& getPrevRayPickResult() { return _prevResult; }
|
||||||
|
|
||||||
//void setIntersectionResult(const IntersectionResult& intersectionResult) { _prevIntersectionResult = intersectionResult; }
|
void setRayPickResult(const RayPickResult& rayPickResult) { _prevResult = rayPickResult; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t _filter;
|
uint16_t _filter;
|
||||||
float _maxDistance;
|
float _maxDistance;
|
||||||
bool _enabled;
|
bool _enabled;
|
||||||
//IntersectionResult _prevIntersectionResult; // set to invalid on disable()?
|
RayPickResult _prevResult;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,14 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
#include "RayPickManager.h"
|
#include "RayPickManager.h"
|
||||||
|
|
||||||
#include "RayPick.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"
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
|
#include "scripting/HMDScriptingInterface.h"
|
||||||
#include "DependencyManager.h"
|
#include "DependencyManager.h"
|
||||||
|
|
||||||
RayPickManager& RayPickManager::getInstance() {
|
RayPickManager& RayPickManager::getInstance() {
|
||||||
|
@ -23,9 +25,9 @@ RayPickManager& RayPickManager::getInstance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 RayPickManager::checkAndCompareCachedResults(std::shared_ptr<RayPick> rayPick, QPair<glm::vec3, glm::vec3>& ray, QHash<QPair<glm::vec3, glm::vec3>, QHash<unsigned int, RayPickResult>> cache, RayPickResult& res, unsigned int mask) {
|
bool RayPickManager::checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, QHash<QPair<glm::vec3, glm::vec3>, QHash<unsigned int, RayPickResult>>& cache, RayPickResult& res, unsigned int mask) {
|
||||||
if (cache.contains(ray) && cache[ray].contains(mask)) {
|
if (cache.contains(ray) && cache[ray].contains(mask)) {
|
||||||
if (cache[ray][mask].getDistance() < res.getDistance() && cache[ray][mask].getDistance() < rayPick->getMaxDistance()) {
|
if (cache[ray][mask].distance < res.distance) {
|
||||||
res = cache[ray][mask];
|
res = cache[ray][mask];
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -33,6 +35,18 @@ bool RayPickManager::checkAndCompareCachedResults(std::shared_ptr<RayPick> rayPi
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RayPickManager::cacheResult(const bool intersects, const RayPickResult& resTemp, unsigned int mask, RayPickResult& res,
|
||||||
|
QPair<glm::vec3, glm::vec3>& ray, QHash<QPair<glm::vec3, glm::vec3>, QHash<unsigned int, RayPickResult>>& cache) {
|
||||||
|
if (intersects) {
|
||||||
|
cache[ray][mask] = resTemp;
|
||||||
|
if (resTemp.distance < res.distance) {
|
||||||
|
res = resTemp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cache[ray][mask] = RayPickResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RayPickManager::update() {
|
void RayPickManager::update() {
|
||||||
QHash<QPair<glm::vec3, glm::vec3>, QHash<unsigned int, RayPickResult>> results;
|
QHash<QPair<glm::vec3, glm::vec3>, QHash<unsigned int, RayPickResult>> results;
|
||||||
for (auto &rayPick : _rayPicks) {
|
for (auto &rayPick : _rayPicks) {
|
||||||
|
@ -44,74 +58,92 @@ void RayPickManager::update() {
|
||||||
// TODO:
|
// TODO:
|
||||||
// get rid of this and make PickRay hashable
|
// get rid of this and make PickRay hashable
|
||||||
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; // start with FLT_MAX distance
|
RayPickResult res;
|
||||||
|
|
||||||
if (rayPick->getFilter() & RayPickMask::PICK_ENTITIES) {
|
if (rayPick->getFilter() & RayPickMask::PICK_ENTITIES) {
|
||||||
RayToEntityIntersectionResult entityRes;
|
RayToEntityIntersectionResult entityRes;
|
||||||
|
bool fromCache = true;
|
||||||
if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE && rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
|
if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE && rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
|
||||||
if (!checkAndCompareCachedResults(rayPick, rayKey, results, res, RayPickMask::PICK_ENTITIES | RayPickMask::PICK_INCLUDE_INVISIBLE | 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);
|
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, QScriptValue(), QScriptValue(), false, false);
|
||||||
|
fromCache = false;
|
||||||
}
|
}
|
||||||
}
|
} else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE) {
|
||||||
else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE) {
|
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_ENTITIES | RayPickMask::PICK_INCLUDE_INVISIBLE)) {
|
||||||
if (!checkAndCompareCachedResults(rayPick, rayKey, results, res, RayPickMask::PICK_ENTITIES | RayPickMask::PICK_INCLUDE_INVISIBLE)) {
|
|
||||||
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, QScriptValue(), QScriptValue(), false, true);
|
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, QScriptValue(), QScriptValue(), false, true);
|
||||||
|
fromCache = false;
|
||||||
}
|
}
|
||||||
}
|
} else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
|
||||||
else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
|
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_ENTITIES | RayPickMask::PICK_INCLUDE_NONCOLLIDABLE)) {
|
||||||
if (!checkAndCompareCachedResults(rayPick, rayKey, results, res, RayPickMask::PICK_ENTITIES | RayPickMask::PICK_INCLUDE_NONCOLLIDABLE)) {
|
|
||||||
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, false);
|
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, false);
|
||||||
|
fromCache = false;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_ENTITIES)) {
|
||||||
if (!checkAndCompareCachedResults(rayPick, rayKey, results, res, RayPickMask::PICK_ENTITIES)) {
|
|
||||||
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, true);
|
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, true);
|
||||||
|
fromCache = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entityRes.intersects) {
|
|
||||||
res = RayPickResult(entityRes.entityID, entityRes.distance, entityRes.intersection, entityRes.surfaceNormal);
|
if (!fromCache) {
|
||||||
// add to cache
|
unsigned int mask = (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE) | (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE);
|
||||||
|
cacheResult(entityRes.intersects, RayPickResult(entityRes.entityID, entityRes.distance, entityRes.intersection, entityRes.surfaceNormal),
|
||||||
|
RayPickMask::PICK_ENTITIES | mask, res, rayKey, results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rayPick->getFilter() & RayPickMask::PICK_OVERLAYS) {
|
if (rayPick->getFilter() & RayPickMask::PICK_OVERLAYS) {
|
||||||
RayToOverlayIntersectionResult overlayRes;
|
RayToOverlayIntersectionResult overlayRes;
|
||||||
|
bool fromCache = true;
|
||||||
if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE && rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
|
if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE && rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
|
||||||
if (!checkAndCompareCachedResults(rayPick, rayKey, results, res, RayPickMask::PICK_OVERLAYS | RayPickMask::PICK_INCLUDE_INVISIBLE | 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);
|
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, QScriptValue(), QScriptValue(), false, false);
|
||||||
|
fromCache = false;
|
||||||
}
|
}
|
||||||
}
|
} else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE) {
|
||||||
else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE) {
|
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_OVERLAYS | RayPickMask::PICK_INCLUDE_INVISIBLE)) {
|
||||||
if (!checkAndCompareCachedResults(rayPick, rayKey, results, res, RayPickMask::PICK_OVERLAYS | RayPickMask::PICK_INCLUDE_INVISIBLE)) {
|
|
||||||
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, QScriptValue(), QScriptValue(), false, true);
|
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, QScriptValue(), QScriptValue(), false, true);
|
||||||
|
fromCache = false;
|
||||||
}
|
}
|
||||||
}
|
} else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
|
||||||
else if (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE) {
|
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_OVERLAYS | RayPickMask::PICK_INCLUDE_NONCOLLIDABLE)) {
|
||||||
if (!checkAndCompareCachedResults(rayPick, rayKey, results, res, RayPickMask::PICK_OVERLAYS | RayPickMask::PICK_INCLUDE_NONCOLLIDABLE)) {
|
|
||||||
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, false);
|
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, false);
|
||||||
|
fromCache = false;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
if (!checkAndCompareCachedResults(rayKey, results, res, RayPickMask::PICK_OVERLAYS)) {
|
||||||
if (!checkAndCompareCachedResults(rayPick, rayKey, results, res, RayPickMask::PICK_OVERLAYS)) {
|
|
||||||
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, true);
|
overlayRes = qApp->getOverlays().findRayIntersection(ray, true, QScriptValue(), QScriptValue(), true, true);
|
||||||
|
fromCache = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (overlayRes.intersects) {
|
|
||||||
res = RayPickResult(overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, overlayRes.surfaceNormal);
|
if (!fromCache) {
|
||||||
// add to cache
|
unsigned int mask = (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_INVISIBLE) | (rayPick->getFilter() & RayPickMask::PICK_INCLUDE_NONCOLLIDABLE);
|
||||||
|
cacheResult(overlayRes.intersects, RayPickResult(overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, overlayRes.surfaceNormal),
|
||||||
|
RayPickMask::PICK_OVERLAYS | mask, res, rayKey, results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rayPick->getFilter() & RayPickMask::PICK_AVATARS) {
|
if (rayPick->getFilter() & RayPickMask::PICK_AVATARS) {
|
||||||
if (!checkAndCompareCachedResults(rayPick, rayKey, results, res, 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, QScriptValue(), QScriptValue());
|
||||||
if (avatarRes.intersects) {
|
cacheResult(avatarRes.intersects, RayPickResult(avatarRes.avatarID, avatarRes.distance, avatarRes.intersection), RayPickMask::PICK_AVATARS, res, rayKey, results);
|
||||||
res = RayPickResult(avatarRes.avatarID, avatarRes.distance, avatarRes.intersection);
|
|
||||||
// add to cache
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)) {
|
||||||
|
glm::vec3 hudRes = DependencyManager::get<HMDScriptingInterface>()->calculateRayUICollisionPoint(ray.origin, ray.direction);
|
||||||
|
cacheResult(true, RayPickResult(0, glm::distance(ray.origin, hudRes), hudRes), RayPickMask::PICK_HUD, res, rayKey, results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.distance < rayPick->getMaxDistance()) {
|
||||||
|
rayPick->setRayPickResult(res);
|
||||||
|
} else {
|
||||||
|
rayPick->setRayPickResult(RayPickResult());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,17 +161,22 @@ void RayPickManager::removeRayPick(const unsigned int uid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::enableRayPick(const unsigned int uid) {
|
void RayPickManager::enableRayPick(const unsigned int uid) {
|
||||||
// TODO:
|
|
||||||
// use lock and defer enabling to prevent issues
|
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
_rayPicks[uid]->enable();
|
_rayPicks[uid]->enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::disableRayPick(const unsigned int uid) {
|
void RayPickManager::disableRayPick(const unsigned int uid) {
|
||||||
// TODO:
|
|
||||||
// use lock and defer disabling to prevent issues
|
|
||||||
if (_rayPicks.contains(uid)) {
|
if (_rayPicks.contains(uid)) {
|
||||||
_rayPicks[uid]->disable();
|
_rayPicks[uid]->disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RayPickResult& RayPickManager::getPrevRayPickResult(const unsigned int uid) {
|
||||||
|
// TODO:
|
||||||
|
// does this need to lock the individual ray? what happens with concurrent set/get?
|
||||||
|
if (_rayPicks.contains(uid)) {
|
||||||
|
return _rayPicks[uid]->getPrevRayPickResult();
|
||||||
|
}
|
||||||
|
return RayPickResult();
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
class RayPick;
|
class RayPick;
|
||||||
|
class RayPickResult;
|
||||||
|
|
||||||
enum RayPickMask {
|
enum RayPickMask {
|
||||||
PICK_NOTHING = 0,
|
PICK_NOTHING = 0,
|
||||||
|
@ -34,28 +35,6 @@ enum RayPickMask {
|
||||||
PICK_ALL_INTERSECTIONS = 128 // if not set, returns closest intersection, otherwise, returns list of all intersections
|
PICK_ALL_INTERSECTIONS = 128 // if not set, returns closest intersection, otherwise, returns list of all intersections
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// move/improve this and register it as a meta type
|
|
||||||
class RayPickResult {
|
|
||||||
|
|
||||||
public:
|
|
||||||
RayPickResult() {}
|
|
||||||
RayPickResult(const QUuid& objectID, const float distance, const glm::vec3& intersection, const glm::vec3& surfaceNormal = glm::vec3(NAN)) :
|
|
||||||
_objectID(objectID), _distance(distance), _intersection(intersection), _surfaceNormal(surfaceNormal) {}
|
|
||||||
|
|
||||||
const QUuid& getUID() { return _objectID; }
|
|
||||||
const float getDistance() { return _distance; }
|
|
||||||
const glm::vec3& getIntersection() { return _intersection; }
|
|
||||||
const glm::vec3& getSurfaceNormal() { return _surfaceNormal; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
//Type type;
|
|
||||||
QUuid _objectID { 0 };
|
|
||||||
float _distance { FLT_MAX };
|
|
||||||
glm::vec3 _intersection { NAN };
|
|
||||||
glm::vec3 _surfaceNormal { NAN };
|
|
||||||
};
|
|
||||||
|
|
||||||
class RayPickManager : public QObject {
|
class RayPickManager : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(unsigned int PICK_NOTHING READ PICK_NOTHING CONSTANT)
|
Q_PROPERTY(unsigned int PICK_NOTHING READ PICK_NOTHING CONSTANT)
|
||||||
|
@ -72,11 +51,14 @@ public:
|
||||||
static RayPickManager& getInstance();
|
static RayPickManager& getInstance();
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
bool RayPickManager::checkAndCompareCachedResults(std::shared_ptr<RayPick> rayPick, QPair<glm::vec3, glm::vec3>& ray, QHash<QPair<glm::vec3, glm::vec3>, QHash<unsigned int, RayPickResult>> cache, RayPickResult& res, unsigned int mask);
|
bool checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, QHash<QPair<glm::vec3, glm::vec3>, QHash<unsigned int, RayPickResult>>& 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, QHash<QPair<glm::vec3, glm::vec3>, QHash<unsigned int, RayPickResult>>& cache);
|
||||||
unsigned int addRayPick(std::shared_ptr<RayPick> rayPick);
|
unsigned int addRayPick(std::shared_ptr<RayPick> rayPick);
|
||||||
void removeRayPick(const unsigned int uid);
|
void removeRayPick(const unsigned int uid);
|
||||||
void enableRayPick(const unsigned int uid);
|
void enableRayPick(const unsigned int uid);
|
||||||
void disableRayPick(const unsigned int uid);
|
void disableRayPick(const unsigned int uid);
|
||||||
|
const RayPickResult& getPrevRayPickResult(const unsigned int uid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<unsigned int, std::shared_ptr<RayPick>> _rayPicks;
|
QHash<unsigned int, std::shared_ptr<RayPick>> _rayPicks;
|
||||||
|
|
|
@ -34,6 +34,7 @@ int vec2MetaTypeId = qRegisterMetaType<glm::vec2>();
|
||||||
int quatMetaTypeId = qRegisterMetaType<glm::quat>();
|
int quatMetaTypeId = qRegisterMetaType<glm::quat>();
|
||||||
int xColorMetaTypeId = qRegisterMetaType<xColor>();
|
int xColorMetaTypeId = qRegisterMetaType<xColor>();
|
||||||
int pickRayMetaTypeId = qRegisterMetaType<PickRay>();
|
int pickRayMetaTypeId = qRegisterMetaType<PickRay>();
|
||||||
|
int rayPickResultMetaTypeId = qRegisterMetaType<RayPickResult>();
|
||||||
int collisionMetaTypeId = qRegisterMetaType<Collision>();
|
int collisionMetaTypeId = qRegisterMetaType<Collision>();
|
||||||
int qMapURLStringMetaTypeId = qRegisterMetaType<QMap<QUrl,QString>>();
|
int qMapURLStringMetaTypeId = qRegisterMetaType<QMap<QUrl,QString>>();
|
||||||
int socketErrorMetaTypeId = qRegisterMetaType<QAbstractSocket::SocketError>();
|
int socketErrorMetaTypeId = qRegisterMetaType<QAbstractSocket::SocketError>();
|
||||||
|
@ -56,6 +57,7 @@ void registerMetaTypes(QScriptEngine* engine) {
|
||||||
qScriptRegisterMetaType(engine, qColorToScriptValue, qColorFromScriptValue);
|
qScriptRegisterMetaType(engine, qColorToScriptValue, qColorFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, qURLToScriptValue, qURLFromScriptValue);
|
qScriptRegisterMetaType(engine, qURLToScriptValue, qURLFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue);
|
qScriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue);
|
||||||
|
qScriptRegisterMetaType(engine, rayPickResultToScriptValue, rayPickResultFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue);
|
qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue);
|
qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue);
|
qScriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue);
|
||||||
|
@ -751,6 +753,22 @@ void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue rayPickResultToScriptValue(QScriptEngine* engine, const RayPickResult& rayPickResult) {
|
||||||
|
QScriptValue obj = engine->newObject();
|
||||||
|
QScriptValue objectID = quuidToScriptValue(engine, rayPickResult.objectID);
|
||||||
|
obj.setProperty("objectID", objectID);
|
||||||
|
obj.setProperty("distance", rayPickResult.distance);
|
||||||
|
QScriptValue intersection = vec3toScriptValue(engine, rayPickResult.intersection);
|
||||||
|
obj.setProperty("intersection", intersection);
|
||||||
|
QScriptValue surfaceNormal = vec3toScriptValue(engine, rayPickResult.surfaceNormal);
|
||||||
|
obj.setProperty("surfaceNormal", surfaceNormal);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rayPickResultFromScriptValue(const QScriptValue& object, RayPickResult& rayPickResult) {
|
||||||
|
// TODO: cannot currently accept RayPickResults from JS
|
||||||
|
}
|
||||||
|
|
||||||
QScriptValue collisionToScriptValue(QScriptEngine* engine, const Collision& collision) {
|
QScriptValue collisionToScriptValue(QScriptEngine* engine, const Collision& collision) {
|
||||||
QScriptValue obj = engine->newObject();
|
QScriptValue obj = engine->newObject();
|
||||||
obj.setProperty("type", collision.type);
|
obj.setProperty("type", collision.type);
|
||||||
|
|
|
@ -136,6 +136,21 @@ Q_DECLARE_METATYPE(PickRay)
|
||||||
QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay);
|
QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay);
|
||||||
void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay);
|
void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay);
|
||||||
|
|
||||||
|
class RayPickResult {
|
||||||
|
public:
|
||||||
|
RayPickResult() {}
|
||||||
|
RayPickResult(const QUuid& objectID, const float distance, const glm::vec3& intersection, const glm::vec3& surfaceNormal = glm::vec3(NAN)) :
|
||||||
|
objectID(objectID), distance(distance), intersection(intersection), surfaceNormal(surfaceNormal) {}
|
||||||
|
//Type type;
|
||||||
|
QUuid objectID { 0 };
|
||||||
|
float distance { FLT_MAX };
|
||||||
|
glm::vec3 intersection { NAN };
|
||||||
|
glm::vec3 surfaceNormal { NAN };
|
||||||
|
};
|
||||||
|
Q_DECLARE_METATYPE(RayPickResult)
|
||||||
|
QScriptValue rayPickResultToScriptValue(QScriptEngine* engine, const RayPickResult& rayPickResult);
|
||||||
|
void rayPickResultFromScriptValue(const QScriptValue& object, RayPickResult& rayPickResult);
|
||||||
|
|
||||||
enum ContactEventType {
|
enum ContactEventType {
|
||||||
CONTACT_EVENT_TYPE_START,
|
CONTACT_EVENT_TYPE_START,
|
||||||
CONTACT_EVENT_TYPE_CONTINUE,
|
CONTACT_EVENT_TYPE_CONTINUE,
|
||||||
|
|
Loading…
Reference in a new issue