diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f0b119b940..285b9f140b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -8748,7 +8748,7 @@ void Application::createLoginDialog() { EntityItemProperties properties; properties.setType(EntityTypes::Web); properties.setName("LoginDialogEntity"); - properties.setSourceUrl(LOGIN_DIALOG); + properties.setSourceUrl(LOGIN_DIALOG.toString()); properties.setPosition(position); properties.setRotation(cameraOrientation); properties.setDimensions(LOGIN_DIMENSIONS); diff --git a/interface/src/avatar/OtherAvatar.h b/interface/src/avatar/OtherAvatar.h index d4628a0478..bf22da4d5e 100644 --- a/interface/src/avatar/OtherAvatar.h +++ b/interface/src/avatar/OtherAvatar.h @@ -57,7 +57,7 @@ protected: void onRemoveAttachedAvatarEntity(const QUuid& id); std::vector _attachedAvatarEntities; - QUuid _otherAvatarOrbMeshPlaceholderID { UNKNOWN_ENTITY_ID }; + QUuid _otherAvatarOrbMeshPlaceholderID; AvatarMotionState* _motionState { nullptr }; int32_t _spaceIndex { -1 }; uint8_t _workloadRegion { workload::Region::INVALID }; diff --git a/interface/src/raypick/ParabolaPointer.h b/interface/src/raypick/ParabolaPointer.h index 5594f101d0..d4b705a7d2 100644 --- a/interface/src/raypick/ParabolaPointer.h +++ b/interface/src/raypick/ParabolaPointer.h @@ -10,6 +10,8 @@ #include "PathPointer.h" +#include + class ParabolaPointer : public PathPointer { using Parent = PathPointer; public: diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp index e35f4584a6..5b45d5efe9 100644 --- a/interface/src/raypick/RayPick.cpp +++ b/interface/src/raypick/RayPick.cpp @@ -102,6 +102,11 @@ glm::vec2 RayPick::projectOntoXYPlane(const glm::vec3& worldPos, const glm::vec3 } glm::vec2 RayPick::projectOntoEntityXYPlane(const QUuid& entityID, const glm::vec3& worldPos, bool unNormalized) { - auto props = DependencyManager::get()->getEntityProperties(entityID); + EntityPropertyFlags desiredProperties; + desiredProperties += PROP_POSITION; + desiredProperties += PROP_ROTATION; + desiredProperties += PROP_DIMENSIONS; + desiredProperties += PROP_REGISTRATION_POINT; + auto props = DependencyManager::get()->getEntityProperties(entityID, desiredProperties); return projectOntoXYPlane(worldPos, props.getPosition(), props.getRotation(), props.getDimensions(), props.getRegistrationPoint(), unNormalized); } diff --git a/interface/src/ui/DialogsManager.cpp b/interface/src/ui/DialogsManager.cpp index 435cd66bf7..27e55a8586 100644 --- a/interface/src/ui/DialogsManager.cpp +++ b/interface/src/ui/DialogsManager.cpp @@ -70,7 +70,7 @@ void DialogsManager::hideAddressBar() { tablet->gotoHomeScreen(); hmd->closeTablet(); } - qApp->setKeyboardFocusLocalEntity(UNKNOWN_OVERLAY_ID); + qApp->setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID); setAddressBarVisible(false); } diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index eb43e8cf45..ad38d91ceb 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -302,7 +302,7 @@ void Base3DOverlay::locationChanged(bool tellPhysics) { // FIXME: Overlays shouldn't be deleted when their parents are void Base3DOverlay::parentDeleted() { - qApp->getOverlays().deleteOverlay(getOverlayID()); + qApp->getOverlays().deleteOverlay(Overlay::getID()); } void Base3DOverlay::update(float duration) { diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index daf15e676f..b72ef73104 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -27,15 +27,9 @@ public: void setVisible(bool visible) override; bool queryAACubeNeedsUpdate() const override { return false; } // HACK: queryAACube not relevant for Overlays - virtual OverlayID getOverlayID() const override { return OverlayID(getID().toString()); } - void setOverlayID(OverlayID overlayID) override { setID(overlayID); } - virtual QString getName() const override; void setName(QString name); - // getters - virtual bool is3D() const override { return true; } - virtual render::ItemKey getKey() override; virtual uint32_t fetchMetaSubItems(render::ItemIDs& subItems) const override { subItems.push_back(getRenderItemID()); return (uint32_t) subItems.size(); } virtual scriptable::ScriptableModelBase getScriptableModel() override { return scriptable::ScriptableModelBase(); } diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 5e6a9b116b..9eb9a75432 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -249,17 +249,17 @@ bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityIt return ContextOverlayInterface::destroyContextOverlay(entityItemID, PointerEvent()); } -void ContextOverlayInterface::contextOverlays_mousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event) { - if (overlayID == _contextOverlayID && event.getButton() == PointerEvent::PrimaryButton) { - qCDebug(context_overlay) << "Clicked Context Overlay. Entity ID:" << _currentEntityWithContextOverlay << "Overlay ID:" << overlayID; +void ContextOverlayInterface::contextOverlays_mousePressOnOverlay(const QUuid& id, const PointerEvent& event) { + if (id == _contextOverlayID && event.getButton() == PointerEvent::PrimaryButton) { + qCDebug(context_overlay) << "Clicked Context Overlay. Entity ID:" << _currentEntityWithContextOverlay << "ID:" << id; emit contextOverlayClicked(_currentEntityWithContextOverlay); _contextOverlayJustClicked = true; } } -void ContextOverlayInterface::contextOverlays_hoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event) { +void ContextOverlayInterface::contextOverlays_hoverEnterOverlay(const QUuid& id, const PointerEvent& event) { if (_contextOverlayID != UNKNOWN_ENTITY_ID) { - qCDebug(context_overlay) << "Started hovering over Context Overlay. Overlay ID:" << overlayID; + qCDebug(context_overlay) << "Started hovering over Context Overlay. ID:" << id; EntityItemProperties properties; properties.setColor(CONTEXT_OVERLAY_COLOR); properties.getPulse().setColorMode(PulseMode::NONE); @@ -269,9 +269,9 @@ void ContextOverlayInterface::contextOverlays_hoverEnterOverlay(const OverlayID& } } -void ContextOverlayInterface::contextOverlays_hoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event) { +void ContextOverlayInterface::contextOverlays_hoverLeaveOverlay(const QUuid& id, const PointerEvent& event) { if (_contextOverlayID != UNKNOWN_ENTITY_ID) { - qCDebug(context_overlay) << "Stopped hovering over Context Overlay. Overlay ID:" << overlayID; + qCDebug(context_overlay) << "Stopped hovering over Context Overlay. ID:" << id; EntityItemProperties properties; properties.setColor(CONTEXT_OVERLAY_COLOR); properties.getPulse().setColorMode(PulseMode::IN_PHASE); @@ -281,17 +281,17 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveOverlay(const OverlayID& } } -void ContextOverlayInterface::contextOverlays_hoverEnterEntity(const EntityItemID& entityID, const PointerEvent& event) { +void ContextOverlayInterface::contextOverlays_hoverEnterEntity(const EntityItemID& id, const PointerEvent& event) { bool isMouse = event.getID() == PointerManager::MOUSE_POINTER_ID || DependencyManager::get()->isMouse(event.getID()); - if (contextOverlayFilterPassed(entityID) && _enabled && !isMouse) { - enableEntityHighlight(entityID); + if (contextOverlayFilterPassed(id) && _enabled && !isMouse) { + enableEntityHighlight(id); } } -void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemID& entityID, const PointerEvent& event) { +void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemID& id, const PointerEvent& event) { bool isMouse = event.getID() == PointerManager::MOUSE_POINTER_ID || DependencyManager::get()->isMouse(event.getID()); - if (_currentEntityWithContextOverlay != entityID && _enabled && !isMouse) { - disableEntityHighlight(entityID); + if (_currentEntityWithContextOverlay != id && _enabled && !isMouse) { + disableEntityHighlight(id); } } @@ -388,12 +388,12 @@ void ContextOverlayInterface::requestOwnershipVerification(const QUuid& entityID } } -void ContextOverlayInterface::enableEntityHighlight(const EntityItemID& entityItemID) { - _selectionScriptingInterface->addToSelectedItemsList("contextOverlayHighlightList", "entity", entityItemID); +void ContextOverlayInterface::enableEntityHighlight(const EntityItemID& entityID) { + _selectionScriptingInterface->addToSelectedItemsList("contextOverlayHighlightList", "entity", entityID); } -void ContextOverlayInterface::disableEntityHighlight(const EntityItemID& entityItemID) { - _selectionScriptingInterface->removeFromSelectedItemsList("contextOverlayHighlightList", "entity", entityItemID); +void ContextOverlayInterface::disableEntityHighlight(const EntityItemID& entityID) { + _selectionScriptingInterface->removeFromSelectedItemsList("contextOverlayHighlightList", "entity", entityID); } void ContextOverlayInterface::deletingEntity(const EntityItemID& entityID) { diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index 2c6607a664..b87535acf2 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -65,9 +65,9 @@ public slots: bool createOrDestroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event); bool destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event); bool destroyContextOverlay(const EntityItemID& entityItemID); - void contextOverlays_mousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event); - void contextOverlays_hoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event); - void contextOverlays_hoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event); + void contextOverlays_mousePressOnOverlay(const QUuid& id, const PointerEvent& event); + void contextOverlays_hoverEnterOverlay(const QUuid& id, const PointerEvent& event); + void contextOverlays_hoverLeaveOverlay(const QUuid& id, const PointerEvent& event); void contextOverlays_hoverEnterEntity(const EntityItemID& entityID, const PointerEvent& event); void contextOverlays_hoverLeaveEntity(const EntityItemID& entityID, const PointerEvent& event); bool contextOverlayFilterPassed(const EntityItemID& entityItemID); diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 9888d696cf..128281faee 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -189,7 +189,7 @@ scriptable::ScriptableModelBase Cube3DOverlay::getScriptableModel() { auto vertexColor = ColorUtils::toVec3(_color); scriptable::ScriptableModelBase result; if (auto mesh = geometryCache->meshFromShape(GeometryCache::Cube, vertexColor)) { - result.objectID = getID(); + result.objectID = Overlay::getID(); result.append(mesh); } return result; diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 14e5cdc7f5..92a316690a 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -92,7 +92,7 @@ void ModelOverlay::update(float deltatime) { render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; if (_model->needsFixupInScene()) { - emit DependencyManager::get()->modelRemovedFromScene(getID(), NestableType::Overlay, _model); + emit DependencyManager::get()->modelRemovedFromScene(Overlay::getID(), NestableType::Overlay, _model); _model->removeFromScene(scene, transaction); _model->addToScene(scene, transaction); @@ -101,8 +101,7 @@ void ModelOverlay::update(float deltatime) { auto modelOverlay = static_cast(&data); modelOverlay->setSubRenderItemIDs(newRenderItemIDs); }); - processMaterials(); - emit DependencyManager::get()->modelAddedToScene(getID(), NestableType::Overlay, _model); + emit DependencyManager::get()->modelAddedToScene(Overlay::getID(), NestableType::Overlay, _model); } bool metaDirty = false; if (_visibleDirty && _texturesLoaded) { @@ -145,15 +144,14 @@ void ModelOverlay::update(float deltatime) { bool ModelOverlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { Volume3DOverlay::addToScene(overlay, scene, transaction); _model->addToScene(scene, transaction); - processMaterials(); - emit DependencyManager::get()->modelAddedToScene(getID(), NestableType::Overlay, _model); + emit DependencyManager::get()->modelAddedToScene(Overlay::getID(), NestableType::Overlay, _model); return true; } void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { Volume3DOverlay::removeFromScene(overlay, scene, transaction); _model->removeFromScene(scene, transaction); - emit DependencyManager::get()->modelRemovedFromScene(getID(), NestableType::Overlay, _model); + emit DependencyManager::get()->modelRemovedFromScene(Overlay::getID(), NestableType::Overlay, _model); transaction.updateItem(getRenderItemID(), [](Overlay& data) { auto modelOverlay = static_cast(&data); modelOverlay->clearSubRenderItemIDs(); @@ -709,32 +707,6 @@ uint32_t ModelOverlay::fetchMetaSubItems(render::ItemIDs& subItems) const { return 0; } -void ModelOverlay::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) { - Overlay::addMaterial(material, parentMaterialName); - if (_model && _model->fetchRenderItemIDs().size() > 0) { - _model->addMaterial(material, parentMaterialName); - } -} - -void ModelOverlay::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) { - Overlay::removeMaterial(material, parentMaterialName); - if (_model && _model->fetchRenderItemIDs().size() > 0) { - _model->removeMaterial(material, parentMaterialName); - } -} - -void ModelOverlay::processMaterials() { - assert(_model); - std::lock_guard lock(_materialsLock); - for (auto& shapeMaterialPair : _materials) { - auto material = shapeMaterialPair.second; - while (!material.empty()) { - _model->addMaterial(material.top(), shapeMaterialPair.first); - material.pop(); - } - } -} - bool ModelOverlay::canReplaceModelMeshPart(int meshIndex, int partIndex) { // TODO: bounds checking; for now just used to indicate provider generally supports mesh updates return _model && _model->isLoaded(); @@ -750,11 +722,7 @@ scriptable::ScriptableModelBase ModelOverlay::getScriptableModel() { return Base3DOverlay::getScriptableModel(); } auto result = _model->getScriptableModel(); - result.objectID = getID(); - { - std::lock_guard lock(_materialsLock); - result.appendMaterials(_materials); - } + result.objectID = Overlay::getID(); return result; } diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index 17a2327d02..63ffeaaafe 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -70,9 +70,6 @@ public: void setDrawHUDLayer(bool drawHUDLayer) override; void setGroupCulled(bool groupCulled); - void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) override; - void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) override; - virtual scriptable::ScriptableModelBase getScriptableModel() override; virtual bool canReplaceModelMeshPart(int meshIndex, int partIndex) override; virtual bool replaceScriptableModelMeshPart(scriptable::ScriptableModelBasePointer model, int meshIndex, int partIndex) override; @@ -130,8 +127,6 @@ private: bool _isGroupCulled { false }; bool _groupCulledDirty { false }; - void processMaterials(); - }; #endif // hifi_ModelOverlay_h diff --git a/interface/src/ui/overlays/Overlay2D.h b/interface/src/ui/overlays/Overlay2D.h index 3175df92f1..5417dbd9e0 100644 --- a/interface/src/ui/overlays/Overlay2D.h +++ b/interface/src/ui/overlays/Overlay2D.h @@ -23,8 +23,6 @@ public: Overlay2D(const Overlay2D* overlay2D); virtual AABox getBounds() const override; - - virtual bool is3D() const override { return false; } virtual uint32_t fetchMetaSubItems(render::ItemIDs& subItems) const override { subItems.push_back(getRenderItemID()); return 1; } diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index df65b26a3f..69d3883de7 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -21,20 +21,15 @@ #include "Application.h" #include "InterfaceLogging.h" -#include "Image3DOverlay.h" -#include "Circle3DOverlay.h" -#include "Cube3DOverlay.h" -#include "Shape3DOverlay.h" + #include "ImageOverlay.h" -#include "Line3DOverlay.h" -#include "ModelOverlay.h" -#include "Rectangle3DOverlay.h" -#include "Sphere3DOverlay.h" -#include "Grid3DOverlay.h" #include "TextOverlay.h" #include "RectangleOverlay.h" -#include "Text3DOverlay.h" -#include "Web3DOverlay.h" + +#include + +#include + #include "ui/Keyboard.h" #include @@ -42,6 +37,9 @@ Q_LOGGING_CATEGORY(trace_render_overlays, "trace.render.overlays") +std::unordered_map Overlays::_entityToOverlayTypes; +std::unordered_map Overlays::_overlayToEntityTypes; + Overlays::Overlays() { auto pointerManager = DependencyManager::get(); connect(pointerManager.data(), &PointerManager::hoverBeginOverlay, this, &Overlays::hoverEnterPointerEvent); @@ -50,6 +48,17 @@ Overlays::Overlays() { connect(pointerManager.data(), &PointerManager::triggerBeginOverlay, this, &Overlays::mousePressPointerEvent); connect(pointerManager.data(), &PointerManager::triggerContinueOverlay, this, &Overlays::mouseMovePointerEvent); connect(pointerManager.data(), &PointerManager::triggerEndOverlay, this, &Overlays::mouseReleasePointerEvent); + + ADD_TYPE_MAP(Box, cube); + ADD_TYPE_MAP(Sphere, sphere); + ADD_TYPE_MAP(Shape, shape); + ADD_TYPE_MAP(Model, model); + ADD_TYPE_MAP(Text, text3d); + ADD_TYPE_MAP(Image, image3d); + ADD_TYPE_MAP(Web, web3d); + ADD_TYPE_MAP(PolyLine, line3d); + ADD_TYPE_MAP(Grid, grid); + ADD_TYPE_MAP(Gizmo, circle3d); } void Overlays::cleanupAllOverlays() { @@ -151,9 +160,39 @@ Overlay::Pointer Overlays::get2DOverlay(const QUuid& id) const { return nullptr; } +QString Overlays::entityToOverlayType(const QString& type) { + auto iter = _entityToOverlayTypes.find(type); + if (iter != _entityToOverlayTypes.end()) { + return iter->second; + } + return "unknown"; +} + +QString Overlays::overlayToEntityType(const QString& type) { + auto iter = _overlayToEntityTypes.find(type); + if (iter != _overlayToEntityTypes.end()) { + return iter->second; + } else if (type == "billboard") { + return "Image"; + } + return "Unknown"; +} + +EntityItemProperties convertOverlayToEntityProperties(const QVariantMap& overlayProps) { + EntityItemProperties props; + + return props; +} + +QVariantMap convertEntityToOverlayProperties(const EntityItemProperties& entityProps) { + QVariantMap props; + + return props; +} + QUuid Overlays::addOverlay(const QString& type, const QVariant& properties) { if (_shuttingDown) { - return UNKNOWN_OVERLAY_ID; + return UNKNOWN_ENTITY_ID; } if (QThread::currentThread() != thread()) { @@ -163,8 +202,6 @@ QUuid Overlays::addOverlay(const QString& type, const QVariant& properties) { return result; } - Overlay::Pointer thisOverlay = nullptr; - /**jsdoc *

An overlay may be one of the following types:

* @@ -172,26 +209,26 @@ QUuid Overlays::addOverlay(const QString& type, const QVariant& properties) { * * * + * + * + * * * * - * * * * - * * * * - * * * * *
Value2D/3DDescription
image2DAn image. Synonym: billboard.
rectangle2DA rectangle.
text2DText.
circle3d3DA circle.
cube3DA cube. Can also use a shape overlay to create a * cube.
grid3DA grid of lines in a plane.
image2DAn image. Synonym: billboard.
image3d3DAn image.
line3d3DA line.
model3DA model.
rectangle2DA rectangle.
rectangle3d3DA rectangle.
shape3DA geometric shape, such as a cube, sphere, or cylinder.
sphere3DA sphere. Can also use a shape overlay to create a * sphere.
text2DText.
text3d3DText.
web3d3DWeb content.
*

2D overlays are rendered on the display surface in desktop mode and on the HUD surface in HMD mode. 3D overlays are - * rendered at a position and orientation in-world.

+ * rendered at a position and orientation in-world, but are deprecated (use local entities instead).

*

Each overlay type has different {@link Overlays.OverlayProperties|OverlayProperties}.

* @typedef {string} Overlays.OverlayType */ @@ -203,18 +240,18 @@ QUuid Overlays::addOverlay(const QString& type, const QVariant& properties) { * {@link Overlays.OverlayType|OverlayType}Overlay Properties * * + * image{@link Overlays.ImageProperties|ImageProperties} + * rectangle{@link Overlays.RectangleProperties|RectangleProperties} + * text{@link Overlays.TextProperties|TextProperties} * circle3d{@link Overlays.Circle3DProperties|Circle3DProperties} * cube{@link Overlays.CubeProperties|CubeProperties} * grid{@link Overlays.GridProperties|GridProperties} - * image{@link Overlays.ImageProperties|ImageProperties} * image3d{@link Overlays.Image3DProperties|Image3DProperties} * line3d{@link Overlays.Line3DProperties|Line3DProperties} * model{@link Overlays.ModelProperties|ModelProperties} - * rectangle{@link Overlays.RectangleProperties|RectangleProperties} * rectangle3d{@link Overlays.Rectangle3DProperties|Rectangle3DProperties} * shape{@link Overlays.ShapeProperties|ShapeProperties} * sphere{@link Overlays.SphereProperties|SphereProperties} - * text{@link Overlays.TextProperties|TextProperties} * text3d{@link Overlays.Text3DProperties|Text3DProperties} * web3d{@link Overlays.Web3DProperties|Web3DProperties} * @@ -222,54 +259,42 @@ QUuid Overlays::addOverlay(const QString& type, const QVariant& properties) { * @typedef {object} Overlays.OverlayProperties */ + Overlay::Pointer overlay; if (type == ImageOverlay::TYPE) { #if !defined(DISABLE_QML) - thisOverlay = Overlay::Pointer(new ImageOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); + overlay = Overlay::Pointer(new ImageOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); #endif - } else if (type == Image3DOverlay::TYPE || type == "billboard") { // "billboard" for backwards compatibility - thisOverlay = Overlay::Pointer(new Image3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); } else if (type == TextOverlay::TYPE) { #if !defined(DISABLE_QML) - thisOverlay = Overlay::Pointer(new TextOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); + overlay = Overlay::Pointer(new TextOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); #endif - } else if (type == Text3DOverlay::TYPE) { - thisOverlay = Overlay::Pointer(new Text3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); - } else if (type == Shape3DOverlay::TYPE) { - thisOverlay = Overlay::Pointer(new Shape3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); - } else if (type == Cube3DOverlay::TYPE) { - thisOverlay = Overlay::Pointer(new Cube3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); - } else if (type == Sphere3DOverlay::TYPE) { - thisOverlay = Overlay::Pointer(new Sphere3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); - } else if (type == Circle3DOverlay::TYPE) { - thisOverlay = Overlay::Pointer(new Circle3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); - } else if (type == Rectangle3DOverlay::TYPE) { - thisOverlay = Overlay::Pointer(new Rectangle3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); - } else if (type == Line3DOverlay::TYPE) { - thisOverlay = Overlay::Pointer(new Line3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); - } else if (type == Grid3DOverlay::TYPE) { - thisOverlay = Overlay::Pointer(new Grid3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); - } else if (type == ModelOverlay::TYPE) { - thisOverlay = Overlay::Pointer(new ModelOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); - } else if (type == Web3DOverlay::TYPE) { - thisOverlay = Overlay::Pointer(new Web3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); } else if (type == RectangleOverlay::TYPE) { - thisOverlay = Overlay::Pointer(new RectangleOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); + overlay = Overlay::Pointer(new RectangleOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); } - if (thisOverlay) { - thisOverlay->setProperties(properties.toMap()); - return add2DOverlay(thisOverlay); + if (overlay) { + overlay->setProperties(properties.toMap()); + return add2DOverlay(overlay); } - return UNKNOWN_OVERLAY_ID; + + QString entityType = overlayToEntityType(type); + + if (entityType == "Unknown") { + return UNKNOWN_ENTITY_ID; + } + + QVariantMap propertyMap = properties.toMap(); + propertyMap["type"] = entityType; + return DependencyManager::get()->addEntity(convertOverlayToEntityProperties(propertyMap), "local"); } QUuid Overlays::add2DOverlay(const Overlay::Pointer& overlay) { if (_shuttingDown) { - return UNKNOWN_OVERLAY_ID; + return UNKNOWN_ENTITY_ID; } QUuid thisID = QUuid::createUuid(); - overlay->setOverlayID(thisID); + overlay->setID(thisID); overlay->setStackOrder(_stackOrder++); { QMutexLocker locker(&_mutex); @@ -281,7 +306,7 @@ QUuid Overlays::add2DOverlay(const Overlay::Pointer& overlay) { QUuid Overlays::cloneOverlay(const QUuid& id) { if (_shuttingDown) { - return UNKNOWN_OVERLAY_ID; + return UNKNOWN_ENTITY_ID; } if (QThread::currentThread() != thread()) { @@ -486,111 +511,70 @@ RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray, const QScriptValue& overlayIDsToInclude, const QScriptValue& overlayIDsToDiscard, bool visibleOnly, bool collidableOnly) { - const QVector overlaysToInclude = qVectorQUuidFromScriptValue(overlayIDsToInclude); - const QVector overlaysToDiscard = qVectorQUuidFromScriptValue(overlayIDsToDiscard); + const QVector include = qVectorEntityItemIDFromScriptValue(overlayIDsToInclude); + const QVector discard = qVectorEntityItemIDFromScriptValue(overlayIDsToDiscard); - return findRayIntersectionVector(ray, precisionPicking, - overlaysToInclude, overlaysToDiscard, visibleOnly, collidableOnly); + return findRayIntersectionVector(ray, precisionPicking, include, discard, visibleOnly, collidableOnly); } - RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay& ray, bool precisionPicking, - const QVector& overlaysToInclude, - const QVector& overlaysToDiscard, + const QVector& include, + const QVector& discard, bool visibleOnly, bool collidableOnly) { - float bestDistance = std::numeric_limits::max(); - bool bestIsFront = false; - bool bestIsTablet = false; - auto tabletIDs = qApp->getTabletIDs(); + unsigned int searchFilter = PickFilter::getBitMask(PickFilter::FlagBit::LOCAL_ENTITIES); - QMutexLocker locker(&_mutex); - RayToOverlayIntersectionResult result; - QMapIterator i(_overlaysWorld); - while (i.hasNext()) { - i.next(); - OverlayID thisID = i.key(); - auto thisOverlay = std::dynamic_pointer_cast(i.value()); - - if ((overlaysToDiscard.size() > 0 && overlaysToDiscard.contains(thisID)) || - (overlaysToInclude.size() > 0 && !overlaysToInclude.contains(thisID))) { - continue; - } - - if (thisOverlay && thisOverlay->getVisible() && !thisOverlay->getIgnorePickIntersection() && thisOverlay->isLoaded()) { - float thisDistance; - BoxFace thisFace; - glm::vec3 thisSurfaceNormal; - QVariantMap thisExtraInfo; - if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance, - thisFace, thisSurfaceNormal, thisExtraInfo, precisionPicking)) { - bool isDrawInFront = thisOverlay->getDrawInFront(); - bool isTablet = tabletIDs.contains(thisID); - if ((isDrawInFront && !bestIsFront && !bestIsTablet) - || ((isTablet || isDrawInFront || !bestIsFront) && thisDistance < bestDistance)) { - bestIsFront = isDrawInFront; - bestIsTablet = isTablet; - bestDistance = thisDistance; - result.intersects = true; - result.distance = thisDistance; - result.face = thisFace; - result.surfaceNormal = thisSurfaceNormal; - result.overlayID = thisID; - result.intersection = ray.origin + (ray.direction * thisDistance); - result.extraInfo = thisExtraInfo; - } - } - } + if (!precisionPicking) { + searchFilter = searchFilter | PickFilter::getBitMask(PickFilter::FlagBit::COARSE); } - return result; + + if (visibleOnly) { + searchFilter = searchFilter | PickFilter::getBitMask(PickFilter::FlagBit::VISIBLE); + } + + if (collidableOnly) { + searchFilter = searchFilter | PickFilter::getBitMask(PickFilter::FlagBit::COLLIDABLE); + } + auto result = DependencyManager::get()->evalRayIntersectionVector(ray, PickFilter(searchFilter), include, discard); + + RayToOverlayIntersectionResult overlayResult; + overlayResult.overlayID = result.entityID; + overlayResult.intersects = result.intersects; + overlayResult.intersection = result.intersection; + overlayResult.distance = result.distance; + overlayResult.surfaceNormal = result.surfaceNormal; + overlayResult.face = result.face; + overlayResult.extraInfo = result.extraInfo; + return overlayResult; } ParabolaToOverlayIntersectionResult Overlays::findParabolaIntersectionVector(const PickParabola& parabola, bool precisionPicking, - const QVector& overlaysToInclude, - const QVector& overlaysToDiscard, + const QVector& include, + const QVector& discard, bool visibleOnly, bool collidableOnly) { - float bestDistance = std::numeric_limits::max(); - bool bestIsFront = false; - const QVector keyboardKeysToDiscard = DependencyManager::get()->getKeysID(); - QMutexLocker locker(&_mutex); - ParabolaToOverlayIntersectionResult result; - QMapIterator i(_overlaysWorld); - while (i.hasNext()) { - i.next(); - OverlayID thisID = i.key(); - auto thisOverlay = std::dynamic_pointer_cast(i.value()); + unsigned int searchFilter = PickFilter::getBitMask(PickFilter::FlagBit::LOCAL_ENTITIES); - if ((overlaysToDiscard.size() > 0 && overlaysToDiscard.contains(thisID)) || - (overlaysToInclude.size() > 0 && !overlaysToInclude.contains(thisID)) || - (keyboardKeysToDiscard.size() > 0 && keyboardKeysToDiscard.contains(thisID))) { - continue; - } - - if (thisOverlay && thisOverlay->getVisible() && !thisOverlay->getIgnorePickIntersection() && thisOverlay->isLoaded()) { - float thisDistance; - BoxFace thisFace; - glm::vec3 thisSurfaceNormal; - QVariantMap thisExtraInfo; - if (thisOverlay->findParabolaIntersectionExtraInfo(parabola.origin, parabola.velocity, parabola.acceleration, thisDistance, - thisFace, thisSurfaceNormal, thisExtraInfo, precisionPicking)) { - bool isDrawInFront = thisOverlay->getDrawInFront(); - if ((bestIsFront && isDrawInFront && thisDistance < bestDistance) - || (!bestIsFront && (isDrawInFront || thisDistance < bestDistance))) { - - bestIsFront = isDrawInFront; - bestDistance = thisDistance; - result.intersects = true; - result.parabolicDistance = thisDistance; - result.face = thisFace; - result.surfaceNormal = thisSurfaceNormal; - result.overlayID = thisID; - result.intersection = parabola.origin + parabola.velocity * thisDistance + 0.5f * parabola.acceleration * thisDistance * thisDistance; - result.distance = glm::distance(result.intersection, parabola.origin); - result.extraInfo = thisExtraInfo; - } - } - } + if (!precisionPicking) { + searchFilter = searchFilter | PickFilter::getBitMask(PickFilter::FlagBit::COARSE); } - return result; + + if (visibleOnly) { + searchFilter = searchFilter | PickFilter::getBitMask(PickFilter::FlagBit::VISIBLE); + } + + if (collidableOnly) { + searchFilter = searchFilter | PickFilter::getBitMask(PickFilter::FlagBit::COLLIDABLE); + } + auto result = DependencyManager::get()->evalParabolaIntersectionVector(parabola, PickFilter(searchFilter), include, discard); + + ParabolaToOverlayIntersectionResult overlayResult; + overlayResult.overlayID = result.entityID; + overlayResult.intersects = result.intersects; + overlayResult.intersection = result.intersection; + overlayResult.parabolicDistance = result.parabolicDistance; + overlayResult.surfaceNormal = result.surfaceNormal; + overlayResult.face = result.face; + overlayResult.extraInfo = result.extraInfo; + return overlayResult; } QScriptValue RayToOverlayIntersectionResultToScriptValue(QScriptEngine* engine, const RayToOverlayIntersectionResult& value) { @@ -671,28 +655,28 @@ bool Overlays::isAddedOverlay(const QUuid& id) { return DependencyManager::get()->isAddedEntity(id); } -void Overlays::sendMousePressOnOverlay(const QUuid& overlayID, const PointerEvent& event) { - mousePressPointerEvent(overlayID, event); +void Overlays::sendMousePressOnOverlay(const QUuid& id, const PointerEvent& event) { + mousePressPointerEvent(id, event); } -void Overlays::sendMouseReleaseOnOverlay(const QUuid& overlayID, const PointerEvent& event) { - mouseReleasePointerEvent(overlayID, event); +void Overlays::sendMouseReleaseOnOverlay(const QUuid& id, const PointerEvent& event) { + mouseReleasePointerEvent(id, event); } -void Overlays::sendMouseMoveOnOverlay(const QUuid& overlayID, const PointerEvent& event) { - mouseMovePointerEvent(overlayID, event); +void Overlays::sendMouseMoveOnOverlay(const QUuid& id, const PointerEvent& event) { + mouseMovePointerEvent(id, event); } -void Overlays::sendHoverEnterOverlay(const QUuid& overlayID, const PointerEvent& event) { - hoverEnterPointerEvent(overlayID, event); +void Overlays::sendHoverEnterOverlay(const QUuid& id, const PointerEvent& event) { + hoverEnterPointerEvent(id, event); } -void Overlays::sendHoverOverOverlay(const QUuid& overlayID, const PointerEvent& event) { - hoverOverPointerEvent(overlayID, event); +void Overlays::sendHoverOverOverlay(const QUuid& id, const PointerEvent& event) { + hoverOverPointerEvent(id, event); } -void Overlays::sendHoverLeaveOverlay(const QUuid& overlayID, const PointerEvent& event) { - hoverLeavePointerEvent(overlayID, event); +void Overlays::sendHoverLeaveOverlay(const QUuid& id, const PointerEvent& event) { + hoverLeavePointerEvent(id, event); } float Overlays::width() { @@ -719,28 +703,6 @@ float Overlays::height() { return offscreenUi->getWindow()->size().height(); } -static glm::vec2 projectOntoOverlayXYPlane(glm::vec3 position, glm::quat rotation, glm::vec2 dimensions, const PickRay& pickRay, - const RayToOverlayIntersectionResult& rayPickResult) { - - // Project the intersection point onto the local xy plane of the overlay. - float distance; - glm::vec3 planePosition = position; - glm::vec3 planeNormal = rotation * Vectors::UNIT_Z; - glm::vec3 overlayDimensions = glm::vec3(dimensions.x, dimensions.y, 0.0f); - glm::vec3 rayDirection = pickRay.direction; - glm::vec3 rayStart = pickRay.origin; - glm::vec3 p; - if (rayPlaneIntersection(planePosition, planeNormal, rayStart, rayDirection, distance)) { - p = rayStart + rayDirection * distance; - } else { - p = rayPickResult.intersection; - } - glm::vec3 localP = glm::inverse(rotation) * (p - position); - glm::vec3 normalizedP = (localP / overlayDimensions) + glm::vec3(0.5f); - return glm::vec2(normalizedP.x * overlayDimensions.x, - (1.0f - normalizedP.y) * overlayDimensions.y); // flip y-axis -} - static uint32_t toPointerButtons(const QMouseEvent& event) { uint32_t buttons = 0; buttons |= event.buttons().testFlag(Qt::LeftButton) ? PointerEvent::PrimaryButton : 0; @@ -765,32 +727,18 @@ static PointerEvent::Button toPointerButton(const QMouseEvent& event) { PointerEvent Overlays::calculateOverlayPointerEvent(const QUuid& id, const PickRay& ray, const RayToOverlayIntersectionResult& rayPickResult, QMouseEvent* event, PointerEvent::EventType eventType) { - auto overlay = std::dynamic_pointer_cast(getOverlay(id)); - if (getOverlayType(overlayID) == "web3d") { - overlay = std::dynamic_pointer_cast(getOverlay(overlayID)); - } - if (!overlay) { - return PointerEvent(); - } - glm::vec3 position = overlay->getWorldPosition(); - glm::quat rotation = overlay->getWorldOrientation(); - glm::vec2 dimensions = overlay->getSize(); - - - glm::vec2 pos2D = projectOntoOverlayXYPlane(position, rotation, dimensions, ray, rayPickResult); - + glm::vec2 pos2D = RayPick::projectOntoEntityXYPlane(id, rayPickResult.intersection); PointerEvent pointerEvent(eventType, PointerManager::MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal, ray.direction, toPointerButton(*event), toPointerButtons(*event), event->modifiers()); return pointerEvent; } - bool Overlays::mousePressEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mousePressEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), QVector()); + RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), QVector()); if (rayPickResult.intersects) { _currentClickingOnOverlayID = rayPickResult.overlayID; @@ -799,35 +747,33 @@ bool Overlays::mousePressEvent(QMouseEvent* event) { return true; } // if we didn't press on an overlay, disable overlay keyboard focus - setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); + setKeyboardFocusOverlay(UNKNOWN_ENTITY_ID); // emit to scripts emit mousePressOffOverlay(); return false; } -void Overlays::mousePressPointerEvent(const OverlayID& overlayID, const PointerEvent& event) { - // TODO: generalize this to allow any overlay to recieve events - std::shared_ptr thisOverlay; - if (getOverlayType(overlayID) == "web3d") { - thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); - } - if (thisOverlay) { - if (event.shouldFocus()) { - // Focus keyboard on web overlays - DependencyManager::get()->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); - setKeyboardFocusOverlay(overlayID); +void Overlays::mousePressPointerEvent(const QUuid& id, const PointerEvent& event) { + // TODO: generalize this to allow any object to recieve events + auto renderable = qApp->getEntities()->renderableForEntityId(id); + if (renderable) { + auto web = std::dynamic_pointer_cast(renderable); + if (web) { + if (event.shouldFocus()) { + // Focus keyboard on web overlays + DependencyManager::get()->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); + setKeyboardFocusOverlay(id); + } + + web->handlePointerEvent(event); } - - // Send to web overlay - QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); } - auto keyboard = DependencyManager::get(); // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed - if (!keyboard->getKeysID().contains(overlayID)) { + if (!keyboard->getKeysID().contains(id)) { // emit to scripts - emit mousePressOnOverlay(overlayID, event); + emit mousePressOnOverlay(id, event); } } @@ -835,7 +781,7 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), QVector()); + RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), QVector()); if (rayPickResult.intersects) { _currentClickingOnOverlayID = rayPickResult.overlayID; @@ -849,60 +795,57 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { return false; } -void Overlays::hoverEnterPointerEvent(const OverlayID& overlayID, const PointerEvent& event) { - // TODO: generalize this to allow any overlay to recieve events - std::shared_ptr thisOverlay; - if (getOverlayType(overlayID) == "web3d") { - thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); - } - if (thisOverlay) { - // Send to web overlay - QMetaObject::invokeMethod(thisOverlay.get(), "hoverEnterOverlay", Q_ARG(PointerEvent, event)); +void Overlays::hoverEnterPointerEvent(const QUuid& id, const PointerEvent& event) { + // TODO: generalize this to allow any object to recieve events + auto renderable = qApp->getEntities()->renderableForEntityId(id); + if (renderable) { + auto web = std::dynamic_pointer_cast(renderable); + if (web) { + web->hoverEnterEntity(event); + } } auto keyboard = DependencyManager::get(); // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed - if (!keyboard->getKeysID().contains(overlayID)) { + if (!keyboard->getKeysID().contains(id)) { // emit to scripts - emit hoverEnterOverlay(overlayID, event); + emit hoverEnterOverlay(id, event); } } -void Overlays::hoverOverPointerEvent(const OverlayID& overlayID, const PointerEvent& event) { +void Overlays::hoverOverPointerEvent(const QUuid& id, const PointerEvent& event) { // TODO: generalize this to allow any overlay to recieve events - std::shared_ptr thisOverlay; - if (getOverlayType(overlayID) == "web3d") { - thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); - } - if (thisOverlay) { - // Send to web overlay - QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); + auto renderable = qApp->getEntities()->renderableForEntityId(id); + if (renderable) { + auto web = std::dynamic_pointer_cast(renderable); + if (web) { + web->handlePointerEvent(event); + } } auto keyboard = DependencyManager::get(); // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed - if (!keyboard->getKeysID().contains(overlayID)) { + if (!keyboard->getKeysID().contains(id)) { // emit to scripts - emit hoverOverOverlay(overlayID, event); + emit hoverOverOverlay(id, event); } } -void Overlays::hoverLeavePointerEvent(const OverlayID& overlayID, const PointerEvent& event) { +void Overlays::hoverLeavePointerEvent(const QUuid& id, const PointerEvent& event) { // TODO: generalize this to allow any overlay to recieve events - std::shared_ptr thisOverlay; - if (getOverlayType(overlayID) == "web3d") { - thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); - } - if (thisOverlay) { - // Send to web overlay - QMetaObject::invokeMethod(thisOverlay.get(), "hoverLeaveOverlay", Q_ARG(PointerEvent, event)); + auto renderable = qApp->getEntities()->renderableForEntityId(id); + if (renderable) { + auto web = std::dynamic_pointer_cast(renderable); + if (web) { + web->hoverLeaveEntity(event); + } } auto keyboard = DependencyManager::get(); // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed - if (!keyboard->getKeysID().contains(overlayID)) { + if (!keyboard->getKeysID().contains(id)) { // emit to scripts - emit hoverLeaveOverlay(overlayID, event); + emit hoverLeaveOverlay(id, event); } } @@ -910,33 +853,31 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseReleaseEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), - QVector()); + RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), QVector()); if (rayPickResult.intersects) { auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release); mouseReleasePointerEvent(rayPickResult.overlayID, pointerEvent); } - _currentClickingOnOverlayID = UNKNOWN_OVERLAY_ID; + _currentClickingOnOverlayID = UNKNOWN_ENTITY_ID; return false; } -void Overlays::mouseReleasePointerEvent(const OverlayID& overlayID, const PointerEvent& event) { +void Overlays::mouseReleasePointerEvent(const QUuid& id, const PointerEvent& event) { // TODO: generalize this to allow any overlay to recieve events - std::shared_ptr thisOverlay; - if (getOverlayType(overlayID) == "web3d") { - thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); - } - if (thisOverlay) { - // Send to web overlay - QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); + auto renderable = qApp->getEntities()->renderableForEntityId(id); + if (renderable) { + auto web = std::dynamic_pointer_cast(renderable); + if (web) { + web->handlePointerEvent(event); + } } auto keyboard = DependencyManager::get(); // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed - if (!keyboard->getKeysID().contains(overlayID)) { + if (!keyboard->getKeysID().contains(id)) { // emit to scripts - emit mouseReleaseOnOverlay(overlayID, event); + emit mouseReleaseOnOverlay(id, event); } } @@ -944,14 +885,13 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseMoveEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), - QVector()); + RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), QVector()); if (rayPickResult.intersects) { auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move); mouseMovePointerEvent(rayPickResult.overlayID, pointerEvent); // If previously hovering over a different overlay then leave hover on that overlay. - if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID && rayPickResult.overlayID != _currentHoverOverOverlayID) { + if (_currentHoverOverOverlayID != UNKNOWN_ENTITY_ID && rayPickResult.overlayID != _currentHoverOverOverlayID) { auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move); hoverLeavePointerEvent(_currentHoverOverOverlayID, pointerEvent); } @@ -967,33 +907,31 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { _currentHoverOverOverlayID = rayPickResult.overlayID; } else { // If previously hovering an overlay then leave hover. - if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID) { + if (_currentHoverOverOverlayID != UNKNOWN_ENTITY_ID) { auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move); hoverLeavePointerEvent(_currentHoverOverOverlayID, pointerEvent); - _currentHoverOverOverlayID = UNKNOWN_OVERLAY_ID; + _currentHoverOverOverlayID = UNKNOWN_ENTITY_ID; } } return false; } -void Overlays::mouseMovePointerEvent(const OverlayID& overlayID, const PointerEvent& event) { +void Overlays::mouseMovePointerEvent(const QUuid& id, const PointerEvent& event) { // TODO: generalize this to allow any overlay to recieve events - std::shared_ptr thisOverlay; - if (getOverlayType(overlayID) == "web3d") { - thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); - } - if (thisOverlay) { - // Send to web overlay - QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); + auto renderable = qApp->getEntities()->renderableForEntityId(id); + if (renderable) { + auto web = std::dynamic_pointer_cast(renderable); + if (web) { + web->handlePointerEvent(event); + } } auto keyboard = DependencyManager::get(); - // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed - if (!keyboard->getKeysID().contains(overlayID)) { + if (!keyboard->getKeysID().contains(id)) { // emit to scripts - emit mouseMoveOnOverlay(overlayID, event); + emit mouseMoveOnOverlay(id, event); } } diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 2a8812f69e..a9d3cffe41 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -103,13 +103,13 @@ public: QUuid add2DOverlay(const Overlay::Pointer& overlay); RayToOverlayIntersectionResult findRayIntersectionVector(const PickRay& ray, bool precisionPicking, - const QVector& overlaysToInclude, - const QVector& overlaysToDiscard, + const QVector& include, + const QVector& discard, bool visibleOnly = false, bool collidableOnly = false); ParabolaToOverlayIntersectionResult findParabolaIntersectionVector(const PickParabola& parabola, bool precisionPicking, - const QVector& overlaysToInclude, - const QVector& overlaysToDiscard, + const QVector& include, + const QVector& discard, bool visibleOnly = false, bool collidableOnly = false); bool mousePressEvent(QMouseEvent* event); @@ -356,8 +356,8 @@ public slots: * @function Overlays.findRayIntersection * @param {PickRay} pickRay - The PickRay to use for finding overlays. * @param {boolean} [precisionPicking=false] - Unused; exists to match Entity API. - * @param {Array.} [overlayIDsToInclude=[]] - If not empty then the search is restricted to these overlays. - * @param {Array.} [overlayIDsToExclude=[]] - Overlays to ignore during the search. + * @param {Array.} [include=[]] - If not empty then the search is restricted to these overlays. + * @param {Array.} [discard=[]] - Overlays to ignore during the search. * @param {boolean} [visibleOnly=false] - Unused; exists to match Entity API. * @param {boolean} [collidableOnly=false] - Unused; exists to match Entity API. * @returns {Overlays.RayToOverlayIntersectionResult} The closest 3D overlay intersected by pickRay, taking @@ -379,8 +379,8 @@ public slots: */ RayToOverlayIntersectionResult findRayIntersection(const PickRay& ray, bool precisionPicking = false, - const QScriptValue& overlayIDsToInclude = QScriptValue(), - const QScriptValue& overlayIDsToDiscard = QScriptValue(), + const QScriptValue& include = QScriptValue(), + const QScriptValue& discard = QScriptValue(), bool visibleOnly = false, bool collidableOnly = false); @@ -718,6 +718,11 @@ private: QUuid _currentClickingOnOverlayID; QUuid _currentHoverOverOverlayID; + static QString entityToOverlayType(const QString& type); + static QString overlayToEntityType(const QString& type); + static std::unordered_map _entityToOverlayTypes; + static std::unordered_map _overlayToEntityTypes; + private slots: void mousePressPointerEvent(const QUuid& id, const PointerEvent& event); void mouseMovePointerEvent(const QUuid& id, const PointerEvent& event); @@ -727,4 +732,8 @@ private slots: void hoverLeavePointerEvent(const QUuid& id, const PointerEvent& event); }; +#define ADD_TYPE_MAP(entity, overlay) \ + _entityToOverlayTypes[#entity] = #overlay; \ + _overlayToEntityTypes[#overlay] = #entity; + #endif // hifi_Overlays_h diff --git a/interface/src/ui/overlays/Shape3DOverlay.cpp b/interface/src/ui/overlays/Shape3DOverlay.cpp index 4adbbf3792..b7bbc76ffb 100644 --- a/interface/src/ui/overlays/Shape3DOverlay.cpp +++ b/interface/src/ui/overlays/Shape3DOverlay.cpp @@ -196,7 +196,7 @@ scriptable::ScriptableModelBase Shape3DOverlay::getScriptableModel() { auto geometryCache = DependencyManager::get(); auto vertexColor = ColorUtils::toVec3(_color); scriptable::ScriptableModelBase result; - result.objectID = getID(); + result.objectID = Overlay::getID(); if (auto mesh = geometryCache->meshFromShape(_shape, vertexColor)) { result.append(mesh); } diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index b1d5c878c4..385fea768c 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -128,7 +128,7 @@ scriptable::ScriptableModelBase Sphere3DOverlay::getScriptableModel() { auto vertexColor = ColorUtils::toVec3(_color); scriptable::ScriptableModelBase result; if (auto mesh = geometryCache->meshFromShape(GeometryCache::Sphere, vertexColor)) { - result.objectID = getID(); + result.objectID = Overlay::getID(); result.append(mesh); } return result;