mirror of
https://github.com/lubosz/overte.git
synced 2025-04-13 02:35:12 +02:00
remove overlays from application.cpp
This commit is contained in:
parent
a75fe4b48b
commit
0bfcde67ea
13 changed files with 587 additions and 546 deletions
|
@ -151,6 +151,7 @@
|
|||
#include <trackers/EyeTracker.h>
|
||||
#include <avatars-renderer/ScriptAvatar.h>
|
||||
#include <RenderableEntityItem.h>
|
||||
#include <RenderableTextEntityItem.h>
|
||||
#include <RenderableWebEntityItem.h>
|
||||
#include <model-networking/MaterialCache.h>
|
||||
#include "recording/ClipCache.h"
|
||||
|
@ -196,8 +197,6 @@
|
|||
#include "ui/AvatarInputs.h"
|
||||
#include "ui/DialogsManager.h"
|
||||
#include "ui/LoginDialog.h"
|
||||
#include "ui/overlays/Cube3DOverlay.h"
|
||||
#include "ui/overlays/Web3DOverlay.h"
|
||||
#include "ui/Snapshot.h"
|
||||
#include "ui/SnapshotAnimated.h"
|
||||
#include "ui/StandAloneJSConsole.h"
|
||||
|
@ -618,8 +617,6 @@ public:
|
|||
switch (type) {
|
||||
case NestableType::Entity:
|
||||
return getEntityModelProvider(static_cast<EntityItemID>(uuid));
|
||||
case NestableType::Overlay:
|
||||
return getOverlayModelProvider(static_cast<OverlayID>(uuid));
|
||||
case NestableType::Avatar:
|
||||
return getAvatarModelProvider(uuid);
|
||||
}
|
||||
|
@ -643,22 +640,6 @@ private:
|
|||
return provider;
|
||||
}
|
||||
|
||||
scriptable::ModelProviderPointer getOverlayModelProvider(OverlayID overlayID) {
|
||||
scriptable::ModelProviderPointer provider;
|
||||
auto &overlays = qApp->getOverlays();
|
||||
if (auto overlay = overlays.getOverlay(overlayID)) {
|
||||
if (auto base3d = std::dynamic_pointer_cast<Base3DOverlay>(overlay)) {
|
||||
provider = std::dynamic_pointer_cast<scriptable::ModelProvider>(base3d);
|
||||
provider->modelProviderType = NestableType::Overlay;
|
||||
} else {
|
||||
qCWarning(interfaceapp) << "no renderer for overlay ID" << overlayID.toString();
|
||||
}
|
||||
} else {
|
||||
qCWarning(interfaceapp) << "overlay not found" << overlayID.toString();
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
scriptable::ModelProviderPointer getAvatarModelProvider(QUuid sessionUUID) {
|
||||
scriptable::ModelProviderPointer provider;
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
|
@ -935,9 +916,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
|||
// FIXME move to header, or better yet, design some kind of UI manager
|
||||
// to take care of highlighting keyboard focused items, rather than
|
||||
// continuing to overburden Application.cpp
|
||||
std::shared_ptr<Cube3DOverlay> _keyboardFocusHighlight{ nullptr };
|
||||
OverlayID _keyboardFocusHighlightID{ UNKNOWN_OVERLAY_ID };
|
||||
|
||||
QUuid _keyboardFocusHighlightID;
|
||||
|
||||
OffscreenGLCanvas* _qmlShareContext { nullptr };
|
||||
|
||||
|
@ -1206,9 +1185,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
if (tabletScriptingInterface) {
|
||||
tabletScriptingInterface->setQmlTabletRoot(SYSTEM_TABLET, nullptr);
|
||||
}
|
||||
getOverlays().deleteOverlay(getTabletScreenID());
|
||||
getOverlays().deleteOverlay(getTabletHomeButtonID());
|
||||
getOverlays().deleteOverlay(getTabletFrameID());
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
entityScriptingInterface->deleteEntity(getTabletScreenID());
|
||||
entityScriptingInterface->deleteEntity(getTabletHomeButtonID());
|
||||
entityScriptingInterface->deleteEntity(getTabletFrameID());
|
||||
_failedToConnectToEntityServer = false;
|
||||
});
|
||||
|
||||
|
@ -1298,10 +1278,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
if (isHMDMode()) {
|
||||
emit loginDialogFocusDisabled();
|
||||
dialogsManager->hideLoginDialog();
|
||||
createLoginDialogOverlay();
|
||||
createLoginDialog();
|
||||
} else {
|
||||
getOverlays().deleteOverlay(_loginDialogOverlayID);
|
||||
_loginDialogOverlayID = OverlayID();
|
||||
DependencyManager::get<EntityScriptingInterface>()->deleteEntity(_loginDialogID);
|
||||
_loginDialogID = QUuid();
|
||||
_loginStateManager.tearDown();
|
||||
dialogsManager->showLoginDialog();
|
||||
emit loginDialogFocusEnabled();
|
||||
|
@ -1898,7 +1878,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
[this](const EntityItemID& entityItemID, const PointerEvent& event) {
|
||||
if (event.shouldFocus()) {
|
||||
if (getEntities()->wantsKeyboardFocus(entityItemID)) {
|
||||
setKeyboardFocusLocalEntity(UNKNOWN_OVERLAY_ID);
|
||||
setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID);
|
||||
setKeyboardFocusEntity(entityItemID);
|
||||
} else {
|
||||
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||
|
@ -1970,33 +1950,25 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
return false;
|
||||
});
|
||||
|
||||
EntityTree::setAddMaterialToOverlayOperator([this](const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||
auto overlay = _overlays.getOverlay(overlayID);
|
||||
if (overlay) {
|
||||
overlay->addMaterial(material, parentMaterialName);
|
||||
return true;
|
||||
EntityTree::setTextSizeOperator([this](const QUuid& id, const QString& text) {
|
||||
auto entities = getEntities();
|
||||
if (auto entity = entities->renderableForEntityId(id)) {
|
||||
if (auto renderable = std::dynamic_pointer_cast<render::entities::TextEntityRenderer>(entity)) {
|
||||
return renderable->textSize(text);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
EntityTree::setRemoveMaterialFromOverlayOperator([this](const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
||||
auto overlay = _overlays.getOverlay(overlayID);
|
||||
if (overlay) {
|
||||
overlay->removeMaterial(material, parentMaterialName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return QSizeF(0.0f, 0.0f);
|
||||
});
|
||||
|
||||
// Keyboard focus handling for Web overlays.
|
||||
auto overlays = &(qApp->getOverlays());
|
||||
connect(overlays, &Overlays::overlayDeleted, [this](const OverlayID& overlayID) {
|
||||
if (overlayID == _keyboardFocusedLocalEntity.get()) {
|
||||
setKeyboardFocusLocalEntity(UNKNOWN_OVERLAY_ID);
|
||||
// Keyboard focus handling for local Web entities.
|
||||
connect(&qApp->getOverlays(), &Overlays::overlayDeleted, [this](const QUuid& id) {
|
||||
if (id == _keyboardFocusedLocalEntity.get()) {
|
||||
setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID);
|
||||
}
|
||||
});
|
||||
|
||||
connect(this, &Application::aboutToQuit, [this]() {
|
||||
setKeyboardFocusLocalEntity(UNKNOWN_OVERLAY_ID);
|
||||
setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID);
|
||||
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||
});
|
||||
|
||||
|
@ -2344,7 +2316,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
});
|
||||
});
|
||||
auto rootItemLoadedFunctor = [webSurface, url, isTablet] {
|
||||
Application::setupQmlSurface(webSurface->getSurfaceContext(), isTablet || url == OVERLAY_LOGIN_DIALOG.toString());
|
||||
Application::setupQmlSurface(webSurface->getSurfaceContext(), isTablet || url == LOGIN_DIALOG.toString());
|
||||
};
|
||||
if (webSurface->getRootItem()) {
|
||||
rootItemLoadedFunctor();
|
||||
|
@ -2600,11 +2572,10 @@ void Application::cleanupBeforeQuit() {
|
|||
_applicationStateDevice.reset();
|
||||
|
||||
{
|
||||
if (_keyboardFocusHighlightID != UNKNOWN_OVERLAY_ID) {
|
||||
getOverlays().deleteOverlay(_keyboardFocusHighlightID);
|
||||
_keyboardFocusHighlightID = UNKNOWN_OVERLAY_ID;
|
||||
if (_keyboardFocusHighlightID != UNKNOWN_ENTITY_ID) {
|
||||
DependencyManager::get<EntityScriptingInterface>()->deleteEntity(_keyboardFocusHighlightID);
|
||||
_keyboardFocusHighlightID = UNKNOWN_ENTITY_ID;
|
||||
}
|
||||
_keyboardFocusHighlight = nullptr;
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -3080,7 +3051,7 @@ void Application::initializeUi() {
|
|||
});
|
||||
|
||||
#if !defined(DISABLE_QML)
|
||||
// Pre-create a couple of Web3D overlays to speed up tablet UI
|
||||
// Pre-create a couple of offscreen surfaces to speed up tablet UI
|
||||
auto offscreenSurfaceCache = DependencyManager::get<OffscreenQmlSurfaceCache>();
|
||||
offscreenSurfaceCache->setOnRootContextCreated([&](const QString& rootObject, QQmlContext* surfaceContext) {
|
||||
if (rootObject == TabletScriptingInterface::QML) {
|
||||
|
@ -3799,7 +3770,7 @@ static inline bool isKeyEvent(QEvent::Type type) {
|
|||
return type == QEvent::KeyPress || type == QEvent::KeyRelease;
|
||||
}
|
||||
|
||||
bool Application::handleKeyEventForFocusedEntityOrOverlay(QEvent* event) {
|
||||
bool Application::handleKeyEventForFocusedEntity(QEvent* event) {
|
||||
if (!_keyboardFocusedEntity.get().isInvalidID()) {
|
||||
switch (event->type()) {
|
||||
case QEvent::KeyPress:
|
||||
|
@ -3821,15 +3792,14 @@ bool Application::handleKeyEventForFocusedEntityOrOverlay(QEvent* event) {
|
|||
}
|
||||
}
|
||||
|
||||
if (_keyboardFocusedLocalEntity.get() != UNKNOWN_OVERLAY_ID) {
|
||||
if (!_keyboardFocusedLocalEntity.get().isInvalidID()) {
|
||||
switch (event->type()) {
|
||||
case QEvent::KeyPress:
|
||||
case QEvent::KeyRelease: {
|
||||
// Only Web entities can have focus.
|
||||
auto overlay = std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(_keyboardFocusedLocalEntity.get()));
|
||||
if (overlay && overlay->getEventHandler()) {
|
||||
auto eventHandler = getEntities()->getEventHandler(_keyboardFocusedEntity.get());
|
||||
if (eventHandler) {
|
||||
event->setAccepted(false);
|
||||
QCoreApplication::sendEvent(overlay->getEventHandler(), event);
|
||||
QCoreApplication::sendEvent(eventHandler, event);
|
||||
if (event->isAccepted()) {
|
||||
_lastAcceptedKeyPress = usecTimestampNow();
|
||||
return true;
|
||||
|
@ -3885,8 +3855,8 @@ bool Application::event(QEvent* event) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Allow focused Entities and Overlays to handle keyboard input
|
||||
if (isKeyEvent(event->type()) && handleKeyEventForFocusedEntityOrOverlay(event)) {
|
||||
// Allow focused Entities to handle keyboard input
|
||||
if (isKeyEvent(event->type()) && handleKeyEventForFocusedEntity(event)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4352,7 +4322,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
|
|||
buttons, event->modifiers());
|
||||
|
||||
if (compositor.getReticleVisible() || !isHMDMode() || !compositor.getReticleOverDesktop() ||
|
||||
getOverlays().getOverlayAtPoint(glm::vec2(transformedPos.x(), transformedPos.y())) != UNKNOWN_OVERLAY_ID) {
|
||||
!getOverlays().getOverlayAtPoint(glm::vec2(transformedPos.x(), transformedPos.y())).isNull()) {
|
||||
getOverlays().mouseMoveEvent(&mappedEvent);
|
||||
getEntities()->mouseMoveEvent(&mappedEvent);
|
||||
}
|
||||
|
@ -4921,29 +4891,31 @@ void Application::idle() {
|
|||
}
|
||||
|
||||
|
||||
// Update focus highlight for entity or overlay.
|
||||
// Update focus highlight for entities
|
||||
{
|
||||
if (!_keyboardFocusedEntity.get().isInvalidID() || _keyboardFocusedLocalEntity.get() != UNKNOWN_OVERLAY_ID) {
|
||||
if (!_keyboardFocusedEntity.get().isInvalidID() || !_keyboardFocusedLocalEntity.get().isInvalidID()) {
|
||||
const quint64 LOSE_FOCUS_AFTER_ELAPSED_TIME = 30 * USECS_PER_SECOND; // if idle for 30 seconds, drop focus
|
||||
quint64 elapsedSinceAcceptedKeyPress = usecTimestampNow() - _lastAcceptedKeyPress;
|
||||
if (elapsedSinceAcceptedKeyPress > LOSE_FOCUS_AFTER_ELAPSED_TIME) {
|
||||
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||
setKeyboardFocusLocalEntity(UNKNOWN_OVERLAY_ID);
|
||||
setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID);
|
||||
} else {
|
||||
// update position of highlight overlay
|
||||
if (!_keyboardFocusedEntity.get().isInvalidID()) {
|
||||
auto entity = getEntities()->getTree()->findEntityByID(_keyboardFocusedEntity.get());
|
||||
if (entity && _keyboardFocusHighlight) {
|
||||
_keyboardFocusHighlight->setWorldOrientation(entity->getWorldOrientation());
|
||||
_keyboardFocusHighlight->setWorldPosition(entity->getWorldPosition());
|
||||
if (entity && !_keyboardFocusHighlightID.isNull()) {
|
||||
EntityItemProperties properties;
|
||||
properties.setPosition(entity->getWorldPosition());
|
||||
properties.setRotation(entity->getWorldOrientation());
|
||||
DependencyManager::get<EntityScriptingInterface>()->editEntity(_keyboardFocusHighlightID, properties);
|
||||
}
|
||||
} else {
|
||||
// Only Web overlays can have focus.
|
||||
auto overlay =
|
||||
std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(_keyboardFocusedLocalEntity.get()));
|
||||
if (overlay && _keyboardFocusHighlight) {
|
||||
_keyboardFocusHighlight->setWorldOrientation(overlay->getWorldOrientation());
|
||||
_keyboardFocusHighlight->setWorldPosition(overlay->getWorldPosition());
|
||||
auto entity = getEntities()->getTree()->findEntityByID(_keyboardFocusedEntity.get());
|
||||
if (entity && !_keyboardFocusHighlightID.isNull()) {
|
||||
EntityItemProperties properties;
|
||||
properties.setPosition(entity->getWorldPosition());
|
||||
properties.setRotation(entity->getWorldOrientation());
|
||||
DependencyManager::get<EntityScriptingInterface>()->editEntity(_keyboardFocusHighlightID, properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5746,24 +5718,28 @@ void Application::setKeyboardFocusHighlight(const glm::vec3& position, const glm
|
|||
if (qApp->getLoginDialogPoppedUp()) {
|
||||
return;
|
||||
}
|
||||
if (_keyboardFocusHighlightID == UNKNOWN_OVERLAY_ID || !getOverlays().isAddedOverlay(_keyboardFocusHighlightID)) {
|
||||
_keyboardFocusHighlight = std::make_shared<Cube3DOverlay>();
|
||||
_keyboardFocusHighlight->setAlpha(1.0f);
|
||||
_keyboardFocusHighlight->setColor({ 0xFF, 0xEF, 0x00 });
|
||||
_keyboardFocusHighlight->setIsSolid(false);
|
||||
_keyboardFocusHighlight->setPulseMin(0.5);
|
||||
_keyboardFocusHighlight->setPulseMax(1.0);
|
||||
_keyboardFocusHighlight->setColorPulse(1.0);
|
||||
_keyboardFocusHighlight->setIgnorePickIntersection(true);
|
||||
_keyboardFocusHighlight->setDrawInFront(false);
|
||||
_keyboardFocusHighlightID = getOverlays().addOverlay(_keyboardFocusHighlight);
|
||||
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
if (_keyboardFocusHighlightID == UNKNOWN_ENTITY_ID || !entityScriptingInterface->isAddedEntity(_keyboardFocusHighlightID)) {
|
||||
EntityItemProperties properties;
|
||||
properties.setType(EntityTypes::Box);
|
||||
properties.setAlpha(1.0f);
|
||||
properties.setColor({ 0xFF, 0xEF, 0x00 });
|
||||
properties.setPrimitiveMode(PrimitiveMode::LINES);
|
||||
properties.getPulse().setMin(0.5);
|
||||
properties.getPulse().setMax(1.0f);
|
||||
properties.getPulse().setColorMode(PulseMode::IN_PHASE);
|
||||
properties.setIgnorePickIntersection(true);
|
||||
_keyboardFocusHighlightID = entityScriptingInterface->addEntity(properties, "local");
|
||||
}
|
||||
|
||||
// Position focus
|
||||
_keyboardFocusHighlight->setWorldOrientation(rotation);
|
||||
_keyboardFocusHighlight->setWorldPosition(position);
|
||||
_keyboardFocusHighlight->setDimensions(dimensions);
|
||||
_keyboardFocusHighlight->setVisible(true);
|
||||
EntityItemProperties properties;
|
||||
properties.setPosition(position);
|
||||
properties.setRotation(rotation);
|
||||
properties.setDimensions(dimensions);
|
||||
properties.setVisible(true);
|
||||
entityScriptingInterface->editEntity(_keyboardFocusHighlightID, properties);
|
||||
}
|
||||
|
||||
QUuid Application::getKeyboardFocusEntity() const {
|
||||
|
@ -5779,18 +5755,16 @@ void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) {
|
|||
if (_keyboardFocusedEntity.get() != entityItemID) {
|
||||
_keyboardFocusedEntity.set(entityItemID);
|
||||
|
||||
if (_keyboardFocusHighlight && _keyboardFocusedLocalEntity.get() == UNKNOWN_OVERLAY_ID) {
|
||||
_keyboardFocusHighlight->setVisible(false);
|
||||
}
|
||||
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
if (entityItemID == UNKNOWN_ENTITY_ID) {
|
||||
EntityItemProperties properties;
|
||||
properties.setVisible(false);
|
||||
entityScriptingInterface->editEntity(_keyboardFocusHighlightID, properties);
|
||||
return;
|
||||
}
|
||||
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
auto properties = entityScriptingInterface->getEntityProperties(entityItemID);
|
||||
if (!properties.getLocked() && properties.getVisible()) {
|
||||
|
||||
auto entities = getEntities();
|
||||
auto entityId = _keyboardFocusedEntity.get();
|
||||
if (entities->wantsKeyboardFocus(entityId)) {
|
||||
|
@ -5814,44 +5788,43 @@ EntityItemID Application::getKeyboardFocusLocalEntity() {
|
|||
return _keyboardFocusedLocalEntity.get();
|
||||
}
|
||||
|
||||
void Application::setKeyboardFocusLocalEntity(const EntityItemID& overlayID) {
|
||||
if (overlayID != _keyboardFocusedLocalEntity.get()) {
|
||||
if (qApp->getLoginDialogPoppedUp() && !_loginDialogOverlayID.isNull()) {
|
||||
if (overlayID == _loginDialogOverlayID) {
|
||||
void Application::setKeyboardFocusLocalEntity(const EntityItemID& entityItemID) {
|
||||
if (entityItemID != _keyboardFocusedLocalEntity.get()) {
|
||||
if (qApp->getLoginDialogPoppedUp() && !_loginDialogID.isNull()) {
|
||||
if (entityItemID == _loginDialogID) {
|
||||
emit loginDialogFocusEnabled();
|
||||
} else {
|
||||
// that's the only overlay we want in focus;
|
||||
// that's the only entity we want in focus;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_keyboardFocusedLocalEntity.set(overlayID);
|
||||
_keyboardFocusedLocalEntity.set(entityItemID);
|
||||
|
||||
if (_keyboardFocusHighlight && _keyboardFocusedEntity.get() == UNKNOWN_ENTITY_ID) {
|
||||
_keyboardFocusHighlight->setVisible(false);
|
||||
}
|
||||
|
||||
if (overlayID == UNKNOWN_OVERLAY_ID) {
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
if (entityItemID == UNKNOWN_ENTITY_ID) {
|
||||
EntityItemProperties properties;
|
||||
properties.setVisible(false);
|
||||
entityScriptingInterface->editEntity(_keyboardFocusHighlightID, properties);
|
||||
return;
|
||||
}
|
||||
|
||||
auto overlayType = getOverlays().getOverlayType(overlayID);
|
||||
auto isVisible = getOverlays().getProperty(overlayID, "visible").value.toBool();
|
||||
if (overlayType == Web3DOverlay::TYPE && isVisible) {
|
||||
auto overlay = std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(overlayID));
|
||||
overlay->setProxyWindow(_window->windowHandle());
|
||||
auto properties = entityScriptingInterface->getEntityProperties(entityItemID);
|
||||
if (!properties.getLocked() && properties.getVisible()) {
|
||||
auto entities = getEntities();
|
||||
auto entityId = _keyboardFocusedLocalEntity.get();
|
||||
if (entities->wantsKeyboardFocus(entityId)) {
|
||||
entities->setProxyWindow(entityId, _window->windowHandle());
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->pluginFocusOutEvent();
|
||||
}
|
||||
_lastAcceptedKeyPress = usecTimestampNow();
|
||||
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->pluginFocusOutEvent();
|
||||
}
|
||||
_lastAcceptedKeyPress = usecTimestampNow();
|
||||
|
||||
if (overlay->getProperty("showKeyboardFocusHighlight").toBool()) {
|
||||
auto size = overlay->getSize() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR;
|
||||
const float OVERLAY_DEPTH = 0.0105f;
|
||||
setKeyboardFocusHighlight(overlay->getWorldPosition(), overlay->getWorldOrientation(), glm::vec3(size.x, size.y, OVERLAY_DEPTH));
|
||||
} else if (_keyboardFocusHighlight) {
|
||||
_keyboardFocusHighlight->setVisible(false);
|
||||
auto entity = getEntities()->getEntity(entityId);
|
||||
if (entity) {
|
||||
setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(),
|
||||
entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6367,9 +6340,9 @@ void Application::update(float deltaTime) {
|
|||
|
||||
updateLOD(deltaTime);
|
||||
|
||||
if (!_loginDialogOverlayID.isNull()) {
|
||||
_loginStateManager.update(getMyAvatar()->getDominantHand(), _loginDialogOverlayID);
|
||||
updateLoginDialogOverlayPosition();
|
||||
if (!_loginDialogID.isNull()) {
|
||||
_loginStateManager.update(getMyAvatar()->getDominantHand(), _loginDialogID);
|
||||
updateLoginDialogPosition();
|
||||
}
|
||||
|
||||
// TODO: break these out into distinct perfTimers when they prove interesting
|
||||
|
@ -7148,7 +7121,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
|||
connect(scriptEngine.data(), &ScriptEngine::finished, clipboardScriptable, &ClipboardScriptingInterface::deleteLater);
|
||||
|
||||
scriptEngine->registerGlobalObject("Overlays", &_overlays);
|
||||
qScriptRegisterMetaType(scriptEngine.data(), OverlayPropertyResultToScriptValue, OverlayPropertyResultFromScriptValue);
|
||||
qScriptRegisterMetaType(scriptEngine.data(), RayToOverlayIntersectionResultToScriptValue,
|
||||
RayToOverlayIntersectionResultFromScriptValue);
|
||||
|
||||
|
@ -7265,8 +7237,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
|||
scriptEngine->registerGlobalObject("HifiAbout", AboutUtil::getInstance());
|
||||
scriptEngine->registerGlobalObject("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data());
|
||||
|
||||
qScriptRegisterMetaType(scriptEngine.data(), OverlayIDtoScriptValue, OverlayIDfromScriptValue);
|
||||
|
||||
registerInteractiveWindowMetaType(scriptEngine.data());
|
||||
|
||||
auto pickScriptingInterface = DependencyManager::get<PickScriptingInterface>();
|
||||
|
@ -8764,45 +8734,48 @@ void Application::setShowBulletConstraintLimits(bool value) {
|
|||
_physicsEngine->setShowBulletConstraintLimits(value);
|
||||
}
|
||||
|
||||
void Application::createLoginDialogOverlay() {
|
||||
const glm::vec2 LOGIN_OVERLAY_DIMENSIONS{ 0.89f, 0.5f };
|
||||
const auto OVERLAY_OFFSET = glm::vec2(0.7f, -0.1f);
|
||||
void Application::createLoginDialog() {
|
||||
const glm::vec3 LOGIN_DIMENSIONS { 0.89f, 0.5f, 0.01f };
|
||||
const auto OFFSET = glm::vec2(0.7f, -0.1f);
|
||||
auto cameraPosition = _myCamera.getPosition();
|
||||
auto cameraOrientation = _myCamera.getOrientation();
|
||||
auto upVec = getMyAvatar()->getWorldOrientation() * Vectors::UNIT_Y;
|
||||
auto headLookVec = (cameraOrientation * Vectors::FRONT);
|
||||
// DEFAULT_DPI / tablet scale percentage
|
||||
const float OVERLAY_DPI = 31.0f / (75.0f / 100.0f);
|
||||
auto offset = headLookVec * OVERLAY_OFFSET.x;
|
||||
auto overlayPosition = (cameraPosition + offset) + (upVec * OVERLAY_OFFSET.y);
|
||||
QVariantMap overlayProperties = {
|
||||
{ "name", "LoginDialogOverlay" },
|
||||
{ "url", OVERLAY_LOGIN_DIALOG },
|
||||
{ "position", vec3toVariant(overlayPosition) },
|
||||
{ "orientation", quatToVariant(cameraOrientation) },
|
||||
{ "isSolid", true },
|
||||
{ "grabbable", false },
|
||||
{ "ignorePickIntersection", false },
|
||||
{ "alpha", 1.0 },
|
||||
{ "dimensions", vec2ToVariant(LOGIN_OVERLAY_DIMENSIONS)},
|
||||
{ "dpi", OVERLAY_DPI },
|
||||
{ "visible", true }
|
||||
};
|
||||
auto& overlays = getOverlays();
|
||||
_loginDialogOverlayID = overlays.addOverlay("web3d", overlayProperties);
|
||||
auto loginOverlay = std::dynamic_pointer_cast<Web3DOverlay>(overlays.getOverlay(_loginDialogOverlayID));
|
||||
const float DPI = 31.0f / (75.0f / 100.0f);
|
||||
auto offset = headLookVec * OFFSET.x;
|
||||
auto position = (cameraPosition + offset) + (upVec * OFFSET.y);
|
||||
|
||||
EntityItemProperties properties;
|
||||
properties.setType(EntityTypes::Web);
|
||||
properties.setName("LoginDialogEntity");
|
||||
properties.setSourceUrl(LOGIN_DIALOG);
|
||||
properties.setPosition(position);
|
||||
properties.setRotation(cameraOrientation);
|
||||
properties.setDimensions(LOGIN_DIMENSIONS);
|
||||
properties.setPrimitiveMode(PrimitiveMode::SOLID);
|
||||
properties.getGrab().setGrabbable(false);
|
||||
properties.setIgnorePickIntersection(false);
|
||||
properties.setAlpha(1.0f);
|
||||
properties.setDPI(DPI);
|
||||
properties.setVisible(true);
|
||||
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
_loginDialogID = entityScriptingInterface->addEntity(properties, "local");
|
||||
|
||||
auto keyboard = DependencyManager::get<Keyboard>().data();
|
||||
if (!keyboard->getAnchorID().isNull() && !_loginDialogOverlayID.isNull()) {
|
||||
if (!keyboard->getAnchorID().isNull() && !_loginDialogID.isNull()) {
|
||||
const auto KEYBOARD_LOCAL_ORIENTATION = glm::quat(0.0f, 0.0, 1.0f, 0.25f);
|
||||
auto keyboardLocalOffset = cameraOrientation * glm::vec3(-0.4f * getMyAvatar()->getSensorToWorldScale(), -0.3f, 0.2f);
|
||||
QVariantMap properties {
|
||||
{ "position", vec3toVariant(overlayPosition + keyboardLocalOffset) },
|
||||
{ "orientation", quatToVariant(cameraOrientation * KEYBOARD_LOCAL_ORIENTATION) },
|
||||
};
|
||||
overlays.editOverlay(keyboard->getAnchorID(), properties);
|
||||
|
||||
EntityItemProperties properties;
|
||||
properties.setPosition(position + keyboardLocalOffset);
|
||||
properties.setRotation(cameraOrientation * KEYBOARD_LOCAL_ORIENTATION);
|
||||
|
||||
entityScriptingInterface->editEntity(keyboard->getAnchorID(), properties);
|
||||
keyboard->setResetKeyboardPositionOnRaise(false);
|
||||
}
|
||||
setKeyboardFocusLocalEntity(_loginDialogOverlayID);
|
||||
setKeyboardFocusLocalEntity(_loginDialogID);
|
||||
emit loginDialogFocusEnabled();
|
||||
getApplicationCompositor().getReticleInterface()->setAllowMouseCapture(false);
|
||||
getApplicationCompositor().getReticleInterface()->setVisible(false);
|
||||
|
@ -8811,38 +8784,44 @@ void Application::createLoginDialogOverlay() {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::updateLoginDialogOverlayPosition() {
|
||||
void Application::updateLoginDialogPosition() {
|
||||
const float LOOK_AWAY_THRESHOLD_ANGLE = 70.0f;
|
||||
const auto OVERLAY_OFFSET = glm::vec2(0.7f, -0.1f);
|
||||
auto& overlays = getOverlays();
|
||||
auto loginOverlay = std::dynamic_pointer_cast<Web3DOverlay>(overlays.getOverlay(_loginDialogOverlayID));
|
||||
auto overlayPositionVec = loginOverlay->getWorldPosition();
|
||||
const auto OFFSET = glm::vec2(0.7f, -0.1f);
|
||||
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
EntityPropertyFlags desiredProperties;
|
||||
desiredProperties += PROP_POSITION;
|
||||
auto properties = entityScriptingInterface->getEntityProperties(_loginDialogID, desiredProperties);
|
||||
auto positionVec = properties.getPosition();
|
||||
auto cameraPositionVec = _myCamera.getPosition();
|
||||
auto cameraOrientation = cancelOutRollAndPitch(_myCamera.getOrientation());
|
||||
auto headLookVec = (cameraOrientation * Vectors::FRONT);
|
||||
auto overlayToHeadVec = overlayPositionVec - cameraPositionVec;
|
||||
auto pointAngle = (glm::acos(glm::dot(glm::normalize(overlayToHeadVec), glm::normalize(headLookVec))) * 180.0f / PI);
|
||||
auto entityToHeadVec = positionVec - cameraPositionVec;
|
||||
auto pointAngle = (glm::acos(glm::dot(glm::normalize(entityToHeadVec), glm::normalize(headLookVec))) * 180.0f / PI);
|
||||
auto upVec = getMyAvatar()->getWorldOrientation() * Vectors::UNIT_Y;
|
||||
auto offset = headLookVec * OVERLAY_OFFSET.x;
|
||||
auto newOverlayPositionVec = (cameraPositionVec + offset) + (upVec * OVERLAY_OFFSET.y);
|
||||
auto newOverlayOrientation = glm::inverse(glm::quat_cast(glm::lookAt(newOverlayPositionVec, cameraPositionVec, upVec))) * Quaternions::Y_180;
|
||||
auto offset = headLookVec * OFFSET.x;
|
||||
auto newPositionVec = (cameraPositionVec + offset) + (upVec * OFFSET.y);
|
||||
auto newOrientation = glm::inverse(glm::quat_cast(glm::lookAt(newPositionVec, cameraPositionVec, upVec))) * Quaternions::Y_180;
|
||||
|
||||
bool overlayOutOfBounds = glm::distance(overlayPositionVec, cameraPositionVec) > 1.0f;
|
||||
bool outOfBounds = glm::distance(positionVec, cameraPositionVec) > 1.0f;
|
||||
|
||||
if (pointAngle > LOOK_AWAY_THRESHOLD_ANGLE || overlayOutOfBounds) {
|
||||
QVariantMap properties {
|
||||
{"position", vec3toVariant(newOverlayPositionVec)},
|
||||
{"orientation", quatToVariant(newOverlayOrientation)}
|
||||
};
|
||||
overlays.editOverlay(_loginDialogOverlayID, properties);
|
||||
const auto KEYBOARD_LOCAL_ORIENTATION = glm::quat(0.0f, 0.0, 1.0f, 0.25f);
|
||||
auto keyboardLocalOffset = newOverlayOrientation * glm::vec3(-0.4f * getMyAvatar()->getSensorToWorldScale(), -0.3f, 0.2f);
|
||||
QVariantMap keyboardProperties {
|
||||
{ "position", vec3toVariant(newOverlayPositionVec + keyboardLocalOffset) },
|
||||
{ "orientation", quatToVariant(newOverlayOrientation * KEYBOARD_LOCAL_ORIENTATION) },
|
||||
};
|
||||
auto keyboard = DependencyManager::get<Keyboard>().data();
|
||||
overlays.editOverlay(keyboard->getAnchorID(), keyboardProperties);
|
||||
if (pointAngle > LOOK_AWAY_THRESHOLD_ANGLE || outOfBounds) {
|
||||
{
|
||||
EntityItemProperties properties;
|
||||
properties.setPosition(newPositionVec);
|
||||
properties.setRotation(newOrientation);
|
||||
entityScriptingInterface->editEntity(_loginDialogID, properties);
|
||||
}
|
||||
|
||||
{
|
||||
const auto KEYBOARD_LOCAL_ORIENTATION = glm::quat(0.0f, 0.0, 1.0f, 0.25f);
|
||||
auto keyboardLocalOffset = newOrientation * glm::vec3(-0.4f * getMyAvatar()->getSensorToWorldScale(), -0.3f, 0.2f);
|
||||
|
||||
EntityItemProperties properties;
|
||||
properties.setPosition(newPositionVec + keyboardLocalOffset);
|
||||
properties.setRotation(newOrientation * KEYBOARD_LOCAL_ORIENTATION);
|
||||
entityScriptingInterface->editEntity(DependencyManager::get<Keyboard>()->getAnchorID(), properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8859,10 +8838,9 @@ void Application::onDismissedLoginDialog() {
|
|||
loginDialogPoppedUp.set(false);
|
||||
auto keyboard = DependencyManager::get<Keyboard>().data();
|
||||
keyboard->setResetKeyboardPositionOnRaise(true);
|
||||
if (!_loginDialogOverlayID.isNull()) {
|
||||
// deleting overlay.
|
||||
getOverlays().deleteOverlay(_loginDialogOverlayID);
|
||||
_loginDialogOverlayID = OverlayID();
|
||||
if (!_loginDialogID.isNull()) {
|
||||
DependencyManager::get<EntityScriptingInterface>()->deleteEntity(_loginDialogID);
|
||||
_loginDialogID = QUuid();
|
||||
_loginStateManager.tearDown();
|
||||
}
|
||||
resumeAfterLoginDialogActionTaken();
|
||||
|
@ -9028,12 +9006,12 @@ void Application::updateSystemTabletMode() {
|
|||
}
|
||||
}
|
||||
|
||||
OverlayID Application::getTabletScreenID() const {
|
||||
QUuid Application::getTabletScreenID() const {
|
||||
auto HMD = DependencyManager::get<HMDScriptingInterface>();
|
||||
return HMD->getCurrentTabletScreenID();
|
||||
}
|
||||
|
||||
OverlayID Application::getTabletHomeButtonID() const {
|
||||
QUuid Application::getTabletHomeButtonID() const {
|
||||
auto HMD = DependencyManager::get<HMDScriptingInterface>();
|
||||
return HMD->getCurrentHomeButtonID();
|
||||
}
|
||||
|
@ -9044,7 +9022,7 @@ QUuid Application::getTabletFrameID() const {
|
|||
}
|
||||
|
||||
QVector<QUuid> Application::getTabletIDs() const {
|
||||
// Most important overlays first.
|
||||
// Most important first.
|
||||
QVector<QUuid> result;
|
||||
auto HMD = DependencyManager::get<HMDScriptingInterface>();
|
||||
result << HMD->getCurrentTabletScreenID();
|
||||
|
|
|
@ -297,10 +297,10 @@ public:
|
|||
|
||||
void shareSnapshot(const QString& filename, const QUrl& href = QUrl(""));
|
||||
|
||||
OverlayID getTabletScreenID() const;
|
||||
OverlayID getTabletHomeButtonID() const;
|
||||
QUuid getTabletFrameID() const; // may be an entity or an overlay
|
||||
QVector<QUuid> getTabletIDs() const; // In order of most important IDs first.
|
||||
QUuid getTabletScreenID() const;
|
||||
QUuid getTabletHomeButtonID() const;
|
||||
QUuid getTabletFrameID() const;
|
||||
QVector<QUuid> getTabletIDs() const;
|
||||
|
||||
void setAvatarOverrideUrl(const QUrl& url, bool save);
|
||||
void clearAvatarOverrideUrl() { _avatarOverrideUrl = QUrl(); _saveAvatarOverrideUrl = false; }
|
||||
|
@ -323,8 +323,8 @@ public:
|
|||
void setOtherAvatarsReplicaCount(int count) { DependencyManager::get<AvatarHashMap>()->setReplicaCount(count); }
|
||||
|
||||
bool getLoginDialogPoppedUp() const { return _loginDialogPoppedUp; }
|
||||
void createLoginDialogOverlay();
|
||||
void updateLoginDialogOverlayPosition();
|
||||
void createLoginDialog();
|
||||
void updateLoginDialogPosition();
|
||||
|
||||
// Check if a headset is connected
|
||||
bool hasRiftControllers();
|
||||
|
@ -440,7 +440,7 @@ public slots:
|
|||
void setKeyboardFocusEntity(const EntityItemID& entityItemID);
|
||||
|
||||
EntityItemID getKeyboardFocusLocalEntity();
|
||||
void setKeyboardFocusLocalEntity(const EntityItemID& overlayID);
|
||||
void setKeyboardFocusLocalEntity(const EntityItemID& id);
|
||||
|
||||
void addAssetToWorldMessageClose();
|
||||
|
||||
|
@ -531,7 +531,7 @@ private:
|
|||
void init();
|
||||
void pauseUntilLoginDetermined();
|
||||
void resumeAfterLoginDialogActionTaken();
|
||||
bool handleKeyEventForFocusedEntityOrOverlay(QEvent* event);
|
||||
bool handleKeyEventForFocusedEntity(QEvent* event);
|
||||
bool handleFileOpenEvent(QFileOpenEvent* event);
|
||||
void cleanupBeforeQuit();
|
||||
|
||||
|
@ -702,7 +702,7 @@ private:
|
|||
QString _previousAvatarSkeletonModel;
|
||||
float _previousAvatarTargetScale;
|
||||
CameraMode _previousCameraMode;
|
||||
OverlayID _loginDialogOverlayID;
|
||||
QUuid _loginDialogID;
|
||||
LoginStateManager _loginStateManager;
|
||||
|
||||
quint64 _lastFaceTrackerUpdate;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
HIFI_QML_DEF(LoginDialog)
|
||||
|
||||
static const QUrl TABLET_LOGIN_DIALOG_URL("dialogs/TabletLoginDialog.qml");
|
||||
const QUrl OVERLAY_LOGIN_DIALOG = PathUtils::qmlUrl("OverlayLoginDialog.qml");
|
||||
const QUrl LOGIN_DIALOG = PathUtils::qmlUrl("OverlayLoginDialog.qml");
|
||||
|
||||
LoginDialog::LoginDialog(QQuickItem *parent) : OffscreenQmlDialog(parent) {
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
|
@ -70,7 +70,7 @@ void LoginDialog::showWithSelection() {
|
|||
if (!qApp->getLoginDialogPoppedUp()) {
|
||||
tablet->initialScreen(TABLET_LOGIN_DIALOG_URL);
|
||||
} else {
|
||||
qApp->createLoginDialogOverlay();
|
||||
qApp->createLoginDialog();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,18 +54,13 @@ Overlays::Overlays() {
|
|||
|
||||
void Overlays::cleanupAllOverlays() {
|
||||
_shuttingDown = true;
|
||||
QMap<OverlayID, Overlay::Pointer> overlaysHUD;
|
||||
QMap<OverlayID, Overlay::Pointer> overlaysWorld;
|
||||
QMap<QUuid, Overlay::Pointer> overlays;
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
overlaysHUD.swap(_overlaysHUD);
|
||||
overlaysWorld.swap(_overlaysWorld);
|
||||
overlays.swap(_overlays);
|
||||
}
|
||||
|
||||
foreach(Overlay::Pointer overlay, overlaysHUD) {
|
||||
_overlaysToDelete.push_back(overlay);
|
||||
}
|
||||
foreach(Overlay::Pointer overlay, overlaysWorld) {
|
||||
foreach(Overlay::Pointer overlay, overlays) {
|
||||
_overlaysToDelete.push_back(overlay);
|
||||
}
|
||||
cleanupOverlaysToDelete();
|
||||
|
@ -77,10 +72,7 @@ void Overlays::init() {
|
|||
void Overlays::update(float deltatime) {
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
foreach(const auto& thisOverlay, _overlaysHUD) {
|
||||
thisOverlay->update(deltatime);
|
||||
}
|
||||
foreach(const auto& thisOverlay, _overlaysWorld) {
|
||||
foreach(const auto& thisOverlay, _overlays) {
|
||||
thisOverlay->update(deltatime);
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +102,7 @@ void Overlays::cleanupOverlaysToDelete() {
|
|||
}
|
||||
}
|
||||
|
||||
void Overlays::renderHUD(RenderArgs* renderArgs) {
|
||||
void Overlays::render(RenderArgs* renderArgs) {
|
||||
PROFILE_RANGE(render_overlays, __FUNCTION__);
|
||||
gpu::Batch& batch = *renderArgs->_batch;
|
||||
|
||||
|
@ -123,7 +115,7 @@ void Overlays::renderHUD(RenderArgs* renderArgs) {
|
|||
mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, -1000, 1000);
|
||||
|
||||
QMutexLocker locker(&_mutex);
|
||||
foreach(Overlay::Pointer thisOverlay, _overlaysHUD) {
|
||||
foreach(Overlay::Pointer thisOverlay, _overlays) {
|
||||
|
||||
// Reset all batch pipeline settings between overlay
|
||||
geometryCache->useSimpleDrawPipeline(batch);
|
||||
|
@ -146,29 +138,28 @@ void Overlays::enable() {
|
|||
|
||||
// Note, can't be invoked by scripts, but can be called by the InterfaceParentFinder
|
||||
// class on packet processing threads
|
||||
Overlay::Pointer Overlays::getOverlay(OverlayID id) const {
|
||||
Overlay::Pointer Overlays::get2DOverlay(const QUuid& id) const {
|
||||
if (_shuttingDown) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QMutexLocker locker(&_mutex);
|
||||
if (_overlaysHUD.contains(id)) {
|
||||
return _overlaysHUD[id];
|
||||
} else if (_overlaysWorld.contains(id)) {
|
||||
return _overlaysWorld[id];
|
||||
auto overlayIter = _overlays.find(id);
|
||||
if (overlayIter != _overlays.end()) {
|
||||
return overlayIter.value();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties) {
|
||||
QUuid Overlays::addOverlay(const QString& type, const QVariant& properties) {
|
||||
if (_shuttingDown) {
|
||||
return UNKNOWN_OVERLAY_ID;
|
||||
}
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
OverlayID result;
|
||||
QUuid result;
|
||||
PROFILE_RANGE(script, __FUNCTION__);
|
||||
BLOCKING_INVOKE_METHOD(this, "addOverlay", Q_RETURN_ARG(OverlayID, result), Q_ARG(QString, type), Q_ARG(QVariant, properties));
|
||||
BLOCKING_INVOKE_METHOD(this, "addOverlay", Q_RETURN_ARG(QUuid, result), Q_ARG(const QString&, type), Q_ARG(const QVariant&, properties));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -267,58 +258,69 @@ OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties)
|
|||
|
||||
if (thisOverlay) {
|
||||
thisOverlay->setProperties(properties.toMap());
|
||||
return addOverlay(thisOverlay);
|
||||
return add2DOverlay(thisOverlay);
|
||||
}
|
||||
return UNKNOWN_OVERLAY_ID;
|
||||
}
|
||||
|
||||
OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) {
|
||||
QUuid Overlays::add2DOverlay(const Overlay::Pointer& overlay) {
|
||||
if (_shuttingDown) {
|
||||
return UNKNOWN_OVERLAY_ID;
|
||||
}
|
||||
|
||||
OverlayID thisID = OverlayID(QUuid::createUuid());
|
||||
QUuid thisID = QUuid::createUuid();
|
||||
overlay->setOverlayID(thisID);
|
||||
overlay->setStackOrder(_stackOrder++);
|
||||
if (overlay->is3D()) {
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
_overlaysWorld[thisID] = overlay;
|
||||
}
|
||||
|
||||
render::ScenePointer scene = qApp->getMain3DScene();
|
||||
render::Transaction transaction;
|
||||
overlay->addToScene(overlay, scene, transaction);
|
||||
scene->enqueueTransaction(transaction);
|
||||
} else {
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
_overlaysHUD[thisID] = overlay;
|
||||
_overlays[thisID] = overlay;
|
||||
}
|
||||
|
||||
return thisID;
|
||||
}
|
||||
|
||||
bool Overlays::editOverlay(OverlayID id, const QVariant& properties) {
|
||||
QUuid Overlays::cloneOverlay(const QUuid& id) {
|
||||
if (_shuttingDown) {
|
||||
return UNKNOWN_OVERLAY_ID;
|
||||
}
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QUuid result;
|
||||
PROFILE_RANGE(script, __FUNCTION__);
|
||||
BLOCKING_INVOKE_METHOD(this, "cloneOverlay", Q_RETURN_ARG(QUuid, result), Q_ARG(const QUuid&, id));
|
||||
return result;
|
||||
}
|
||||
|
||||
Overlay::Pointer overlay = get2DOverlay(id);
|
||||
if (overlay) {
|
||||
return add2DOverlay(Overlay::Pointer(overlay->createClone(), [](Overlay* ptr) { ptr->deleteLater(); }));
|
||||
}
|
||||
|
||||
return DependencyManager::get<EntityScriptingInterface>()->cloneEntity(id);
|
||||
}
|
||||
|
||||
bool Overlays::editOverlay(const QUuid& id, const QVariant& properties) {
|
||||
if (_shuttingDown) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto thisOverlay = getOverlay(id);
|
||||
if (!thisOverlay) {
|
||||
return false;
|
||||
}
|
||||
auto overlay = get2DOverlay(id);
|
||||
if (overlay) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
// NOTE editOverlay can be called very frequently in scripts and can't afford to
|
||||
// block waiting on the main thread. Additionally, no script actually
|
||||
// examines the return value and does something useful with it, so use a non-blocking
|
||||
// invoke and just always return true
|
||||
QMetaObject::invokeMethod(this, "editOverlay", Q_ARG(const QUuid&, id), Q_ARG(const QVariant&, properties));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!thisOverlay->is3D() && QThread::currentThread() != thread()) {
|
||||
// NOTE editOverlay can be called very frequently in scripts and can't afford to
|
||||
// block waiting on the main thread. Additionally, no script actually
|
||||
// examines the return value and does something useful with it, so use a non-blocking
|
||||
// invoke and just always return true
|
||||
QMetaObject::invokeMethod(this, "editOverlay", Q_ARG(OverlayID, id), Q_ARG(QVariant, properties));
|
||||
overlay->setProperties(properties.toMap());
|
||||
return true;
|
||||
}
|
||||
|
||||
thisOverlay->setProperties(properties.toMap());
|
||||
return true;
|
||||
EntityItemProperties entityProperties = convertOverlayToEntityProperties(properties.toMap());
|
||||
return !DependencyManager::get<EntityScriptingInterface>()->editEntity(id, entityProperties).isNull();
|
||||
}
|
||||
|
||||
bool Overlays::editOverlays(const QVariant& propertiesById) {
|
||||
|
@ -326,165 +328,166 @@ bool Overlays::editOverlays(const QVariant& propertiesById) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool defer2DOverlays = QThread::currentThread() != thread();
|
||||
bool deferOverlays = QThread::currentThread() != thread();
|
||||
|
||||
QVariantMap deferrred;
|
||||
QVariantMap deferred;
|
||||
const QVariantMap map = propertiesById.toMap();
|
||||
bool success = true;
|
||||
for (const auto& key : map.keys()) {
|
||||
OverlayID id = OverlayID(key);
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
if (!thisOverlay) {
|
||||
success = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
QUuid id = QUuid(key);
|
||||
const QVariant& properties = map[key];
|
||||
if (defer2DOverlays && !thisOverlay->is3D()) {
|
||||
deferrred[key] = properties;
|
||||
continue;
|
||||
|
||||
Overlay::Pointer overlay = get2DOverlay(id);
|
||||
if (overlay) {
|
||||
if (deferOverlays) {
|
||||
deferred[key] = properties;
|
||||
continue;
|
||||
}
|
||||
overlay->setProperties(properties.toMap());
|
||||
} else {
|
||||
EntityItemProperties entityProperties = convertOverlayToEntityProperties(properties.toMap());
|
||||
DependencyManager::get<EntityScriptingInterface>()->editEntity(id, entityProperties);
|
||||
}
|
||||
thisOverlay->setProperties(properties.toMap());
|
||||
}
|
||||
|
||||
// For 2D/QML overlays, we need to perform the edit on the main thread
|
||||
if (defer2DOverlays && !deferrred.empty()) {
|
||||
if (!deferred.empty()) {
|
||||
// NOTE see comment on editOverlay for why this is not a blocking call
|
||||
QMetaObject::invokeMethod(this, "editOverlays", Q_ARG(QVariant, deferrred));
|
||||
QMetaObject::invokeMethod(this, "editOverlays", Q_ARG(const QVariant&, deferred));
|
||||
}
|
||||
|
||||
return success;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Overlays::deleteOverlay(EntityItemID id) {
|
||||
void Overlays::deleteOverlay(const QUuid& id) {
|
||||
if (_shuttingDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
Overlay::Pointer overlay = get2DOverlay(id);
|
||||
if (overlay) {
|
||||
_overlaysToDelete.push_back(overlay);
|
||||
emit overlayDeleted(id);
|
||||
return;
|
||||
}
|
||||
|
||||
DependencyManager::get<EntityScriptingInterface>()->deleteEntity(id);
|
||||
emit overlayDeleted(id);
|
||||
}
|
||||
|
||||
QString Overlays::getOverlayType(OverlayID overlayId) {
|
||||
QString Overlays::getOverlayType(const QUuid& id) {
|
||||
if (_shuttingDown) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QString result;
|
||||
PROFILE_RANGE(script, __FUNCTION__);
|
||||
BLOCKING_INVOKE_METHOD(this, "getOverlayType", Q_RETURN_ARG(QString, result), Q_ARG(OverlayID, overlayId));
|
||||
BLOCKING_INVOKE_METHOD(this, "getOverlayType", Q_RETURN_ARG(QString, result), Q_ARG(const QUuid&, id));
|
||||
return result;
|
||||
}
|
||||
|
||||
Overlay::Pointer overlay = getOverlay(overlayId);
|
||||
Overlay::Pointer overlay = get2DOverlay(id);
|
||||
if (overlay) {
|
||||
return overlay->getType();
|
||||
}
|
||||
return "";
|
||||
|
||||
return entityToOverlayType(DependencyManager::get<EntityScriptingInterface>()->getEntityType(id));
|
||||
}
|
||||
|
||||
QObject* Overlays::getOverlayObject(OverlayID id) {
|
||||
QObject* Overlays::getOverlayObject(const QUuid& id) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QObject* result;
|
||||
PROFILE_RANGE(script, __FUNCTION__);
|
||||
BLOCKING_INVOKE_METHOD(this, "getOverlayObject", Q_RETURN_ARG(QObject*, result), Q_ARG(OverlayID, id));
|
||||
BLOCKING_INVOKE_METHOD(this, "getOverlayObject", Q_RETURN_ARG(QObject*, result), Q_ARG(const QUuid&, id));
|
||||
return result;
|
||||
}
|
||||
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
if (thisOverlay) {
|
||||
return qobject_cast<QObject*>(&(*thisOverlay));
|
||||
Overlay::Pointer overlay = get2DOverlay(id);
|
||||
if (overlay) {
|
||||
return qobject_cast<QObject*>(&(*overlay));
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
return DependencyManager::get<EntityScriptingInterface>()->getEntityObject(id);
|
||||
}
|
||||
|
||||
OverlayID Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
||||
QUuid Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
||||
if (_shuttingDown || !_enabled) {
|
||||
return UNKNOWN_OVERLAY_ID;
|
||||
return UNKNOWN_ENTITY_ID;
|
||||
}
|
||||
|
||||
QMutexLocker locker(&_mutex);
|
||||
QMapIterator<OverlayID, Overlay::Pointer> i(_overlaysHUD);
|
||||
QMapIterator<QUuid, Overlay::Pointer> i(_overlays);
|
||||
unsigned int bestStackOrder = 0;
|
||||
OverlayID bestOverlayID = UNKNOWN_OVERLAY_ID;
|
||||
QUuid bestID = UNKNOWN_ENTITY_ID;
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
auto thisOverlay = std::dynamic_pointer_cast<Overlay2D>(i.value());
|
||||
if (thisOverlay && thisOverlay->getVisible() && thisOverlay->isLoaded() &&
|
||||
thisOverlay->getBoundingRect().contains(point.x, point.y, false)) {
|
||||
if (thisOverlay->getStackOrder() > bestStackOrder) {
|
||||
bestOverlayID = i.key();
|
||||
bestID = i.key();
|
||||
bestStackOrder = thisOverlay->getStackOrder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bestOverlayID;
|
||||
return bestID;
|
||||
}
|
||||
|
||||
OverlayPropertyResult Overlays::getProperty(OverlayID id, const QString& property) {
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
OverlayPropertyResult result;
|
||||
if (thisOverlay && thisOverlay->supportsGetProperty()) {
|
||||
result.value = thisOverlay->getProperty(property);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OverlayPropertyResult Overlays::getProperties(const OverlayID& id, const QStringList& properties) {
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
OverlayPropertyResult result;
|
||||
if (thisOverlay && thisOverlay->supportsGetProperty()) {
|
||||
QVariantMap mapResult;
|
||||
for (const auto& property : properties) {
|
||||
mapResult.insert(property, thisOverlay->getProperty(property));
|
||||
QVariant Overlays::getProperty(const QUuid& id, const QString& property) {
|
||||
Overlay::Pointer overlay = get2DOverlay(id);
|
||||
if (overlay) {
|
||||
if (overlay->supportsGetProperty()) {
|
||||
return overlay->getProperty(property);
|
||||
}
|
||||
result.value = mapResult;
|
||||
return QVariant();
|
||||
}
|
||||
return result;
|
||||
|
||||
QVariantMap overlayProperties = convertEntityToOverlayProperties(DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(id));
|
||||
auto propIter = overlayProperties.find(property);
|
||||
if (propIter != overlayProperties.end()) {
|
||||
return propIter.value();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
OverlayPropertyResult Overlays::getOverlaysProperties(const QVariant& propertiesById) {
|
||||
QVariantMap map = propertiesById.toMap();
|
||||
OverlayPropertyResult result;
|
||||
QVariantMap resultMap;
|
||||
for (const auto& key : map.keys()) {
|
||||
OverlayID id = OverlayID(key);
|
||||
QVariantMap overlayResult;
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
if (thisOverlay && thisOverlay->supportsGetProperty()) {
|
||||
QStringList propertiesToFetch = map[key].toStringList();
|
||||
for (const auto& property : propertiesToFetch) {
|
||||
overlayResult[property] = thisOverlay->getProperty(property);
|
||||
QVariantMap Overlays::getProperties(const QUuid& id, const QStringList& properties) {
|
||||
Overlay::Pointer overlay = get2DOverlay(id);
|
||||
QVariantMap result;
|
||||
if (overlay) {
|
||||
if (overlay->supportsGetProperty()) {
|
||||
for (const auto& property : properties) {
|
||||
result.insert(property, overlay->getProperty(property));
|
||||
}
|
||||
}
|
||||
resultMap[key] = overlayResult;
|
||||
return result;
|
||||
}
|
||||
|
||||
QVariantMap overlayProperties = convertEntityToOverlayProperties(DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(id));
|
||||
for (const auto& property : properties) {
|
||||
auto propIter = overlayProperties.find(property);
|
||||
if (propIter != overlayProperties.end()) {
|
||||
result.insert(property, propIter.value());
|
||||
}
|
||||
}
|
||||
result.value = resultMap;
|
||||
return result;
|
||||
}
|
||||
|
||||
OverlayPropertyResult::OverlayPropertyResult() {
|
||||
}
|
||||
|
||||
QScriptValue OverlayPropertyResultToScriptValue(QScriptEngine* engine, const OverlayPropertyResult& value) {
|
||||
if (!value.value.isValid()) {
|
||||
return QScriptValue::UndefinedValue;
|
||||
QVariantMap Overlays::getOverlaysProperties(const QVariant& propertiesById) {
|
||||
QVariantMap map = propertiesById.toMap();
|
||||
QVariantMap result;
|
||||
for (const auto& key : map.keys()) {
|
||||
result[key] = getProperties(QUuid(key), map[key].toStringList());
|
||||
}
|
||||
return engine->toScriptValue(value.value);
|
||||
return result;
|
||||
}
|
||||
|
||||
void OverlayPropertyResultFromScriptValue(const QScriptValue& object, OverlayPropertyResult& value) {
|
||||
value.value = object.toVariant();
|
||||
}
|
||||
|
||||
|
||||
RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray, bool precisionPicking,
|
||||
const QScriptValue& overlayIDsToInclude,
|
||||
const QScriptValue& overlayIDsToDiscard,
|
||||
bool visibleOnly, bool collidableOnly) {
|
||||
const QVector<OverlayID> overlaysToInclude = qVectorOverlayIDFromScriptValue(overlayIDsToInclude);
|
||||
const QVector<OverlayID> overlaysToDiscard = qVectorOverlayIDFromScriptValue(overlayIDsToDiscard);
|
||||
const QVector<QUuid> overlaysToInclude = qVectorQUuidFromScriptValue(overlayIDsToInclude);
|
||||
const QVector<QUuid> overlaysToDiscard = qVectorQUuidFromScriptValue(overlayIDsToDiscard);
|
||||
|
||||
return findRayIntersectionVector(ray, precisionPicking,
|
||||
overlaysToInclude, overlaysToDiscard, visibleOnly, collidableOnly);
|
||||
|
@ -492,8 +495,8 @@ RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray,
|
|||
|
||||
|
||||
RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay& ray, bool precisionPicking,
|
||||
const QVector<OverlayID>& overlaysToInclude,
|
||||
const QVector<OverlayID>& overlaysToDiscard,
|
||||
const QVector<QUuid>& overlaysToInclude,
|
||||
const QVector<QUuid>& overlaysToDiscard,
|
||||
bool visibleOnly, bool collidableOnly) {
|
||||
float bestDistance = std::numeric_limits<float>::max();
|
||||
bool bestIsFront = false;
|
||||
|
@ -624,77 +627,71 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R
|
|||
value.extraInfo = object.property("extraInfo").toVariant().toMap();
|
||||
}
|
||||
|
||||
bool Overlays::isLoaded(OverlayID id) {
|
||||
bool Overlays::isLoaded(const QUuid& id) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
bool result;
|
||||
PROFILE_RANGE(script, __FUNCTION__);
|
||||
BLOCKING_INVOKE_METHOD(this, "isLoaded", Q_RETURN_ARG(bool, result), Q_ARG(OverlayID, id));
|
||||
BLOCKING_INVOKE_METHOD(this, "isLoaded", Q_RETURN_ARG(bool, result), Q_ARG(const QUuid&, id));
|
||||
return result;
|
||||
}
|
||||
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
if (!thisOverlay) {
|
||||
return false; // not found
|
||||
Overlay::Pointer overlay = get2DOverlay(id);
|
||||
if (overlay) {
|
||||
return overlay->isLoaded();
|
||||
}
|
||||
return thisOverlay->isLoaded();
|
||||
|
||||
return DependencyManager::get<EntityScriptingInterface>()->isLoaded(id);
|
||||
}
|
||||
|
||||
QSizeF Overlays::textSize(OverlayID id, const QString& text) {
|
||||
QSizeF Overlays::textSize(const QUuid& id, const QString& text) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QSizeF result;
|
||||
PROFILE_RANGE(script, __FUNCTION__);
|
||||
BLOCKING_INVOKE_METHOD(this, "textSize", Q_RETURN_ARG(QSizeF, result), Q_ARG(OverlayID, id), Q_ARG(QString, text));
|
||||
BLOCKING_INVOKE_METHOD(this, "textSize", Q_RETURN_ARG(QSizeF, result), Q_ARG(const QUuid&, id), Q_ARG(QString, text));
|
||||
return result;
|
||||
}
|
||||
|
||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||
if (thisOverlay) {
|
||||
if (thisOverlay->is3D()) {
|
||||
if (auto text3dOverlay = std::dynamic_pointer_cast<Text3DOverlay>(thisOverlay)) {
|
||||
return text3dOverlay->textSize(text);
|
||||
}
|
||||
} else {
|
||||
if (auto textOverlay = std::dynamic_pointer_cast<TextOverlay>(thisOverlay)) {
|
||||
return textOverlay->textSize(text);
|
||||
}
|
||||
Overlay::Pointer overlay = get2DOverlay(id);
|
||||
if (overlay) {
|
||||
if (auto textOverlay = std::dynamic_pointer_cast<TextOverlay>(overlay)) {
|
||||
return textOverlay->textSize(text);
|
||||
}
|
||||
return QSizeF(0.0f, 0.0f);
|
||||
} else {
|
||||
return DependencyManager::get<EntityScriptingInterface>()->textSize(id, text);
|
||||
}
|
||||
return QSizeF(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
bool Overlays::isAddedOverlay(OverlayID id) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
bool result;
|
||||
PROFILE_RANGE(script, __FUNCTION__);
|
||||
BLOCKING_INVOKE_METHOD(this, "isAddedOverlay", Q_RETURN_ARG(bool, result), Q_ARG(OverlayID, id));
|
||||
return result;
|
||||
bool Overlays::isAddedOverlay(const QUuid& id) {
|
||||
Overlay::Pointer overlay = get2DOverlay(id);
|
||||
if (overlay) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QMutexLocker locker(&_mutex);
|
||||
return _overlaysHUD.contains(id) || _overlaysWorld.contains(id);
|
||||
return DependencyManager::get<EntityScriptingInterface>()->isAddedEntity(id);
|
||||
}
|
||||
|
||||
void Overlays::sendMousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
void Overlays::sendMousePressOnOverlay(const QUuid& overlayID, const PointerEvent& event) {
|
||||
mousePressPointerEvent(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendMouseReleaseOnOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
void Overlays::sendMouseReleaseOnOverlay(const QUuid& overlayID, const PointerEvent& event) {
|
||||
mouseReleasePointerEvent(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendMouseMoveOnOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
void Overlays::sendMouseMoveOnOverlay(const QUuid& overlayID, const PointerEvent& event) {
|
||||
mouseMovePointerEvent(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendHoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
void Overlays::sendHoverEnterOverlay(const QUuid& overlayID, const PointerEvent& event) {
|
||||
hoverEnterPointerEvent(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendHoverOverOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
void Overlays::sendHoverOverOverlay(const QUuid& overlayID, const PointerEvent& event) {
|
||||
hoverOverPointerEvent(overlayID, event);
|
||||
}
|
||||
|
||||
void Overlays::sendHoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
void Overlays::sendHoverLeaveOverlay(const QUuid& overlayID, const PointerEvent& event) {
|
||||
hoverLeavePointerEvent(overlayID, event);
|
||||
}
|
||||
|
||||
|
@ -765,10 +762,10 @@ static PointerEvent::Button toPointerButton(const QMouseEvent& event) {
|
|||
}
|
||||
}
|
||||
|
||||
PointerEvent Overlays::calculateOverlayPointerEvent(OverlayID overlayID, PickRay ray,
|
||||
RayToOverlayIntersectionResult rayPickResult, 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<Planar3DOverlay>(getOverlay(overlayID));
|
||||
auto overlay = std::dynamic_pointer_cast<Planar3DOverlay>(getOverlay(id));
|
||||
if (getOverlayType(overlayID) == "web3d") {
|
||||
overlay = std::dynamic_pointer_cast<Web3DOverlay>(getOverlay(overlayID));
|
||||
}
|
||||
|
@ -793,8 +790,7 @@ bool Overlays::mousePressEvent(QMouseEvent* event) {
|
|||
PerformanceTimer perfTimer("Overlays::mousePressEvent");
|
||||
|
||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
|
||||
QVector<OverlayID>());
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<QUuid>(), QVector<QUuid>());
|
||||
if (rayPickResult.intersects) {
|
||||
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
||||
|
||||
|
@ -839,8 +835,7 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) {
|
|||
PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent");
|
||||
|
||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
|
||||
QVector<OverlayID>());
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(), QVector<OverlayID>());
|
||||
if (rayPickResult.intersects) {
|
||||
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
||||
|
||||
|
|
|
@ -32,19 +32,6 @@
|
|||
|
||||
class PickRay;
|
||||
|
||||
class OverlayPropertyResult {
|
||||
public:
|
||||
OverlayPropertyResult();
|
||||
QVariant value;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(OverlayPropertyResult);
|
||||
|
||||
QScriptValue OverlayPropertyResultToScriptValue(QScriptEngine* engine, const OverlayPropertyResult& value);
|
||||
void OverlayPropertyResultFromScriptValue(const QScriptValue& object, OverlayPropertyResult& value);
|
||||
|
||||
const OverlayID UNKNOWN_OVERLAY_ID = OverlayID();
|
||||
|
||||
/**jsdoc
|
||||
* The result of a {@link PickRay} search using {@link Overlays.findRayIntersection|findRayIntersection}.
|
||||
* @typedef {object} Overlays.RayToOverlayIntersectionResult
|
||||
|
@ -59,7 +46,7 @@ const OverlayID UNKNOWN_OVERLAY_ID = OverlayID();
|
|||
class RayToOverlayIntersectionResult {
|
||||
public:
|
||||
bool intersects { false };
|
||||
OverlayID overlayID { UNKNOWN_OVERLAY_ID };
|
||||
QUuid overlayID { UNKNOWN_OVERLAY_ID };
|
||||
float distance { 0.0f };
|
||||
BoxFace face { UNKNOWN_FACE };
|
||||
glm::vec3 surfaceNormal;
|
||||
|
@ -73,7 +60,7 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R
|
|||
class ParabolaToOverlayIntersectionResult {
|
||||
public:
|
||||
bool intersects { false };
|
||||
OverlayID overlayID { UNKNOWN_OVERLAY_ID };
|
||||
QUuid overlayID { UNKNOWN_OVERLAY_ID };
|
||||
float distance { 0.0f };
|
||||
float parabolicDistance { 0.0f };
|
||||
BoxFace face { UNKNOWN_FACE };
|
||||
|
@ -83,7 +70,7 @@ public:
|
|||
};
|
||||
|
||||
/**jsdoc
|
||||
* Deprecated. Use local entities instead. The Overlays API provides facilities to create and interact with overlays. Overlays are 2D and 3D objects visible only to
|
||||
* (Note: 3D Overlays are deprecated. Use local entities instead.) The Overlays API provides facilities to create and interact with overlays. Overlays are 2D and 3D objects visible only to
|
||||
* yourself and that aren't persisted to the domain. They are used for UI.
|
||||
* @namespace Overlays
|
||||
*
|
||||
|
@ -98,31 +85,31 @@ public:
|
|||
class Overlays : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(OverlayID keyboardFocusOverlay READ getKeyboardFocusOverlay WRITE setKeyboardFocusOverlay)
|
||||
Q_PROPERTY(QUuid keyboardFocusOverlay READ getKeyboardFocusOverlay WRITE setKeyboardFocusOverlay)
|
||||
|
||||
public:
|
||||
Overlays();
|
||||
|
||||
void init();
|
||||
void update(float deltatime);
|
||||
void renderHUD(RenderArgs* renderArgs);
|
||||
void render(RenderArgs* renderArgs);
|
||||
void disable();
|
||||
void enable();
|
||||
|
||||
Overlay::Pointer getOverlay(OverlayID id) const;
|
||||
Overlay::Pointer get2DOverlay(const QUuid& id) const;
|
||||
|
||||
/// adds an overlay that's already been created
|
||||
OverlayID addOverlay(Overlay* overlay) { return addOverlay(Overlay::Pointer(overlay)); }
|
||||
OverlayID addOverlay(const Overlay::Pointer& overlay);
|
||||
QUuid addOverlay(Overlay* overlay) { return add2DOverlay(Overlay::Pointer(overlay)); }
|
||||
QUuid add2DOverlay(const Overlay::Pointer& overlay);
|
||||
|
||||
RayToOverlayIntersectionResult findRayIntersectionVector(const PickRay& ray, bool precisionPicking,
|
||||
const QVector<OverlayID>& overlaysToInclude,
|
||||
const QVector<OverlayID>& overlaysToDiscard,
|
||||
const QVector<QUuid>& overlaysToInclude,
|
||||
const QVector<QUuid>& overlaysToDiscard,
|
||||
bool visibleOnly = false, bool collidableOnly = false);
|
||||
|
||||
ParabolaToOverlayIntersectionResult findParabolaIntersectionVector(const PickParabola& parabola, bool precisionPicking,
|
||||
const QVector<OverlayID>& overlaysToInclude,
|
||||
const QVector<OverlayID>& overlaysToDiscard,
|
||||
const QVector<QUuid>& overlaysToInclude,
|
||||
const QVector<QUuid>& overlaysToDiscard,
|
||||
bool visibleOnly = false, bool collidableOnly = false);
|
||||
|
||||
bool mousePressEvent(QMouseEvent* event);
|
||||
|
@ -147,20 +134,20 @@ public slots:
|
|||
* solid: true
|
||||
* });
|
||||
*/
|
||||
OverlayID addOverlay(const QString& type, const QVariant& properties);
|
||||
QUuid addOverlay(const QString& type, const QVariant& properties);
|
||||
|
||||
/**jsdoc
|
||||
* Create a clone of an existing entity.
|
||||
* Create a clone of an existing entity (or 2D overlay).
|
||||
* @function Overlays.cloneOverlay
|
||||
* @param {Uuid} id - The ID of the entity to clone.
|
||||
* @returns {Uuid} The ID of the new entity if successful, otherwise {@link Uuid|Uuid.NULL}.
|
||||
* @param {Uuid} id - The ID of the entity/2D overlay to clone.
|
||||
* @returns {Uuid} The ID of the new object if successful, otherwise {@link Uuid|Uuid.NULL}.
|
||||
*/
|
||||
EntityItemID cloneOverlay(EntityItemID id) { return DependencyManager::get<EntityScriptingInterface>()->cloneEntity(id); }
|
||||
QUuid cloneOverlay(const QUuid& id);
|
||||
|
||||
/**jsdoc
|
||||
* Edit an overlay's properties.
|
||||
* @function Overlays.editOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay to edit.
|
||||
* @param {Uuid} id - The ID of the overlay to edit.
|
||||
* @param {Overlays.OverlayProperties} properties - The properties changes to make.
|
||||
* @returns {boolean} <code>true</code> if the overlay was found and edited, otherwise <code>false</code>.
|
||||
* @example <caption>Add an overlay in front of your avatar then change its color.</caption>
|
||||
|
@ -176,7 +163,7 @@ public slots:
|
|||
* });
|
||||
* print("Success: " + success);
|
||||
*/
|
||||
bool editOverlay(OverlayID id, const QVariant& properties);
|
||||
bool editOverlay(const QUuid& id, const QVariant& properties);
|
||||
|
||||
/**jsdoc
|
||||
* Edit multiple overlays' properties.
|
||||
|
@ -208,18 +195,18 @@ public slots:
|
|||
bool editOverlays(const QVariant& propertiesById);
|
||||
|
||||
/**jsdoc
|
||||
* Delete an entity.
|
||||
* Delete an entity or 2D overlay.
|
||||
* @function Overlays.deleteOverlay
|
||||
* @param {Uuid} id - The ID of the entity to delete.
|
||||
* @param {Uuid} id - The ID of the object to delete.
|
||||
*/
|
||||
void deleteOverlay(EntityItemID id);
|
||||
void deleteOverlay(const QUuid& id);
|
||||
|
||||
/**jsdoc
|
||||
* Get the type of an overlay.
|
||||
* Get the type of an entity or 2D overlay.
|
||||
* @function Overlays.getOverlayType
|
||||
* @param {Uuid} overlayID - The ID of the overlay to get the type of.
|
||||
* @returns {Overlays.OverlayType} The type of the overlay if found, otherwise an empty string.
|
||||
* @example <caption>Create an overlay in front of your avatar then get and report its type.</caption>
|
||||
* @param {Uuid} id - The ID of the object to get the type of.
|
||||
* @returns {string} The type of the object if found, otherwise an empty string.
|
||||
* @example <caption>Create an object in front of your avatar then get and report its type.</caption>
|
||||
* var overlay = Overlays.addOverlay("cube", {
|
||||
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -3 })),
|
||||
* rotation: MyAvatar.orientation,
|
||||
|
@ -229,7 +216,7 @@ public slots:
|
|||
* var type = Overlays.getOverlayType(overlay);
|
||||
* print("Type: " + type);
|
||||
*/
|
||||
QString getOverlayType(OverlayID overlayId);
|
||||
QString getOverlayType(const QUuid& id);
|
||||
|
||||
/**jsdoc
|
||||
* Get the overlay script object. In particular, this is useful for accessing the event bridge for a <code>web3d</code>
|
||||
|
@ -273,7 +260,7 @@ public slots:
|
|||
* Overlays.deleteOverlay(web3dOverlay);
|
||||
* });
|
||||
*/
|
||||
QObject* getOverlayObject(OverlayID id);
|
||||
QObject* getOverlayObject(const QUuid& id);
|
||||
|
||||
/**jsdoc
|
||||
* Get the ID of the 2D overlay at a particular point on the screen or HUD.
|
||||
|
@ -292,12 +279,12 @@ public slots:
|
|||
* print("Clicked: " + overlay);
|
||||
* });
|
||||
*/
|
||||
OverlayID getOverlayAtPoint(const glm::vec2& point);
|
||||
QUuid getOverlayAtPoint(const glm::vec2& point);
|
||||
|
||||
/**jsdoc
|
||||
* Get the value of a 3D overlay's property.
|
||||
* @function Overlays.getProperty
|
||||
* @param {Uuid} overlayID - The ID of the overlay. <em>Must be for a 3D {@link Overlays.OverlayType|OverlayType}.</em>
|
||||
* @param {Uuid} id - The ID of the overlay. <em>Must be for a 3D {@link Overlays.OverlayType|OverlayType}.</em>
|
||||
* @param {string} property - The name of the property value to get.
|
||||
* @returns {object} The value of the property if the 3D overlay and property can be found, otherwise
|
||||
* <code>undefined</code>.
|
||||
|
@ -311,12 +298,12 @@ public slots:
|
|||
* var alpha = Overlays.getProperty(overlay, "alpha");
|
||||
* print("Overlay alpha: " + alpha);
|
||||
*/
|
||||
OverlayPropertyResult getProperty(OverlayID id, const QString& property);
|
||||
QVariant getProperty(const QUuid& id, const QString& property);
|
||||
|
||||
/**jsdoc
|
||||
* Get the values of an overlay's properties.
|
||||
* @function Overlays.getProperties
|
||||
* @param {Uuid} overlayID - The ID of the overlay.
|
||||
* @param {Uuid} id - The ID of the overlay.
|
||||
* @param {Array.<string>} properties - An array of names of properties to get the values of.
|
||||
* @returns {Overlays.OverlayProperties} The values of valid properties if the overlay can be found, otherwise
|
||||
* <code>undefined</code>.
|
||||
|
@ -330,7 +317,7 @@ public slots:
|
|||
* var properties = Overlays.getProperties(overlay, ["color", "alpha", "grabbable"]);
|
||||
* print("Overlay properties: " + JSON.stringify(properties));
|
||||
*/
|
||||
OverlayPropertyResult getProperties(const OverlayID& id, const QStringList& properties);
|
||||
QVariantMap getProperties(const QUuid& id, const QStringList& properties);
|
||||
|
||||
/**jsdoc
|
||||
* Get the values of multiple overlays' properties.
|
||||
|
@ -358,7 +345,7 @@ public slots:
|
|||
* var properties = Overlays.getOverlaysProperties(propertiesToGet);
|
||||
* print("Overlays properties: " + JSON.stringify(properties));
|
||||
*/
|
||||
OverlayPropertyResult getOverlaysProperties(const QVariant& overlaysProperties);
|
||||
QVariantMap getOverlaysProperties(const QVariant& overlaysProperties);
|
||||
|
||||
/**jsdoc
|
||||
* Find the closest 3D overlay intersected by a {@link PickRay}. Overlays with their <code>drawInFront</code> property set
|
||||
|
@ -428,7 +415,7 @@ public slots:
|
|||
* Check whether an overlay's assets have been loaded. For example, for an <code>image</code> overlay the result indicates
|
||||
* whether its image has been loaded.
|
||||
* @function Overlays.isLoaded
|
||||
* @param {Uuid} overlayID - The ID of the overlay to check.
|
||||
* @param {Uuid} id - The ID of the overlay to check.
|
||||
* @returns {boolean} <code>true</code> if the overlay's assets have been loaded, otherwise <code>false</code>.
|
||||
* @example <caption>Create an image overlay and report whether its image is loaded after 1s.</caption>
|
||||
* var overlay = Overlays.addOverlay("image", {
|
||||
|
@ -440,17 +427,17 @@ public slots:
|
|||
* print("Image loaded: " + isLoaded);
|
||||
* }, 1000);
|
||||
*/
|
||||
bool isLoaded(OverlayID id);
|
||||
bool isLoaded(const QUuid& id);
|
||||
|
||||
/**jsdoc
|
||||
* Calculates the size of the given text in the specified overlay if it is a text overlay.
|
||||
* Calculates the size of the given text in the specified object if it is a text entity or overlay.
|
||||
* @function Overlays.textSize
|
||||
* @param {Uuid} overlayID - The ID of the overlay to use for calculation.
|
||||
* @param {Uuid} id - The ID of the object to use for calculation.
|
||||
* @param {string} text - The string to calculate the size of.
|
||||
* @returns {Size} The size of the <code>text</code> if the overlay is a text overlay, otherwise
|
||||
* <code>{ height: 0, width : 0 }</code>. If the overlay is a 2D overlay, the size is in pixels; if the overlay is a 3D
|
||||
* overlay, the size is in meters.
|
||||
* @example <caption>Calculate the size of "hello" in a 3D text overlay.</caption>
|
||||
* @returns {Size} The size of the <code>text</code> if the object is a text entity or overlay, otherwise
|
||||
* <code>{ height: 0, width : 0 }</code>. If the object is a 2D overlay, the size is in pixels; if the object is an entity,
|
||||
* the size is in meters.
|
||||
* @example <caption>Calculate the size of "hello" in a 3D text entity.</caption>
|
||||
* var overlay = Overlays.addOverlay("text3d", {
|
||||
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -2 })),
|
||||
* rotation: MyAvatar.orientation,
|
||||
|
@ -460,7 +447,7 @@ public slots:
|
|||
* var textSize = Overlays.textSize(overlay, "hello");
|
||||
* print("Size of \"hello\": " + JSON.stringify(textSize));
|
||||
*/
|
||||
QSizeF textSize(OverlayID id, const QString& text);
|
||||
QSizeF textSize(const QUuid& id, const QString& text);
|
||||
|
||||
/**jsdoc
|
||||
* Get the width of the window or HUD.
|
||||
|
@ -477,17 +464,17 @@ public slots:
|
|||
float height();
|
||||
|
||||
/**jsdoc
|
||||
* Check if there is an overlay of a given ID.
|
||||
* Check if there is an object of a given ID.
|
||||
* @function Overlays.isAddedOverlay
|
||||
* @param {Uuid} overlayID - The ID to check.
|
||||
* @returns {boolean} <code>true</code> if an overlay with the given ID exists, <code>false</code> otherwise.
|
||||
* @param {Uuid} id - The ID to check.
|
||||
* @returns {boolean} <code>true</code> if an object with the given ID exists, <code>false</code> otherwise.
|
||||
*/
|
||||
bool isAddedOverlay(OverlayID id);
|
||||
bool isAddedOverlay(const QUuid& id);
|
||||
|
||||
/**jsdoc
|
||||
* Generate a mouse press event on an overlay.
|
||||
* @function Overlays.sendMousePressOnOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay to generate a mouse press event on.
|
||||
* @param {Uuid} id - The ID of the overlay to generate a mouse press event on.
|
||||
* @param {PointerEvent} event - The mouse press event details.
|
||||
* @example <caption>Create a 2D rectangle overlay plus a 3D cube overlay and generate mousePressOnOverlay events for the 2D
|
||||
* overlay.</caption>
|
||||
|
@ -522,23 +509,23 @@ public slots:
|
|||
* }
|
||||
* });
|
||||
*/
|
||||
void sendMousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void sendMousePressOnOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Generate a mouse release event on an overlay.
|
||||
* @function Overlays.sendMouseReleaseOnOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay to generate a mouse release event on.
|
||||
* @param {Uuid} id - The ID of the overlay to generate a mouse release event on.
|
||||
* @param {PointerEvent} event - The mouse release event details.
|
||||
*/
|
||||
void sendMouseReleaseOnOverlay(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void sendMouseReleaseOnOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Generate a mouse move event on an overlay.
|
||||
* @function Overlays.sendMouseMoveOnOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay to generate a mouse move event on.
|
||||
* @param {Uuid} id - The ID of the overlay to generate a mouse move event on.
|
||||
* @param {PointerEvent} event - The mouse move event details.
|
||||
*/
|
||||
void sendMouseMoveOnOverlay(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void sendMouseMoveOnOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Generate a hover enter event on an overlay.
|
||||
|
@ -546,23 +533,23 @@ public slots:
|
|||
* @param {Uuid} id - The ID of the overlay to generate a hover enter event on.
|
||||
* @param {PointerEvent} event - The hover enter event details.
|
||||
*/
|
||||
void sendHoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void sendHoverEnterOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Generate a hover over event on an overlay.
|
||||
* @function Overlays.sendHoverOverOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay to generate a hover over event on.
|
||||
* @param {Uuid} id - The ID of the overlay to generate a hover over event on.
|
||||
* @param {PointerEvent} event - The hover over event details.
|
||||
*/
|
||||
void sendHoverOverOverlay(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void sendHoverOverOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Generate a hover leave event on an overlay.
|
||||
* @function Overlays.sendHoverLeaveOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay to generate a hover leave event on.
|
||||
* @param {Uuid} id - The ID of the overlay to generate a hover leave event on.
|
||||
* @param {PointerEvent} event - The hover leave event details.
|
||||
*/
|
||||
void sendHoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void sendHoverLeaveOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Get the ID of the Web3D local entity that has keyboard focus.
|
||||
|
@ -575,16 +562,16 @@ public slots:
|
|||
/**jsdoc
|
||||
* Set the Web3D local entity that has keyboard focus.
|
||||
* @function Overlays.setKeyboardFocusOverlay
|
||||
* @param {Uuid} overlayID - The ID of the {@link Entities.EntityTypes|Web} overlay to set keyboard focus to. Use
|
||||
* @param {Uuid} id - The ID of the {@link Entities.EntityTypes|Web} overlay to set keyboard focus to. Use
|
||||
* <code>null</code> or {@link Uuid|Uuid.NULL} to unset keyboard focus from an overlay.
|
||||
*/
|
||||
void Overlays::setKeyboardFocusOverlay(const EntityItemID& id) { DependencyManager::get<EntityScriptingInterface>()->setKeyboardFocusLocalEntity(id); }
|
||||
void setKeyboardFocusOverlay(const EntityItemID& id) { DependencyManager::get<EntityScriptingInterface>()->setKeyboardFocusLocalEntity(id); }
|
||||
|
||||
signals:
|
||||
/**jsdoc
|
||||
* Triggered when an overlay is deleted.
|
||||
* @function Overlays.overlayDeleted
|
||||
* @param {Uuid} overlayID - The ID of the overlay that was deleted.
|
||||
* @param {Uuid} id - The ID of the overlay that was deleted.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Create an overlay then delete it after 1s.</caption>
|
||||
* var overlay = Overlays.addOverlay("cube", {
|
||||
|
@ -602,13 +589,13 @@ signals:
|
|||
* Overlays.deleteOverlay(overlay);
|
||||
* }, 1000);
|
||||
*/
|
||||
void overlayDeleted(OverlayID id);
|
||||
void overlayDeleted(const QUuid& id);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a mouse press event occurs on an overlay. Only occurs for 3D overlays (unless you use
|
||||
* {@link Overlays.sendMousePressOnOverlay|sendMousePressOnOverlay} for a 2D overlay).
|
||||
* @function Overlays.mousePressOnOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay the mouse press event occurred on.
|
||||
* @param {Uuid} id - The ID of the overlay the mouse press event occurred on.
|
||||
* @param {PointerEvent} event - The mouse press event details.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Create a cube overlay in front of your avatar and report mouse clicks on it.</caption>
|
||||
|
@ -626,36 +613,36 @@ signals:
|
|||
* }
|
||||
* });
|
||||
*/
|
||||
void mousePressOnOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void mousePressOnOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a mouse double press event occurs on an overlay. Only occurs for 3D overlays.
|
||||
* @function Overlays.mouseDoublePressOnOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay the mouse double press event occurred on.
|
||||
* @param {Uuid} id - The ID of the overlay the mouse double press event occurred on.
|
||||
* @param {PointerEvent} event - The mouse double press event details.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void mouseDoublePressOnOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void mouseDoublePressOnOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a mouse release event occurs on an overlay. Only occurs for 3D overlays (unless you use
|
||||
* {@link Overlays.sendMouseReleaseOnOverlay|sendMouseReleaseOnOverlay} for a 2D overlay).
|
||||
* @function Overlays.mouseReleaseOnOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay the mouse release event occurred on.
|
||||
* @param {Uuid} id - The ID of the overlay the mouse release event occurred on.
|
||||
* @param {PointerEvent} event - The mouse release event details.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void mouseReleaseOnOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void mouseReleaseOnOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a mouse move event occurs on an overlay. Only occurs for 3D overlays (unless you use
|
||||
* {@link Overlays.sendMouseMoveOnOverlay|sendMouseMoveOnOverlay} for a 2D overlay).
|
||||
* @function Overlays.mouseMoveOnOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay the mouse moved event occurred on.
|
||||
* @param {Uuid} id - The ID of the overlay the mouse moved event occurred on.
|
||||
* @param {PointerEvent} event - The mouse move event details.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void mouseMoveOnOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void mouseMoveOnOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a mouse press event occurs on something other than a 3D overlay.
|
||||
|
@ -675,7 +662,7 @@ signals:
|
|||
* Triggered when a mouse cursor starts hovering over an overlay. Only occurs for 3D overlays (unless you use
|
||||
* {@link Overlays.sendHoverEnterOverlay|sendHoverEnterOverlay} for a 2D overlay).
|
||||
* @function Overlays.hoverEnterOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay the mouse moved event occurred on.
|
||||
* @param {Uuid} id - The ID of the overlay the mouse moved event occurred on.
|
||||
* @param {PointerEvent} event - The mouse move event details.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Create a cube overlay in front of your avatar and report when you start hovering your mouse over
|
||||
|
@ -691,54 +678,53 @@ signals:
|
|||
* print("Hover enter: " + overlayID);
|
||||
* });
|
||||
*/
|
||||
void hoverEnterOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void hoverEnterOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a mouse cursor continues hovering over an overlay. Only occurs for 3D overlays (unless you use
|
||||
* {@link Overlays.sendHoverOverOverlay|sendHoverOverOverlay} for a 2D overlay).
|
||||
* @function Overlays.hoverOverOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay the hover over event occurred on.
|
||||
* @param {Uuid} id - The ID of the overlay the hover over event occurred on.
|
||||
* @param {PointerEvent} event - The hover over event details.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void hoverOverOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void hoverOverOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a mouse cursor finishes hovering over an overlay. Only occurs for 3D overlays (unless you use
|
||||
* {@link Overlays.sendHoverLeaveOverlay|sendHoverLeaveOverlay} for a 2D overlay).
|
||||
* @function Overlays.hoverLeaveOverlay
|
||||
* @param {Uuid} overlayID - The ID of the overlay the hover leave event occurred on.
|
||||
* @param {Uuid} id - The ID of the overlay the hover leave event occurred on.
|
||||
* @param {PointerEvent} event - The hover leave event details.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void hoverLeaveOverlay(OverlayID overlayID, const PointerEvent& event);
|
||||
void hoverLeaveOverlay(const QUuid& id, const PointerEvent& event);
|
||||
|
||||
private:
|
||||
void cleanupOverlaysToDelete();
|
||||
|
||||
mutable QMutex _mutex { QMutex::Recursive };
|
||||
QMap<OverlayID, Overlay::Pointer> _overlaysHUD;
|
||||
QMap<OverlayID, Overlay::Pointer> _overlaysWorld;
|
||||
|
||||
QMap<QUuid, Overlay::Pointer> _overlays;
|
||||
QList<Overlay::Pointer> _overlaysToDelete;
|
||||
|
||||
unsigned int _stackOrder { 1 };
|
||||
|
||||
bool _enabled = true;
|
||||
std::atomic<bool> _shuttingDown{ false };
|
||||
bool _enabled { true };
|
||||
std::atomic<bool> _shuttingDown { false };
|
||||
|
||||
PointerEvent calculateOverlayPointerEvent(OverlayID overlayID, PickRay ray, RayToOverlayIntersectionResult rayPickResult,
|
||||
PointerEvent calculateOverlayPointerEvent(const QUuid& id, const PickRay& ray, const RayToOverlayIntersectionResult& rayPickResult,
|
||||
QMouseEvent* event, PointerEvent::EventType eventType);
|
||||
|
||||
OverlayID _currentClickingOnOverlayID { UNKNOWN_OVERLAY_ID };
|
||||
OverlayID _currentHoverOverOverlayID { UNKNOWN_OVERLAY_ID };
|
||||
QUuid _currentClickingOnOverlayID { UNKNOWN_OVERLAY_ID };
|
||||
QUuid _currentHoverOverOverlayID { UNKNOWN_OVERLAY_ID };
|
||||
|
||||
private slots:
|
||||
void mousePressPointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void mouseMovePointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void mouseReleasePointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void hoverEnterPointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void hoverOverPointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void hoverLeavePointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void mousePressPointerEvent(const QUuid& id, const PointerEvent& event);
|
||||
void mouseMovePointerEvent(const QUuid& id, const PointerEvent& event);
|
||||
void mouseReleasePointerEvent(const QUuid& id, const PointerEvent& event);
|
||||
void hoverEnterPointerEvent(const QUuid& id, const PointerEvent& event);
|
||||
void hoverOverPointerEvent(const QUuid& id, const PointerEvent& event);
|
||||
void hoverLeavePointerEvent(const QUuid& id, const PointerEvent& event);
|
||||
};
|
||||
|
||||
#endif // hifi_Overlays_h
|
||||
|
|
|
@ -104,8 +104,8 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi
|
|||
});
|
||||
_emitting = entity->getIsEmitting();
|
||||
|
||||
bool hasTexture = resultWithReadLock<bool>([&]{ return _particleProperties.textures.isEmpty(); });
|
||||
if (hasTexture) {
|
||||
bool textureEmpty = resultWithReadLock<bool>([&]{ return _particleProperties.textures.isEmpty(); });
|
||||
if (textureEmpty) {
|
||||
if (_networkTexture) {
|
||||
withWriteLock([&] {
|
||||
_networkTexture.reset();
|
||||
|
|
|
@ -23,6 +23,9 @@ using namespace render;
|
|||
using namespace render::entities;
|
||||
|
||||
static const int FIXED_FONT_POINT_SIZE = 40;
|
||||
const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 92.0f; // Determined through experimentation to fit font to line
|
||||
// height.
|
||||
const float LINE_SCALE_RATIO = 1.2f;
|
||||
|
||||
TextEntityRenderer::TextEntityRenderer(const EntityItemPointer& entity) :
|
||||
Parent(entity),
|
||||
|
@ -205,3 +208,12 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
|||
dimensions.y - (_topMargin + _bottomMargin));
|
||||
_textRenderer->draw(batch, _leftMargin / scale, -_topMargin / scale, _text, textColor, bounds / scale);
|
||||
}
|
||||
|
||||
QSizeF TextEntityRenderer::textSize(const QString& text) const {
|
||||
auto extents = _textRenderer->computeExtent(text);
|
||||
|
||||
float maxHeight = (float)_textRenderer->computeExtent("Xy").y * LINE_SCALE_RATIO;
|
||||
float pointToWorldScale = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight;
|
||||
|
||||
return QSizeF(extents.x, extents.y) * pointToWorldScale;
|
||||
}
|
|
@ -29,6 +29,8 @@ public:
|
|||
bool isTransparent() const override;
|
||||
ShapeKey getShapeKey() override;
|
||||
|
||||
QSizeF textSize(const QString& text) const;
|
||||
|
||||
private:
|
||||
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
|
||||
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
|
||||
|
|
|
@ -47,6 +47,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void setProxyWindow(QWindow* proxyWindow) override;
|
||||
virtual QObject* getEventHandler() override;
|
||||
|
||||
protected:
|
||||
virtual bool needsRenderUpdate() const override;
|
||||
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
|
||||
|
@ -57,9 +60,6 @@ protected:
|
|||
virtual bool wantsHandControllerPointerEvents() const override { return true; }
|
||||
virtual bool wantsKeyboardFocus() const override { return true; }
|
||||
|
||||
virtual void setProxyWindow(QWindow* proxyWindow) override;
|
||||
virtual QObject* getEventHandler() override;
|
||||
|
||||
void handlePointerEventAsTouch(const PointerEvent& event);
|
||||
void handlePointerEventAsMouse(const PointerEvent& event);
|
||||
|
||||
|
|
|
@ -571,7 +571,7 @@ QUuid EntityScriptingInterface::addModelEntity(const QString& name, const QStrin
|
|||
return addEntity(properties);
|
||||
}
|
||||
|
||||
QUuid EntityScriptingInterface::cloneEntity(QUuid entityIDToClone) {
|
||||
QUuid EntityScriptingInterface::cloneEntity(const QUuid& entityIDToClone) {
|
||||
EntityItemID newEntityID;
|
||||
EntityItemProperties properties = getEntityProperties(entityIDToClone);
|
||||
bool cloneAvatarEntity = properties.getCloneAvatarEntity();
|
||||
|
@ -596,12 +596,12 @@ QUuid EntityScriptingInterface::cloneEntity(QUuid entityIDToClone) {
|
|||
}
|
||||
}
|
||||
|
||||
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid entityID) {
|
||||
EntityItemProperties EntityScriptingInterface::getEntityProperties(const QUuid& entityID) {
|
||||
const EntityPropertyFlags noSpecificProperties;
|
||||
return getEntityProperties(entityID, noSpecificProperties);
|
||||
}
|
||||
|
||||
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid entityID, EntityPropertyFlags desiredProperties) {
|
||||
EntityItemProperties EntityScriptingInterface::getEntityProperties(const QUuid& entityID, EntityPropertyFlags desiredProperties) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
bool scalesWithParent { false };
|
||||
|
@ -775,7 +775,7 @@ QScriptValue EntityScriptingInterface::getMultipleEntityPropertiesInternal(QScri
|
|||
return finalResult;
|
||||
}
|
||||
|
||||
QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) {
|
||||
QUuid EntityScriptingInterface::editEntity(const QUuid& id, const EntityItemProperties& scriptSideProperties) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
_activityTracking.editedEntityCount++;
|
||||
|
@ -960,7 +960,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
|||
return id;
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::deleteEntity(QUuid id) {
|
||||
void EntityScriptingInterface::deleteEntity(const QUuid& id) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
_activityTracking.deletedEntityCount++;
|
||||
|
@ -1005,12 +1005,49 @@ void EntityScriptingInterface::deleteEntity(QUuid id) {
|
|||
}
|
||||
}
|
||||
|
||||
QString EntityScriptingInterface::getEntityType(const QUuid& entityID) {
|
||||
QString toReturn;
|
||||
_entityTree->withReadLock([&] {
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
|
||||
if (entity) {
|
||||
toReturn = EntityTypes::getEntityTypeName(entity->getType());
|
||||
}
|
||||
});
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
QObject* EntityScriptingInterface::getEntityObject(const QUuid& id) {
|
||||
QObject* toReturn { nullptr };
|
||||
_entityTree->withReadLock([&] {
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(id);
|
||||
if (entity) {
|
||||
toReturn = qobject_cast<QObject*>(&(*entity));
|
||||
}
|
||||
});
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::isLoaded(const QUuid& id) {
|
||||
bool toReturn = false;
|
||||
_entityTree->withReadLock([&] {
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(id);
|
||||
if (entity) {
|
||||
toReturn = entity->isVisuallyReady();
|
||||
}
|
||||
});
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
QSizeF EntityScriptingInterface::textSize(const QUuid& id, const QString& text) {
|
||||
return EntityTree::textSize(id, text);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::setEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock);
|
||||
_entitiesScriptEngine = engine;
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::callEntityMethod(QUuid id, const QString& method, const QStringList& params) {
|
||||
void EntityScriptingInterface::callEntityMethod(const QUuid& id, const QString& method, const QStringList& params) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock);
|
||||
|
@ -1020,12 +1057,12 @@ void EntityScriptingInterface::callEntityMethod(QUuid id, const QString& method,
|
|||
}
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::callEntityServerMethod(QUuid id, const QString& method, const QStringList& params) {
|
||||
void EntityScriptingInterface::callEntityServerMethod(const QUuid& id, const QString& method, const QStringList& params) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
DependencyManager::get<EntityScriptClient>()->callEntityServerMethod(id, method, params);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params) {
|
||||
void EntityScriptingInterface::callEntityClientMethod(const QUuid& clientSessionID, const QUuid& entityID, const QString& method, const QStringList& params) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
auto scriptServerServices = DependencyManager::get<EntityScriptServerServices>();
|
||||
|
||||
|
@ -1262,7 +1299,7 @@ ParabolaToEntityIntersectionResult EntityScriptingInterface::evalParabolaInterse
|
|||
return result;
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::reloadServerScripts(QUuid entityID) {
|
||||
bool EntityScriptingInterface::reloadServerScripts(const QUuid& entityID) {
|
||||
auto client = DependencyManager::get<EntityScriptClient>();
|
||||
return client->reloadServerScript(entityID);
|
||||
}
|
||||
|
@ -1335,7 +1372,7 @@ bool EntityPropertyMetadataRequest::serverScripts(EntityItemID entityID, QScript
|
|||
return true;
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::queryPropertyMetadata(QUuid entityID, QScriptValue property, QScriptValue scopeOrCallback, QScriptValue methodOrName) {
|
||||
bool EntityScriptingInterface::queryPropertyMetadata(const QUuid& entityID, QScriptValue property, QScriptValue scopeOrCallback, QScriptValue methodOrName) {
|
||||
auto name = property.toString();
|
||||
auto handler = makeScopedHandlerObject(scopeOrCallback, methodOrName);
|
||||
QPointer<BaseScriptEngine> engine = dynamic_cast<BaseScriptEngine*>(handler.engine());
|
||||
|
@ -1379,7 +1416,7 @@ bool EntityScriptingInterface::queryPropertyMetadata(QUuid entityID, QScriptValu
|
|||
}
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::getServerScriptStatus(QUuid entityID, QScriptValue callback) {
|
||||
bool EntityScriptingInterface::getServerScriptStatus(const QUuid& entityID, QScriptValue callback) {
|
||||
auto client = DependencyManager::get<EntityScriptClient>();
|
||||
auto request = client->createScriptStatusRequest(entityID);
|
||||
connect(request, &GetScriptStatusRequest::finished, callback.engine(), [callback](GetScriptStatusRequest* request) mutable {
|
||||
|
@ -1518,14 +1555,14 @@ bool EntityScriptingInterface::setPoints(QUuid entityID, std::function<bool(Line
|
|||
return success;
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value) {
|
||||
bool EntityScriptingInterface::setVoxelSphere(const QUuid& entityID, const glm::vec3& center, float radius, int value) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
return polyVoxWorker(entityID, [center, radius, value](PolyVoxEntityItem& polyVoxEntity) {
|
||||
return polyVoxEntity.setSphere(center, radius, value);
|
||||
});
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::setVoxelCapsule(QUuid entityID,
|
||||
bool EntityScriptingInterface::setVoxelCapsule(const QUuid& entityID,
|
||||
const glm::vec3& start, const glm::vec3& end,
|
||||
float radius, int value) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
@ -1535,7 +1572,7 @@ bool EntityScriptingInterface::setVoxelCapsule(QUuid entityID,
|
|||
});
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::setVoxel(QUuid entityID, const glm::vec3& position, int value) {
|
||||
bool EntityScriptingInterface::setVoxel(const QUuid& entityID, const glm::vec3& position, int value) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
return polyVoxWorker(entityID, [position, value](PolyVoxEntityItem& polyVoxEntity) {
|
||||
|
@ -1543,7 +1580,7 @@ bool EntityScriptingInterface::setVoxel(QUuid entityID, const glm::vec3& positio
|
|||
});
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) {
|
||||
bool EntityScriptingInterface::setAllVoxels(const QUuid& entityID, int value) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
return polyVoxWorker(entityID, [value](PolyVoxEntityItem& polyVoxEntity) {
|
||||
|
@ -1551,7 +1588,7 @@ bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) {
|
|||
});
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::setVoxelsInCuboid(QUuid entityID, const glm::vec3& lowPosition,
|
||||
bool EntityScriptingInterface::setVoxelsInCuboid(const QUuid& entityID, const glm::vec3& lowPosition,
|
||||
const glm::vec3& cuboidSize, int value) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
|
@ -1560,7 +1597,7 @@ bool EntityScriptingInterface::setVoxelsInCuboid(QUuid entityID, const glm::vec3
|
|||
});
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::setAllPoints(QUuid entityID, const QVector<glm::vec3>& points) {
|
||||
bool EntityScriptingInterface::setAllPoints(const QUuid& entityID, const QVector<glm::vec3>& points) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
||||
|
@ -1580,7 +1617,7 @@ bool EntityScriptingInterface::setAllPoints(QUuid entityID, const QVector<glm::v
|
|||
return false;
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::appendPoint(QUuid entityID, const glm::vec3& point) {
|
||||
bool EntityScriptingInterface::appendPoint(const QUuid& entityID, const glm::vec3& point) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
||||
|
@ -2040,7 +2077,7 @@ QVector<QUuid> EntityScriptingInterface::getChildrenIDs(const QUuid& parentID) {
|
|||
return result;
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::isChildOfParent(QUuid childID, QUuid parentID) {
|
||||
bool EntityScriptingInterface::isChildOfParent(const QUuid& childID, const QUuid& parentID) {
|
||||
bool isChild = false;
|
||||
|
||||
if (!_entityTree) {
|
||||
|
@ -2062,7 +2099,7 @@ bool EntityScriptingInterface::isChildOfParent(QUuid childID, QUuid parentID) {
|
|||
return isChild;
|
||||
}
|
||||
|
||||
QString EntityScriptingInterface::getNestableType(QUuid id) {
|
||||
QString EntityScriptingInterface::getNestableType(const QUuid& id) {
|
||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||
if (!parentFinder) {
|
||||
return "unknown";
|
||||
|
@ -2164,7 +2201,7 @@ void EntityScriptingInterface::sendHoverLeaveEntity(const EntityItemID& id, cons
|
|||
emit hoverLeaveEntity(id, event);
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::wantsHandControllerPointerEvents(QUuid id) {
|
||||
bool EntityScriptingInterface::wantsHandControllerPointerEvents(const QUuid& id) {
|
||||
bool result = false;
|
||||
if (_entityTree) {
|
||||
_entityTree->withReadLock([&] {
|
||||
|
@ -2196,7 +2233,7 @@ bool EntityScriptingInterface::AABoxIntersectsCapsule(const glm::vec3& low, cons
|
|||
return aaBox.findCapsulePenetration(start, end, radius, penetration);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::getMeshes(QUuid entityID, QScriptValue callback) {
|
||||
void EntityScriptingInterface::getMeshes(const QUuid& entityID, QScriptValue callback) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
||||
|
|
|
@ -296,7 +296,7 @@ public slots:
|
|||
* @param {Uuid} entityID - The ID of the entity to clone.
|
||||
* @returns {Uuid} The ID of the new entity if successfully cloned, otherwise {@link Uuid|Uuid.NULL}.
|
||||
*/
|
||||
Q_INVOKABLE QUuid cloneEntity(QUuid entityIDToClone);
|
||||
Q_INVOKABLE QUuid cloneEntity(const QUuid& entityID);
|
||||
|
||||
/**jsdoc
|
||||
* Get the properties of an entity.
|
||||
|
@ -315,8 +315,8 @@ public slots:
|
|||
* var properties = Entities.getEntityProperties(entityID, ["color"]);
|
||||
* print("Entity color: " + JSON.stringify(properties.color));
|
||||
*/
|
||||
Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid entityID);
|
||||
Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid entityID, EntityPropertyFlags desiredProperties);
|
||||
Q_INVOKABLE EntityItemProperties getEntityProperties(const QUuid& entityID);
|
||||
Q_INVOKABLE EntityItemProperties getEntityProperties(const QUuid& entityID, EntityPropertyFlags desiredProperties);
|
||||
|
||||
/**jsdoc
|
||||
* Update an entity with specified properties.
|
||||
|
@ -340,7 +340,7 @@ public slots:
|
|||
* properties = Entities.getEntityProperties(entityID, ["color"]);
|
||||
* print("Entity color: " + JSON.stringify(properties.color));
|
||||
*/
|
||||
Q_INVOKABLE QUuid editEntity(QUuid entityID, const EntityItemProperties& properties);
|
||||
Q_INVOKABLE QUuid editEntity(const QUuid& entityID, const EntityItemProperties& properties);
|
||||
|
||||
/**jsdoc
|
||||
* Delete an entity.
|
||||
|
@ -358,8 +358,50 @@ public slots:
|
|||
* Entities.deleteEntity(entityID);
|
||||
* }, 3000);
|
||||
*/
|
||||
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
||||
Q_INVOKABLE void deleteEntity(const QUuid& entityID);
|
||||
|
||||
/**jsdoc
|
||||
* Get an entities type as a string.
|
||||
* @function Entities.deleteEntity
|
||||
* @param {Uuid} id - The id of the entity to get the type of.
|
||||
*/
|
||||
Q_INVOKABLE QString getEntityType(const QUuid& entityID);
|
||||
|
||||
/**jsdoc
|
||||
* Get the entity script object. In particular, this is useful for accessing the event bridge for a <code>Web</code>
|
||||
* entity.
|
||||
* @function Entities.getEntityObject
|
||||
* @param {Uuid} id - The ID of the entity to get the script object of.
|
||||
* @returns {object} The script object for the entity if found.
|
||||
*/
|
||||
Q_INVOKABLE QObject* getEntityObject(const QUuid& id);
|
||||
|
||||
/**jsdoc
|
||||
* Check whether an entities's assets have been loaded. For example, for an <code>Model</code> entity the result indicates
|
||||
* whether its textures have been loaded.
|
||||
* @function Entities.isLoaded
|
||||
* @param {Uuid} id - The ID of the entity to check.
|
||||
* @returns {boolean} <code>true</code> if the entity's assets have been loaded, otherwise <code>false</code>.
|
||||
*/
|
||||
Q_INVOKABLE bool isLoaded(const QUuid& id);
|
||||
|
||||
/**jsdoc
|
||||
* Check if there is an object of a given ID.
|
||||
* @function Entities.isAddedEntity
|
||||
* @param {Uuid} id - The ID to check.
|
||||
* @returns {boolean} <code>true</code> if an object with the given ID exists, <code>false</code> otherwise.
|
||||
*/
|
||||
Q_INVOKABLE bool isAddedEntity(const QUuid& id);
|
||||
|
||||
/**jsdoc
|
||||
* Calculates the size of the given text in the specified object if it is a text entity.
|
||||
* @function Entities.textSize
|
||||
* @param {Uuid} id - The ID of the entity to use for calculation.
|
||||
* @param {string} text - The string to calculate the size of.
|
||||
* @returns {Size} The size of the <code>text</code> in meters if the object is a text entity, otherwise
|
||||
* <code>{ height: 0, width : 0 }</code>.
|
||||
*/
|
||||
Q_INVOKABLE QSizeF textSize(const QUuid& id, const QString& text);
|
||||
|
||||
/**jsdoc
|
||||
* Call a method in a client entity script from a client script or client entity script, or call a method in a server
|
||||
|
@ -371,7 +413,7 @@ public slots:
|
|||
* @param {string} method - The name of the method to call.
|
||||
* @param {string[]} [parameters=[]] - The parameters to call the specified method with.
|
||||
*/
|
||||
Q_INVOKABLE void callEntityMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
||||
Q_INVOKABLE void callEntityMethod(const QUuid& entityID, const QString& method, const QStringList& params = QStringList());
|
||||
|
||||
/**jsdoc
|
||||
* Call a method in a server entity script from a client script or client entity script. The entity script method must be
|
||||
|
@ -383,7 +425,7 @@ public slots:
|
|||
* @param {string} method - The name of the method to call.
|
||||
* @param {string[]} [parameters=[]] - The parameters to call the specified method with.
|
||||
*/
|
||||
Q_INVOKABLE void callEntityServerMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
||||
Q_INVOKABLE void callEntityServerMethod(const QUuid& entityID, const QString& method, const QStringList& params = QStringList());
|
||||
|
||||
/**jsdoc
|
||||
* Call a method in a specific user's client entity script from a server entity script. The entity script method must be
|
||||
|
@ -394,7 +436,7 @@ public slots:
|
|||
* @param {string} method - The name of the method to call.
|
||||
* @param {string[]} [parameters=[]] - The parameters to call the specified method with.
|
||||
*/
|
||||
Q_INVOKABLE void callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method,
|
||||
Q_INVOKABLE void callEntityClientMethod(const QUuid& clientSessionID, const QUuid& entityID, const QString& method,
|
||||
const QStringList& params = QStringList());
|
||||
|
||||
/**jsdoc
|
||||
|
@ -524,7 +566,7 @@ public slots:
|
|||
* @returns {boolean} <code>true</code> if the reload request was successfully sent to the server, otherwise
|
||||
* <code>false</code>.
|
||||
*/
|
||||
Q_INVOKABLE bool reloadServerScripts(QUuid entityID);
|
||||
Q_INVOKABLE bool reloadServerScripts(const QUuid& entityID);
|
||||
|
||||
/**jsdoc
|
||||
* Gets the status of server entity script attached to an entity
|
||||
|
@ -543,7 +585,7 @@ public slots:
|
|||
* @param {string} errorInfo - <code>""</code> if there is a server entity script running, otherwise it may contain extra
|
||||
* information on the error.
|
||||
*/
|
||||
Q_INVOKABLE bool getServerScriptStatus(QUuid entityID, QScriptValue callback);
|
||||
Q_INVOKABLE bool getServerScriptStatus(const QUuid& entityID, QScriptValue callback);
|
||||
|
||||
/**jsdoc
|
||||
* Get metadata for certain entity properties such as <code>script</code> and <code>serverScripts</code>.
|
||||
|
@ -573,7 +615,7 @@ public slots:
|
|||
* @param {object} result - The metadata for the requested entity property if there was no error, otherwise
|
||||
* <code>undefined</code>.
|
||||
*/
|
||||
Q_INVOKABLE bool queryPropertyMetadata(QUuid entityID, QScriptValue property, QScriptValue scopeOrCallback,
|
||||
Q_INVOKABLE bool queryPropertyMetadata(const QUuid& entityID, QScriptValue property, QScriptValue scopeOrCallback,
|
||||
QScriptValue methodOrName = QScriptValue());
|
||||
|
||||
|
||||
|
@ -657,7 +699,7 @@ public slots:
|
|||
* Entities.setVoxelSphere(polyVox, position, 0.9, 255);
|
||||
*/
|
||||
// FIXME move to a renderable entity interface
|
||||
Q_INVOKABLE bool setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value);
|
||||
Q_INVOKABLE bool setVoxelSphere(const QUuid& entityID, const glm::vec3& center, float radius, int value);
|
||||
|
||||
/**jsdoc
|
||||
* Set the values of all voxels in a capsule-shaped portion of a {@link Entities.EntityType|PolyVox} entity.
|
||||
|
@ -681,7 +723,7 @@ public slots:
|
|||
* Entities.setVoxelCapsule(polyVox, startPosition, endPosition, 0.5, 255);
|
||||
*/
|
||||
// FIXME move to a renderable entity interface
|
||||
Q_INVOKABLE bool setVoxelCapsule(QUuid entityID, const glm::vec3& start, const glm::vec3& end, float radius, int value);
|
||||
Q_INVOKABLE bool setVoxelCapsule(const QUuid& entityID, const glm::vec3& start, const glm::vec3& end, float radius, int value);
|
||||
|
||||
/**jsdoc
|
||||
* Set the value of a particular voxels in a {@link Entities.EntityType|PolyVox} entity.
|
||||
|
@ -703,7 +745,7 @@ public slots:
|
|||
* Entities.setVoxel(entity, { x: 0, y: 0, z: 0 }, 0);
|
||||
*/
|
||||
// FIXME move to a renderable entity interface
|
||||
Q_INVOKABLE bool setVoxel(QUuid entityID, const glm::vec3& position, int value);
|
||||
Q_INVOKABLE bool setVoxel(const QUuid& entityID, const glm::vec3& position, int value);
|
||||
|
||||
/**jsdoc
|
||||
* Set the values of all voxels in a {@link Entities.EntityType|PolyVox} entity.
|
||||
|
@ -721,7 +763,7 @@ public slots:
|
|||
* Entities.setAllVoxels(entity, 1);
|
||||
*/
|
||||
// FIXME move to a renderable entity interface
|
||||
Q_INVOKABLE bool setAllVoxels(QUuid entityID, int value);
|
||||
Q_INVOKABLE bool setAllVoxels(const QUuid& entityID, int value);
|
||||
|
||||
/**jsdoc
|
||||
* Set the values of all voxels in a cubic portion of a {@link Entities.EntityType|PolyVox} entity.
|
||||
|
@ -746,7 +788,7 @@ public slots:
|
|||
* Entities.setVoxelsInCuboid(polyVox, cuboidPosition, cuboidSize, 0);
|
||||
*/
|
||||
// FIXME move to a renderable entity interface
|
||||
Q_INVOKABLE bool setVoxelsInCuboid(QUuid entityID, const glm::vec3& lowPosition, const glm::vec3& cuboidSize, int value);
|
||||
Q_INVOKABLE bool setVoxelsInCuboid(const QUuid& entityID, const glm::vec3& lowPosition, const glm::vec3& cuboidSize, int value);
|
||||
|
||||
/**jsdoc
|
||||
* Convert voxel coordinates in a {@link Entities.EntityType|PolyVox} entity to world coordinates. Voxel coordinates are
|
||||
|
@ -862,7 +904,7 @@ public slots:
|
|||
* ]);
|
||||
* }, 2000);
|
||||
*/
|
||||
Q_INVOKABLE bool setAllPoints(QUuid entityID, const QVector<glm::vec3>& points);
|
||||
Q_INVOKABLE bool setAllPoints(const QUuid& entityID, const QVector<glm::vec3>& points);
|
||||
|
||||
/**jsdoc
|
||||
* Append a point to a {@link Entities.EntityType|Line} entity.
|
||||
|
@ -890,7 +932,7 @@ public slots:
|
|||
* // Add a third point to create a "V".
|
||||
* Entities.appendPoint(entity, { x: 1, y: 1, z: 0 });
|
||||
*/
|
||||
Q_INVOKABLE bool appendPoint(QUuid entityID, const glm::vec3& point);
|
||||
Q_INVOKABLE bool appendPoint(const QUuid& entityID, const glm::vec3& point);
|
||||
|
||||
/**jsdoc
|
||||
* Dumps debug information about all entities in Interface's local in-memory tree of entities it knows about to the program log.
|
||||
|
@ -1355,7 +1397,7 @@ public slots:
|
|||
*
|
||||
* print("grandChild has root as parent: " + Entities.isChildOfParent(grandChild, root)); // true
|
||||
*/
|
||||
Q_INVOKABLE bool isChildOfParent(QUuid childID, QUuid parentID);
|
||||
Q_INVOKABLE bool isChildOfParent(const QUuid& childID, const QUuid& parentID);
|
||||
|
||||
/**jsdoc
|
||||
* Get the type — entity, overlay, or avatar — of an in-world item.
|
||||
|
@ -1374,7 +1416,7 @@ public slots:
|
|||
* print(Entities.getNestableType(entity)); // "entity"
|
||||
* print(Entities.getNestableType(Uuid.generate())); // "unknown"
|
||||
*/
|
||||
Q_INVOKABLE QString getNestableType(QUuid entityID);
|
||||
Q_INVOKABLE QString getNestableType(const QUuid& entityID);
|
||||
|
||||
/**jsdoc
|
||||
* Get the ID of the {@link Entities.EntityType|Web} entity that has keyboard focus.
|
||||
|
@ -1486,7 +1528,7 @@ public slots:
|
|||
* @returns {boolean} <code>true</code> if the entity can be found and it wants hand controller pointer events, otherwise
|
||||
* <code>false</code>.
|
||||
*/
|
||||
Q_INVOKABLE bool wantsHandControllerPointerEvents(QUuid id);
|
||||
Q_INVOKABLE bool wantsHandControllerPointerEvents(const QUuid& id);
|
||||
|
||||
/**jsdoc
|
||||
* Send a script event over a {@link Entities.EntityType|Web} entity's <code>EventBridge</code> to the Web page's scripts.
|
||||
|
@ -1527,7 +1569,7 @@ public slots:
|
|||
* @deprecated Use the {@link Graphics} API instead.
|
||||
*/
|
||||
// FIXME move to a renderable entity interface
|
||||
Q_INVOKABLE void getMeshes(QUuid entityID, QScriptValue callback);
|
||||
Q_INVOKABLE void getMeshes(const QUuid& entityID, QScriptValue callback);
|
||||
|
||||
/**jsdoc
|
||||
* Get the object to world transform, excluding scale, of an entity.
|
||||
|
|
|
@ -2957,8 +2957,7 @@ std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> E
|
|||
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> EntityTree::_removeMaterialFromEntityOperator = nullptr;
|
||||
std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> EntityTree::_addMaterialToAvatarOperator = nullptr;
|
||||
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> EntityTree::_removeMaterialFromAvatarOperator = nullptr;
|
||||
std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> EntityTree::_addMaterialToOverlayOperator = nullptr;
|
||||
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> EntityTree::_removeMaterialFromOverlayOperator = nullptr;
|
||||
std::function<QSizeF(const QUuid&, const QString&)> EntityTree::_textSizeOperator = nullptr;
|
||||
|
||||
bool EntityTree::addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||
if (_addMaterialToEntityOperator) {
|
||||
|
@ -2988,18 +2987,11 @@ bool EntityTree::removeMaterialFromAvatar(const QUuid& avatarID, graphics::Mater
|
|||
return false;
|
||||
}
|
||||
|
||||
bool EntityTree::addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||
if (_addMaterialToOverlayOperator) {
|
||||
return _addMaterialToOverlayOperator(overlayID, material, parentMaterialName);
|
||||
QSizeF EntityTree::textSize(const QUuid& id, const QString& text) {
|
||||
if (_textSizeOperator) {
|
||||
return _textSizeOperator(id, text);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EntityTree::removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
||||
if (_removeMaterialFromOverlayOperator) {
|
||||
return _removeMaterialFromOverlayOperator(overlayID, material, parentMaterialName);
|
||||
}
|
||||
return false;
|
||||
return QSizeF(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void EntityTree::updateEntityQueryAACubeWorker(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender,
|
||||
|
|
|
@ -272,10 +272,8 @@ public:
|
|||
static bool addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName);
|
||||
static bool removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName);
|
||||
|
||||
static void setAddMaterialToOverlayOperator(std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> addMaterialToOverlayOperator) { _addMaterialToOverlayOperator = addMaterialToOverlayOperator; }
|
||||
static void setRemoveMaterialFromOverlayOperator(std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> removeMaterialFromOverlayOperator) { _removeMaterialFromOverlayOperator = removeMaterialFromOverlayOperator; }
|
||||
static bool addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName);
|
||||
static bool removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName);
|
||||
static void setTextSizeOperator(std::function<QSizeF(const QUuid&, const QString&)> textSizeOperator) { _textSizeOperator = textSizeOperator; }
|
||||
static QSizeF textSize(const QUuid& id, const QString& text);
|
||||
|
||||
std::map<QString, QString> getNamedPaths() const { return _namedPaths; }
|
||||
|
||||
|
@ -389,8 +387,7 @@ private:
|
|||
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromEntityOperator;
|
||||
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToAvatarOperator;
|
||||
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromAvatarOperator;
|
||||
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToOverlayOperator;
|
||||
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromOverlayOperator;
|
||||
static std::function<QSizeF(const QUuid&, const QString&)> _textSizeOperator;
|
||||
|
||||
std::vector<int32_t> _staleProxies;
|
||||
|
||||
|
|
Loading…
Reference in a new issue