mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 12:57:38 +02:00
c++ side laserpointer rendering with renderstates
This commit is contained in:
parent
6f970fd7a0
commit
8f533636f5
9 changed files with 127 additions and 5 deletions
|
@ -4925,6 +4925,11 @@ void Application::update(float deltaTime) {
|
|||
RayPickManager::getInstance().update();
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(app, "LaserPointerManager");
|
||||
LaserPointerManager::getInstance().update();
|
||||
}
|
||||
|
||||
// Update _viewFrustum with latest camera and view frustum data...
|
||||
// NOTE: we get this from the view frustum, to make it simpler, since the
|
||||
// loadViewFrumstum() method will get the correct details from the camera
|
||||
|
|
|
@ -21,10 +21,19 @@ LaserPointer::LaserPointer(const QString& jointName, const glm::vec3& posOffset,
|
|||
_renderStates(renderStates)
|
||||
{
|
||||
_rayPickUID = RayPickManager::getInstance().addRayPick(std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled));
|
||||
|
||||
if (!enabled) {
|
||||
disableCurrentRenderState();
|
||||
}
|
||||
}
|
||||
|
||||
LaserPointer::~LaserPointer() {
|
||||
RayPickManager::getInstance().removeRayPick(_rayPickUID);
|
||||
for (RenderState& renderState : _renderStates) {
|
||||
if (!renderState.getStartID().isNull()) qApp->getOverlays().deleteOverlay(renderState.getStartID());
|
||||
if (!renderState.getPathID().isNull()) qApp->getOverlays().deleteOverlay(renderState.getPathID());
|
||||
if (!renderState.getEndID().isNull()) qApp->getOverlays().deleteOverlay(renderState.getEndID());
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointer::enable() {
|
||||
|
@ -35,20 +44,87 @@ void LaserPointer::enable() {
|
|||
void LaserPointer::disable() {
|
||||
RayPickManager::getInstance().disableRayPick(_rayPickUID);
|
||||
_renderingEnabled = false;
|
||||
if (!_currentRenderState.isEmpty() && _renderStates.contains(_currentRenderState)) disableCurrentRenderState();
|
||||
}
|
||||
|
||||
void LaserPointer::setRenderState(const QString& state) {
|
||||
if (!_currentRenderState.isEmpty() && _renderStates.contains(_currentRenderState)) disableCurrentRenderState();
|
||||
_currentRenderState = state;
|
||||
}
|
||||
|
||||
const RayPickResult& LaserPointer::getPrevRayPickResult() {
|
||||
return RayPickManager::getInstance().getPrevRayPickResult(_rayPickUID);
|
||||
}
|
||||
|
||||
void LaserPointer::disableCurrentRenderState() {
|
||||
if (!_renderStates[_currentRenderState].getStartID().isNull()) {
|
||||
QVariantMap startProps;
|
||||
startProps.insert("visible", false);
|
||||
startProps.insert("ignoreRayIntersection", true);
|
||||
qApp->getOverlays().editOverlay(_renderStates[_currentRenderState].getStartID(), startProps);
|
||||
}
|
||||
if (!_renderStates[_currentRenderState].getPathID().isNull()) {
|
||||
QVariantMap pathProps;
|
||||
pathProps.insert("visible", false);
|
||||
pathProps.insert("ignoreRayIntersection", true);
|
||||
qApp->getOverlays().editOverlay(_renderStates[_currentRenderState].getPathID(), pathProps);
|
||||
}
|
||||
if (!_renderStates[_currentRenderState].getEndID().isNull()) {
|
||||
QVariantMap endProps;
|
||||
endProps.insert("visible", false);
|
||||
endProps.insert("ignoreRayIntersection", true);
|
||||
qApp->getOverlays().editOverlay(_renderStates[_currentRenderState].getEndID(), endProps);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointer::update() {
|
||||
RayPickResult prevRayPickResult = RayPickManager::getInstance().getPrevRayPickResult(_rayPickUID);
|
||||
if (_renderingEnabled && !_currentRenderState.isEmpty() && _renderStates.contains(_currentRenderState) && prevRayPickResult.type != IntersectionType::NONE) {
|
||||
PickRay pickRay = RayPickManager::getInstance().getPickRay(_rayPickUID);
|
||||
if (!_renderStates[_currentRenderState].getStartID().isNull()) {
|
||||
QVariantMap startProps;
|
||||
startProps.insert("position", vec3toVariant(pickRay.origin));
|
||||
startProps.insert("visible", true);
|
||||
startProps.insert("ignoreRayIntersection", _renderStates[_currentRenderState].doesStartIgnoreRays());
|
||||
qApp->getOverlays().editOverlay(_renderStates[_currentRenderState].getStartID(), startProps);
|
||||
}
|
||||
QVariant end = vec3toVariant(pickRay.origin + pickRay.direction * prevRayPickResult.distance);
|
||||
if (!_renderStates[_currentRenderState].getPathID().isNull()) {
|
||||
QVariantMap pathProps;
|
||||
pathProps.insert("start", vec3toVariant(pickRay.origin));
|
||||
pathProps.insert("end", end);
|
||||
pathProps.insert("visible", true);
|
||||
pathProps.insert("ignoreRayIntersection", _renderStates[_currentRenderState].doesPathIgnoreRays());
|
||||
qApp->getOverlays().editOverlay(_renderStates[_currentRenderState].getPathID(), pathProps);
|
||||
}
|
||||
if (!_renderStates[_currentRenderState].getEndID().isNull()) {
|
||||
QVariantMap endProps;
|
||||
endProps.insert("position", end);
|
||||
endProps.insert("visible", true);
|
||||
endProps.insert("ignoreRayIntersection", _renderStates[_currentRenderState].doesEndIgnoreRays());
|
||||
qApp->getOverlays().editOverlay(_renderStates[_currentRenderState].getEndID(), endProps);
|
||||
}
|
||||
} else {
|
||||
disableCurrentRenderState();
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointer::render(RenderArgs* args) {
|
||||
if (_renderingEnabled && !_currentRenderState.isEmpty() && _renderStates.contains(_currentRenderState)) {
|
||||
_renderStates[_currentRenderState].render(args);
|
||||
}
|
||||
}
|
||||
|
||||
RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) :
|
||||
_startID(startID), _pathID(pathID), _endID(endID)
|
||||
{
|
||||
if (!_startID.isNull()) _startIgnoreRays = qApp->getOverlays().getOverlay(_startID)->getProperty("ignoreRayIntersection").toBool();
|
||||
if (!_pathID.isNull()) _pathIgnoreRays = qApp->getOverlays().getOverlay(_pathID)->getProperty("ignoreRayIntersection").toBool();
|
||||
if (!_endID.isNull()) _endIgnoreRays = qApp->getOverlays().getOverlay(_endID)->getProperty("ignoreRayIntersection").toBool();
|
||||
}
|
||||
|
||||
void RenderState::render(RenderArgs * args) {
|
||||
if (!_startID.isNull()) qApp->getOverlays().getOverlay(_startID)->render(args);
|
||||
if (!_pathID.isNull()) qApp->getOverlays().getOverlay(_pathID)->render(args);
|
||||
if (!_endID.isNull()) qApp->getOverlays().getOverlay(_endID)->render(args);
|
||||
}
|
||||
}
|
|
@ -22,15 +22,24 @@ class RenderState {
|
|||
|
||||
public:
|
||||
RenderState() {}
|
||||
RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) :
|
||||
_startID(startID), _pathID(pathID), _endID(endID) {}
|
||||
RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID);
|
||||
|
||||
void render(RenderArgs* args);
|
||||
|
||||
const OverlayID& getStartID() { return _startID; }
|
||||
const OverlayID& getPathID() { return _pathID; }
|
||||
const OverlayID& getEndID() { return _endID; }
|
||||
const bool& doesStartIgnoreRays() { return _startIgnoreRays; }
|
||||
const bool& doesPathIgnoreRays() { return _pathIgnoreRays; }
|
||||
const bool& doesEndIgnoreRays() { return _endIgnoreRays; }
|
||||
|
||||
private:
|
||||
OverlayID _startID;
|
||||
OverlayID _pathID;
|
||||
OverlayID _endID;
|
||||
bool _startIgnoreRays;
|
||||
bool _pathIgnoreRays;
|
||||
bool _endIgnoreRays;
|
||||
};
|
||||
|
||||
|
||||
|
@ -45,10 +54,13 @@ public:
|
|||
void enable();
|
||||
void disable();
|
||||
|
||||
void setRenderState(const QString& state) { _currentRenderState = state; }
|
||||
void setRenderState(const QString& state);
|
||||
|
||||
const RayPickResult& getPrevRayPickResult();
|
||||
|
||||
void disableCurrentRenderState();
|
||||
|
||||
void update();
|
||||
void render(RenderArgs* args);
|
||||
const render::ShapeKey getShapeKey() { return render::ShapeKey::Builder::ownPipeline(); }
|
||||
|
||||
|
|
|
@ -37,9 +37,21 @@ void LaserPointerManager::disableLaserPointer(const unsigned int uid) {
|
|||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setRenderState(unsigned int uid, const QString & renderState) {
|
||||
if (_laserPointers.contains(uid)) {
|
||||
_laserPointers[uid]->setRenderState(renderState);
|
||||
}
|
||||
}
|
||||
|
||||
const RayPickResult& LaserPointerManager::getPrevRayPickResult(const unsigned int uid) {
|
||||
if (_laserPointers.contains(uid)) {
|
||||
return _laserPointers[uid]->getPrevRayPickResult();
|
||||
}
|
||||
return RayPickResult();
|
||||
}
|
||||
|
||||
void LaserPointerManager::update() {
|
||||
for (auto& laserPointer : _laserPointers) {
|
||||
laserPointer->update();
|
||||
}
|
||||
}
|
|
@ -30,8 +30,11 @@ public:
|
|||
void removeLaserPointer(const unsigned int uid) { _laserPointers.remove(uid); }
|
||||
void enableLaserPointer(const unsigned int uid);
|
||||
void disableLaserPointer(const unsigned int uid);
|
||||
void setRenderState(unsigned int uid, const QString& renderState);
|
||||
const RayPickResult& getPrevRayPickResult(const unsigned int uid);
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
QHash<unsigned int, std::shared_ptr<LaserPointer>> _laserPointers;
|
||||
|
||||
|
|
|
@ -74,7 +74,8 @@ uint32_t LaserPointerScriptingInterface::createLaserPointer(const QVariant& prop
|
|||
QUuid pathID;
|
||||
if (renderStateMap["path"].isValid()) {
|
||||
QVariantMap pathMap = renderStateMap["path"].toMap();
|
||||
if (pathMap["type"].isValid()) {
|
||||
// right now paths must be line3ds
|
||||
if (pathMap["type"].isValid() && pathMap["type"].toString() == "line3d") {
|
||||
pathID = qApp->getOverlays().addOverlay(pathMap["type"].toString(), pathMap);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ public slots:
|
|||
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 removeLaserPointer(unsigned int uid) { LaserPointerManager::getInstance().removeLaserPointer(uid); }
|
||||
Q_INVOKABLE void setRenderState(unsigned int uid, const QString& renderState) { LaserPointerManager::getInstance().setRenderState(uid, renderState); }
|
||||
Q_INVOKABLE RayPickResult getPrevRayPickResult(unsigned int uid) { return LaserPointerManager::getInstance().getPrevRayPickResult(uid); }
|
||||
|
||||
};
|
||||
|
|
|
@ -178,6 +178,17 @@ void RayPickManager::disableRayPick(const unsigned int uid) {
|
|||
}
|
||||
}
|
||||
|
||||
const PickRay& RayPickManager::getPickRay(const unsigned int uid) {
|
||||
if (_rayPicks.contains(uid)) {
|
||||
bool valid;
|
||||
PickRay pickRay = _rayPicks[uid]->getPickRay(valid);
|
||||
if (valid) {
|
||||
return pickRay;
|
||||
}
|
||||
}
|
||||
return PickRay();
|
||||
}
|
||||
|
||||
const RayPickResult& RayPickManager::getPrevRayPickResult(const unsigned int uid) {
|
||||
// TODO:
|
||||
// does this need to lock the individual ray? what happens with concurrent set/get?
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
void removeRayPick(const unsigned int uid);
|
||||
void enableRayPick(const unsigned int uid);
|
||||
void disableRayPick(const unsigned int uid);
|
||||
const PickRay& getPickRay(const unsigned int uid);
|
||||
const RayPickResult& getPrevRayPickResult(const unsigned int uid);
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in a new issue