From a6ad53e79e74c5cfeb79264431555c0b2ab9198e Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Fri, 22 Feb 2019 11:30:26 -0800 Subject: [PATCH 01/20] TEST --- tools/CMakeLists.txt | 2 +- tools/nitpick/CMakeLists.txt | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 6cda67db2d..ed66ab1ed1 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -20,7 +20,7 @@ endfunction() if (BUILD_TOOLS) # Allow different tools for stable builds - if (RELEASE_TYPE STREQUAL "PRODUCTION") + if (NOT STABLE_BUILD) set(ALL_TOOLS udt-test vhacd-util diff --git a/tools/nitpick/CMakeLists.txt b/tools/nitpick/CMakeLists.txt index e69b16b866..44eace5e70 100644 --- a/tools/nitpick/CMakeLists.txt +++ b/tools/nitpick/CMakeLists.txt @@ -80,7 +80,9 @@ else () add_executable(${TARGET_NAME} ${NITPICK_SRCS} ${QM}) endif () -add_dependencies(${TARGET_NAME} resources) +if (NOT UNIX) + add_dependencies(${TARGET_NAME} resources) +endif() # disable /OPT:REF and /OPT:ICF for the Debug builds # This will prevent the following linker warnings From 7cf79c11081209537e74ee123daa42bee963804c Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Fri, 22 Feb 2019 15:06:42 -0800 Subject: [PATCH 02/20] Now WITH installation of nitpick. --- tools/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index ed66ab1ed1..b9ae635a4f 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -20,7 +20,7 @@ endfunction() if (BUILD_TOOLS) # Allow different tools for stable builds - if (NOT STABLE_BUILD) + if (STABLE_BUILD) set(ALL_TOOLS udt-test vhacd-util From d27d624c3f652011dea0ba4459680154846426e3 Mon Sep 17 00:00:00 2001 From: Clement Date: Fri, 22 Feb 2019 18:05:42 -0800 Subject: [PATCH 03/20] Don't send a KillAvatar packet on kick The DS already takes cares of removing nodes no longer allowed when the permissions are updated and KillAvatar was never meant to be used from the DS. --- domain-server/src/DomainServerSettingsManager.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index 780fad15f2..4e833f6b77 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -25,13 +25,13 @@ #include #include +#include #include #include #include #include #include #include -#include //for KillAvatarReason #include #include "DomainServerNodeData.h" @@ -870,14 +870,6 @@ void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointerwrite(nodeUUID.toRfc4122()); - packet->writePrimitive(KillAvatarReason::NoReason); - - // send to avatar mixer, it sends the kill to everyone else - limitedNodeList->broadcastToNodes(std::move(packet), NodeSet() << NodeType::AvatarMixer); - if (newPermissions) { qDebug() << "Removing connect permission for node" << uuidStringWithoutCurlyBraces(matchingNode->getUUID()) << "after kick request from" << uuidStringWithoutCurlyBraces(sendingNode->getUUID()); From 6e13203fecc0e94853fd76fcdcf6e2a72a7329d5 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 25 Feb 2019 13:52:46 -0800 Subject: [PATCH 04/20] avoid nullptr deref --- interface/src/avatar/AvatarProject.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/AvatarProject.cpp b/interface/src/avatar/AvatarProject.cpp index b020cdb627..260ff33db7 100644 --- a/interface/src/avatar/AvatarProject.cpp +++ b/interface/src/avatar/AvatarProject.cpp @@ -254,11 +254,15 @@ void AvatarProject::openInInventory() const { DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system")); tablet->loadQMLSource("hifi/commerce/wallet/Wallet.qml"); DependencyManager::get()->openTablet(); - tablet->getTabletRoot()->forceActiveFocus(); - auto name = getProjectName(); // I'm not a fan of this, but it's the only current option. + auto name = getProjectName(); QTimer::singleShot(TIME_TO_WAIT_FOR_INVENTORY_TO_OPEN_MS, [name, tablet]() { tablet->sendToQml(QVariantMap({ { "method", "updatePurchases" }, { "filterText", name } })); }); + + QQuickItem* root = tablet->getTabletRoot(); + if (root) { + root->forceActiveFocus(); + } } From a8e6d0127913487fb56322a665f653b37a3ff248 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 28 Feb 2019 11:33:09 -0800 Subject: [PATCH 05/20] fix context overlay --- .../ui/overlays/ContextOverlayInterface.cpp | 20 +++++++++---------- .../src/ui/overlays/ContextOverlayInterface.h | 1 - 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 24c0986d09..e5cec70f64 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -50,11 +50,14 @@ ContextOverlayInterface::ContextOverlayInterface() { _entityPropertyFlags += PROP_OWNING_AVATAR_ID; auto entityScriptingInterface = DependencyManager::get().data(); - connect(entityScriptingInterface, &EntityScriptingInterface::clickDownOnEntity, this, &ContextOverlayInterface::clickDownOnEntity); - connect(entityScriptingInterface, &EntityScriptingInterface::holdingClickOnEntity, this, &ContextOverlayInterface::holdingClickOnEntity); + connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, &ContextOverlayInterface::clickDownOnEntity); connect(entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity, this, &ContextOverlayInterface::mouseReleaseOnEntity); connect(entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity, this, &ContextOverlayInterface::contextOverlays_hoverEnterEntity); connect(entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity, this, &ContextOverlayInterface::contextOverlays_hoverLeaveEntity); + + connect(&qApp->getOverlays(), &Overlays::hoverEnterOverlay, this, &ContextOverlayInterface::contextOverlays_hoverEnterOverlay); + connect(&qApp->getOverlays(), &Overlays::hoverLeaveOverlay, this, &ContextOverlayInterface::contextOverlays_hoverLeaveOverlay); + connect(_tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"), &TabletProxy::tabletShownChanged, this, [&]() { if (_contextOverlayJustClicked && _hmdScriptingInterface->isMounted()) { QUuid tabletFrameID = _hmdScriptingInterface->getCurrentTabletFrameID(); @@ -70,8 +73,6 @@ ContextOverlayInterface::ContextOverlayInterface() { } }); connect(entityScriptingInterface, &EntityScriptingInterface::deletingEntity, this, &ContextOverlayInterface::deletingEntity); - connect(&qApp->getOverlays(), &Overlays::hoverEnterOverlay, this, &ContextOverlayInterface::contextOverlays_hoverEnterOverlay); - connect(&qApp->getOverlays(), &Overlays::hoverLeaveOverlay, this, &ContextOverlayInterface::contextOverlays_hoverLeaveOverlay); { _selectionScriptingInterface->enableListHighlight("contextOverlayHighlightList", QVariantMap()); @@ -106,7 +107,7 @@ void ContextOverlayInterface::clickDownOnEntity(const EntityItemID& id, const Po if (_enabled && event.getButton() == PointerEvent::SecondaryButton && contextOverlayFilterPassed(id)) { _mouseDownEntity = id; _mouseDownEntityTimestamp = usecTimestampNow(); - } else if (id == _contextOverlayID && event.getButton() == PointerEvent::PrimaryButton) { + } else if ((event.shouldFocus() || event.getButton() == PointerEvent::PrimaryButton) && id == _contextOverlayID) { qCDebug(context_overlay) << "Clicked Context Overlay. Entity ID:" << _currentEntityWithContextOverlay << "ID:" << id; emit contextOverlayClicked(_currentEntityWithContextOverlay); _contextOverlayJustClicked = true; @@ -119,13 +120,10 @@ void ContextOverlayInterface::clickDownOnEntity(const EntityItemID& id, const Po } static const float CONTEXT_OVERLAY_CLICK_HOLD_TIME_MSEC = 400.0f; -void ContextOverlayInterface::holdingClickOnEntity(const EntityItemID& entityItemID, const PointerEvent& event) { +void ContextOverlayInterface::mouseReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event) { if (!_mouseDownEntity.isNull() && ((usecTimestampNow() - _mouseDownEntityTimestamp) > (CONTEXT_OVERLAY_CLICK_HOLD_TIME_MSEC * USECS_PER_MSEC))) { _mouseDownEntity = EntityItemID(); } -} - -void ContextOverlayInterface::mouseReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event) { if (_enabled && event.getButton() == PointerEvent::SecondaryButton && contextOverlayFilterPassed(entityItemID) && _mouseDownEntity == entityItemID) { createOrDestroyContextOverlay(entityItemID, event); } @@ -253,7 +251,7 @@ bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityIt } void ContextOverlayInterface::contextOverlays_hoverEnterOverlay(const QUuid& id, const PointerEvent& event) { - if (_contextOverlayID != UNKNOWN_ENTITY_ID) { + if (_contextOverlayID == id) { qCDebug(context_overlay) << "Started hovering over Context Overlay. ID:" << id; EntityItemProperties properties; properties.setColor(CONTEXT_OVERLAY_COLOR); @@ -265,7 +263,7 @@ void ContextOverlayInterface::contextOverlays_hoverEnterOverlay(const QUuid& id, } void ContextOverlayInterface::contextOverlays_hoverLeaveOverlay(const QUuid& id, const PointerEvent& event) { - if (_contextOverlayID != UNKNOWN_ENTITY_ID) { + if (_contextOverlayID == id) { qCDebug(context_overlay) << "Stopped hovering over Context Overlay. ID:" << id; EntityItemProperties properties; properties.setColor(CONTEXT_OVERLAY_COLOR); diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index 57fc8ebe6e..b1b62aa0c4 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -59,7 +59,6 @@ signals: public slots: void clickDownOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void holdingClickOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); void mouseReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); bool createOrDestroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event); From f715dbe243ce4ea094b455c327331888aa8eb073 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Thu, 28 Feb 2019 11:53:20 -0800 Subject: [PATCH 06/20] fix tablet scaling --- .../src/RenderableWebEntityItem.cpp | 3 +- libraries/entities/src/EntityItem.cpp | 42 +++++------ libraries/entities/src/EntityItem.h | 2 +- .../entities/src/EntityItemProperties.cpp | 46 ++++++------ libraries/entities/src/EntityItemProperties.h | 4 +- libraries/entities/src/EntityPropertyFlags.h | 4 +- libraries/entities/src/ModelEntityItem.cpp | 35 +++++++-- libraries/entities/src/ModelEntityItem.h | 8 +- libraries/networking/src/udt/PacketHeaders.h | 1 + .../nearParentGrabOverlay.js | 7 +- scripts/system/libraries/WebTablet.js | 2 +- scripts/system/libraries/utils.js | 74 +++++++++++++++++-- 12 files changed, 164 insertions(+), 64 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 0f2c708d17..3b615ba467 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -266,6 +266,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene _webSurface->resize(QSize(windowSize.x, windowSize.y)); updateModelTransformAndBound(); _renderTransform = getModelTransform(); + _renderTransform.setScale(1.0f); _renderTransform.postScale(entity->getScaledDimensions()); }); }); @@ -487,4 +488,4 @@ QObject* WebEntityRenderer::getEventHandler() { void WebEntityRenderer::emitScriptEvent(const QVariant& message) { emit scriptEventReceived(message); -} \ No newline at end of file +} diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 5dc218bc3b..5da1c05aa2 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -79,6 +79,8 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param // Core requestedProperties += PROP_SIMULATION_OWNER; + requestedProperties += PROP_PARENT_ID; + requestedProperties += PROP_PARENT_JOINT_INDEX; requestedProperties += PROP_VISIBLE; requestedProperties += PROP_NAME; requestedProperties += PROP_LOCKED; @@ -93,8 +95,6 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param requestedProperties += PROP_LAST_EDITED_BY; requestedProperties += PROP_ENTITY_HOST_TYPE; requestedProperties += PROP_OWNING_AVATAR_ID; - requestedProperties += PROP_PARENT_ID; - requestedProperties += PROP_PARENT_JOINT_INDEX; requestedProperties += PROP_QUERY_AA_CUBE; requestedProperties += PROP_CAN_CAST_SHADOW; requestedProperties += PROP_VISIBLE_IN_SECONDARY_CAMERA; @@ -260,6 +260,14 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet // PROP_CUSTOM_PROPERTIES_INCLUDED, APPEND_ENTITY_PROPERTY(PROP_SIMULATION_OWNER, _simulationOwner.toByteArray()); + // convert AVATAR_SELF_ID to actual sessionUUID. + QUuid actualParentID = getParentID(); + if (actualParentID == AVATAR_SELF_ID) { + auto nodeList = DependencyManager::get(); + actualParentID = nodeList->getSessionUUID(); + } + APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, actualParentID); + APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, getParentJointIndex()); APPEND_ENTITY_PROPERTY(PROP_VISIBLE, getVisible()); APPEND_ENTITY_PROPERTY(PROP_NAME, getName()); APPEND_ENTITY_PROPERTY(PROP_LOCKED, getLocked()); @@ -274,14 +282,6 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet APPEND_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, getLastEditedBy()); // APPEND_ENTITY_PROPERTY(PROP_ENTITY_HOST_TYPE, (uint32_t)getEntityHostType()); // not sent over the wire // APPEND_ENTITY_PROPERTY(PROP_OWNING_AVATAR_ID, getOwningAvatarID()); // not sent over the wire - // convert AVATAR_SELF_ID to actual sessionUUID. - QUuid actualParentID = getParentID(); - if (actualParentID == AVATAR_SELF_ID) { - auto nodeList = DependencyManager::get(); - actualParentID = nodeList->getSessionUUID(); - } - APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, actualParentID); - APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, getParentJointIndex()); APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, getQueryAACube()); APPEND_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, getCanCastShadow()); // APPEND_ENTITY_PROPERTY(PROP_VISIBLE_IN_SECONDARY_CAMERA, getIsVisibleInSecondaryCamera()); // not sent over the wire @@ -792,6 +792,13 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef // Core // PROP_SIMULATION_OWNER handled above + { // parentID and parentJointIndex are protected by simulation ownership + bool oldOverwrite = overwriteLocalData; + overwriteLocalData = overwriteLocalData && !weOwnSimulation; + READ_ENTITY_PROPERTY(PROP_PARENT_ID, QUuid, setParentID); + READ_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex); + overwriteLocalData = oldOverwrite; + } READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, setVisible); READ_ENTITY_PROPERTY(PROP_NAME, QString, setName); READ_ENTITY_PROPERTY(PROP_LOCKED, bool, setLocked); @@ -835,13 +842,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, QUuid, setLastEditedBy); // READ_ENTITY_PROPERTY(PROP_ENTITY_HOST_TYPE, entity::HostType, setEntityHostType); // not sent over the wire // READ_ENTITY_PROPERTY(PROP_OWNING_AVATAR_ID, QUuuid, setOwningAvatarID); // not sent over the wire - { // parentID and parentJointIndex are protected by simulation ownership - bool oldOverwrite = overwriteLocalData; - overwriteLocalData = overwriteLocalData && !weOwnSimulation; - READ_ENTITY_PROPERTY(PROP_PARENT_ID, QUuid, setParentID); - READ_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex); - overwriteLocalData = oldOverwrite; - } { // See comment above auto customUpdateQueryAACubeFromNetwork = [this, shouldUpdate, lastEdited](AACube value) { if (shouldUpdate(_lastUpdatedQueryAACubeTimestamp, value != _lastUpdatedQueryAACubeValue)) { @@ -1309,6 +1309,8 @@ EntityItemProperties EntityItem::getProperties(const EntityPropertyFlags& desire // Core COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulationOwner, getSimulationOwner); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentID, getParentID); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentJointIndex, getParentJointIndex); COPY_ENTITY_PROPERTY_TO_PROPERTIES(visible, getVisible); COPY_ENTITY_PROPERTY_TO_PROPERTIES(name, getName); COPY_ENTITY_PROPERTY_TO_PROPERTIES(locked, getLocked); @@ -1323,8 +1325,6 @@ EntityItemProperties EntityItem::getProperties(const EntityPropertyFlags& desire COPY_ENTITY_PROPERTY_TO_PROPERTIES(lastEditedBy, getLastEditedBy); COPY_ENTITY_PROPERTY_TO_PROPERTIES(entityHostType, getEntityHostType); COPY_ENTITY_PROPERTY_TO_PROPERTIES(owningAvatarID, getOwningAvatarID); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentID, getParentID); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentJointIndex, getParentJointIndex); COPY_ENTITY_PROPERTY_TO_PROPERTIES(queryAACube, getQueryAACube); COPY_ENTITY_PROPERTY_TO_PROPERTIES(canCastShadow, getCanCastShadow); COPY_ENTITY_PROPERTY_TO_PROPERTIES(isVisibleInSecondaryCamera, isVisibleInSecondaryCamera); @@ -1456,6 +1456,8 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { // Core SET_ENTITY_PROPERTY_FROM_PROPERTIES(simulationOwner, setSimulationOwner); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentID, setParentID); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentJointIndex, setParentJointIndex); SET_ENTITY_PROPERTY_FROM_PROPERTIES(visible, setVisible); SET_ENTITY_PROPERTY_FROM_PROPERTIES(name, setName); SET_ENTITY_PROPERTY_FROM_PROPERTIES(locked, setLocked); @@ -1470,8 +1472,6 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(lastEditedBy, setLastEditedBy); SET_ENTITY_PROPERTY_FROM_PROPERTIES(entityHostType, setEntityHostType); SET_ENTITY_PROPERTY_FROM_PROPERTIES(owningAvatarID, setOwningAvatarID); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentID, setParentID); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentJointIndex, setParentJointIndex); SET_ENTITY_PROPERTY_FROM_PROPERTIES(queryAACube, setQueryAACube); SET_ENTITY_PROPERTY_FROM_PROPERTIES(canCastShadow, setCanCastShadow); SET_ENTITY_PROPERTY_FROM_PROPERTIES(isVisibleInSecondaryCamera, setIsVisibleInSecondaryCamera); diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 0ca851e228..bd1977f053 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -197,7 +197,7 @@ public: void setDescription(const QString& value); /// Dimensions in meters (0.0 - TREE_SCALE) - glm::vec3 getScaledDimensions() const; + virtual glm::vec3 getScaledDimensions() const; virtual void setScaledDimensions(const glm::vec3& value); virtual glm::vec3 getRaycastDimensions() const { return getScaledDimensions(); } diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 7575763bf9..5ae9b30869 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -462,6 +462,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { // Core CHECK_PROPERTY_CHANGE(PROP_SIMULATION_OWNER, simulationOwner); + CHECK_PROPERTY_CHANGE(PROP_PARENT_ID, parentID); + CHECK_PROPERTY_CHANGE(PROP_PARENT_JOINT_INDEX, parentJointIndex); CHECK_PROPERTY_CHANGE(PROP_VISIBLE, visible); CHECK_PROPERTY_CHANGE(PROP_NAME, name); CHECK_PROPERTY_CHANGE(PROP_LOCKED, locked); @@ -476,8 +478,6 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_LAST_EDITED_BY, lastEditedBy); CHECK_PROPERTY_CHANGE(PROP_ENTITY_HOST_TYPE, entityHostType); CHECK_PROPERTY_CHANGE(PROP_OWNING_AVATAR_ID, owningAvatarID); - CHECK_PROPERTY_CHANGE(PROP_PARENT_ID, parentID); - CHECK_PROPERTY_CHANGE(PROP_PARENT_JOINT_INDEX, parentJointIndex); CHECK_PROPERTY_CHANGE(PROP_QUERY_AA_CUBE, queryAACube); CHECK_PROPERTY_CHANGE(PROP_CAN_CAST_SHADOW, canCastShadow); CHECK_PROPERTY_CHANGE(PROP_VISIBLE_IN_SECONDARY_CAMERA, isVisibleInSecondaryCamera); @@ -1551,6 +1551,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool // Core properties //COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SIMULATION_OWNER, simulationOwner); // not exposed yet + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_ID, parentID); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_JOINT_INDEX, parentJointIndex); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VISIBLE, visible); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NAME, name); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCKED, locked); @@ -1565,8 +1567,6 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LAST_EDITED_BY, lastEditedBy); COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ENTITY_HOST_TYPE, entityHostType, getEntityHostTypeAsString()); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_OWNING_AVATAR_ID, owningAvatarID); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_ID, parentID); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_JOINT_INDEX, parentJointIndex); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_QUERY_AA_CUBE, queryAACube); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CAN_CAST_SHADOW, canCastShadow); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VISIBLE_IN_SECONDARY_CAMERA, isVisibleInSecondaryCamera); @@ -1956,6 +1956,8 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool // not handled yet // COPY_PROPERTY_FROM_QSCRIPTVALUE(simulationOwner, SimulationOwner, setSimulationOwner); } + COPY_PROPERTY_FROM_QSCRIPTVALUE(parentID, QUuid, setParentID); + COPY_PROPERTY_FROM_QSCRIPTVALUE(parentJointIndex, quint16, setParentJointIndex); COPY_PROPERTY_FROM_QSCRIPTVALUE(visible, bool, setVisible); COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName); COPY_PROPERTY_FROM_QSCRIPTVALUE(locked, bool, setLocked); @@ -1972,8 +1974,6 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(entityHostType, EntityHostType); COPY_PROPERTY_FROM_QSCRIPTVALUE(owningAvatarID, QUuid, setOwningAvatarID); } - COPY_PROPERTY_FROM_QSCRIPTVALUE(parentID, QUuid, setParentID); - COPY_PROPERTY_FROM_QSCRIPTVALUE(parentJointIndex, quint16, setParentJointIndex); COPY_PROPERTY_FROM_QSCRIPTVALUE(queryAACube, AACube, setQueryAACube); // TODO: should scripts be able to set this? COPY_PROPERTY_FROM_QSCRIPTVALUE(canCastShadow, bool, setCanCastShadow); COPY_PROPERTY_FROM_QSCRIPTVALUE(isVisibleInSecondaryCamera, bool, setIsVisibleInSecondaryCamera); @@ -2243,6 +2243,8 @@ void EntityItemProperties::copyFromJSONString(QScriptEngine& scriptEngine, const void EntityItemProperties::merge(const EntityItemProperties& other) { // Core COPY_PROPERTY_IF_CHANGED(simulationOwner); + COPY_PROPERTY_IF_CHANGED(parentID); + COPY_PROPERTY_IF_CHANGED(parentJointIndex); COPY_PROPERTY_IF_CHANGED(visible); COPY_PROPERTY_IF_CHANGED(name); COPY_PROPERTY_IF_CHANGED(locked); @@ -2257,8 +2259,6 @@ void EntityItemProperties::merge(const EntityItemProperties& other) { COPY_PROPERTY_IF_CHANGED(lastEditedBy); COPY_PROPERTY_IF_CHANGED(entityHostType); COPY_PROPERTY_IF_CHANGED(owningAvatarID); - COPY_PROPERTY_IF_CHANGED(parentID); - COPY_PROPERTY_IF_CHANGED(parentJointIndex); COPY_PROPERTY_IF_CHANGED(queryAACube); COPY_PROPERTY_IF_CHANGED(canCastShadow); COPY_PROPERTY_IF_CHANGED(isVisibleInSecondaryCamera); @@ -2526,6 +2526,8 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr std::call_once(initMap, []() { // Core ADD_PROPERTY_TO_MAP(PROP_SIMULATION_OWNER, SimulationOwner, simulationOwner, SimulationOwner); + ADD_PROPERTY_TO_MAP(PROP_PARENT_ID, ParentID, parentID, QUuid); + ADD_PROPERTY_TO_MAP(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, uint16_t); ADD_PROPERTY_TO_MAP(PROP_VISIBLE, Visible, visible, bool); ADD_PROPERTY_TO_MAP(PROP_NAME, Name, name, QString); ADD_PROPERTY_TO_MAP(PROP_LOCKED, Locked, locked, bool); @@ -2541,8 +2543,6 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr ADD_PROPERTY_TO_MAP(PROP_LAST_EDITED_BY, LastEditedBy, lastEditedBy, QUuid); ADD_PROPERTY_TO_MAP(PROP_ENTITY_HOST_TYPE, EntityHostType, entityHostType, entity::HostType); ADD_PROPERTY_TO_MAP(PROP_OWNING_AVATAR_ID, OwningAvatarID, owningAvatarID, QUuid); - ADD_PROPERTY_TO_MAP(PROP_PARENT_ID, ParentID, parentID, QUuid); - ADD_PROPERTY_TO_MAP(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, uint16_t); ADD_PROPERTY_TO_MAP(PROP_QUERY_AA_CUBE, QueryAACube, queryAACube, AACube); ADD_PROPERTY_TO_MAP(PROP_CAN_CAST_SHADOW, CanCastShadow, canCastShadow, bool); ADD_PROPERTY_TO_MAP(PROP_VISIBLE_IN_SECONDARY_CAMERA, IsVisibleInSecondaryCamera, isVisibleInSecondaryCamera, bool); @@ -2998,6 +2998,8 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_SIMULATION_OWNER, properties._simulationOwner.toByteArray()); + APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, properties.getParentID()); + APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, properties.getParentJointIndex()); APPEND_ENTITY_PROPERTY(PROP_VISIBLE, properties.getVisible()); APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName()); APPEND_ENTITY_PROPERTY(PROP_LOCKED, properties.getLocked()); @@ -3012,8 +3014,6 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, properties.getLastEditedBy()); // APPEND_ENTITY_PROPERTY(PROP_ENTITY_HOST_TYPE, (uint32_t)properties.getEntityHostType()); // not sent over the wire // APPEND_ENTITY_PROPERTY(PROP_OWNING_AVATAR_ID, properties.getOwningAvatarID()); // not sent over the wire - APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, properties.getParentID()); - APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, properties.getParentJointIndex()); APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, properties.getQueryAACube()); APPEND_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, properties.getCanCastShadow()); // APPEND_ENTITY_PROPERTY(PROP_VISIBLE_IN_SECONDARY_CAMERA, properties.getIsVisibleInSecondaryCamera()); // not sent over the wire @@ -3124,6 +3124,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, properties.getModelURL()); + APPEND_ENTITY_PROPERTY(PROP_MODEL_SCALE, properties.getModelScale()); APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, properties.getJointRotationsSet()); APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, properties.getJointRotations()); APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, properties.getJointTranslationsSet()); @@ -3477,6 +3478,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int processedBytes += propertyFlags.getEncodedLength(); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SIMULATION_OWNER, QByteArray, setSimulationOwner); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_ID, QUuid, setParentID); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE, bool, setVisible); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked); @@ -3491,8 +3494,6 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LAST_EDITED_BY, QUuid, setLastEditedBy); // READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ENTITY_HOST_TYPE, entity::HostType, setEntityHostType); // not sent over the wire // READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_OWNING_AVATAR_ID, QUuid, setOwningAvatarID); // not sent over the wire - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_ID, QUuid, setParentID); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_QUERY_AA_CUBE, AACube, setQueryAACube); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow); // READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE_IN_SECONDARY_CAMERA, bool, setIsVisibleInSecondaryCamera); // not sent over the wire @@ -3599,6 +3600,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MODEL_URL, QString, setModelURL); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MODEL_SCALE, vec3, setModelScale); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS_SET, QVector, setJointRotationsSet); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS, QVector, setJointRotations); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS_SET, QVector, setJointTranslationsSet); @@ -3884,6 +3886,8 @@ bool EntityItemProperties::decodeCloneEntityMessage(const QByteArray& buffer, in void EntityItemProperties::markAllChanged() { // Core _simulationOwnerChanged = true; + _parentIDChanged = true; + _parentJointIndexChanged = true; _visibleChanged = true; _nameChanged = true; _lockedChanged = true; @@ -3898,8 +3902,6 @@ void EntityItemProperties::markAllChanged() { _lastEditedByChanged = true; _entityHostTypeChanged = true; _owningAvatarIDChanged = true; - _parentIDChanged = true; - _parentJointIndexChanged = true; _queryAACubeChanged = true; _canCastShadowChanged = true; _isVisibleInSecondaryCameraChanged = true; @@ -4232,6 +4234,12 @@ QList EntityItemProperties::listChangedProperties() { if (simulationOwnerChanged()) { out += "simulationOwner"; } + if (parentIDChanged()) { + out += "parentID"; + } + if (parentJointIndexChanged()) { + out += "parentJointIndex"; + } if (visibleChanged()) { out += "visible"; } @@ -4274,12 +4282,6 @@ QList EntityItemProperties::listChangedProperties() { if (owningAvatarIDChanged()) { out += "owningAvatarID"; } - if (parentIDChanged()) { - out += "parentID"; - } - if (parentJointIndexChanged()) { - out += "parentJointIndex"; - } if (queryAACubeChanged()) { out += "queryAACube"; } diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index afc3537559..00a93dd129 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -161,6 +161,8 @@ public: // Core Properties DEFINE_PROPERTY_REF(PROP_SIMULATION_OWNER, SimulationOwner, simulationOwner, SimulationOwner, SimulationOwner()); + DEFINE_PROPERTY_REF(PROP_PARENT_ID, ParentID, parentID, QUuid, UNKNOWN_ENTITY_ID); + DEFINE_PROPERTY_REF(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, quint16, -1); DEFINE_PROPERTY(PROP_VISIBLE, Visible, visible, bool, ENTITY_ITEM_DEFAULT_VISIBLE); DEFINE_PROPERTY_REF(PROP_NAME, Name, name, QString, ENTITY_ITEM_DEFAULT_NAME); DEFINE_PROPERTY(PROP_LOCKED, Locked, locked, bool, ENTITY_ITEM_DEFAULT_LOCKED); @@ -175,8 +177,6 @@ public: DEFINE_PROPERTY_REF(PROP_LAST_EDITED_BY, LastEditedBy, lastEditedBy, QUuid, ENTITY_ITEM_DEFAULT_LAST_EDITED_BY); DEFINE_PROPERTY_REF_ENUM(PROP_ENTITY_HOST_TYPE, EntityHostType, entityHostType, entity::HostType, entity::HostType::DOMAIN); DEFINE_PROPERTY_REF_WITH_SETTER(PROP_OWNING_AVATAR_ID, OwningAvatarID, owningAvatarID, QUuid, UNKNOWN_ENTITY_ID); - DEFINE_PROPERTY_REF(PROP_PARENT_ID, ParentID, parentID, QUuid, UNKNOWN_ENTITY_ID); - DEFINE_PROPERTY_REF(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, quint16, -1); DEFINE_PROPERTY_REF(PROP_QUERY_AA_CUBE, QueryAACube, queryAACube, AACube, AACube()); DEFINE_PROPERTY(PROP_CAN_CAST_SHADOW, CanCastShadow, canCastShadow, bool, ENTITY_ITEM_DEFAULT_CAN_CAST_SHADOW); DEFINE_PROPERTY(PROP_VISIBLE_IN_SECONDARY_CAMERA, IsVisibleInSecondaryCamera, isVisibleInSecondaryCamera, bool, ENTITY_ITEM_DEFAULT_VISIBLE_IN_SECONDARY_CAMERA); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index cce30c9614..0326268f55 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -20,6 +20,8 @@ enum EntityPropertyList { // Core properties PROP_SIMULATION_OWNER, + PROP_PARENT_ID, + PROP_PARENT_JOINT_INDEX, PROP_VISIBLE, PROP_NAME, PROP_LOCKED, @@ -34,8 +36,6 @@ enum EntityPropertyList { PROP_LAST_EDITED_BY, PROP_ENTITY_HOST_TYPE, // not sent over the wire PROP_OWNING_AVATAR_ID, // not sent over the wire - PROP_PARENT_ID, - PROP_PARENT_JOINT_INDEX, PROP_QUERY_AA_CUBE, PROP_CAN_CAST_SHADOW, PROP_VISIBLE_IN_SECONDARY_CAMERA, // not sent over the wire diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index bb8f375302..505ee26c0f 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -301,6 +301,31 @@ void ModelEntityItem::setModelURL(const QString& url) { }); } +glm::vec3 ModelEntityItem::getScaledDimensions() const { + glm::vec3 parentScale = getTransform().getScale(); + return _unscaledDimensions * parentScale; +} + +void ModelEntityItem::setScaledDimensions(const glm::vec3& value) { + glm::vec3 parentScale = getTransform().getScale(); + setUnscaledDimensions(value / parentScale); +} + +const Transform ModelEntityItem::getTransform() const { + bool success; + return getTransform(success); +} + +const Transform ModelEntityItem::getTransform(bool& success, int depth) const { + const Transform parentTransform = getParentTransform(success, depth); + Transform localTransform = getLocalTransform(); + localTransform.postScale(getModelScale()); + + Transform worldTransform; + Transform::mult(worldTransform, parentTransform, localTransform); + + return worldTransform; +} void ModelEntityItem::setCompoundShapeURL(const QString& url) { withWriteLock([&] { if (_compoundShapeURL.get() != url) { @@ -715,13 +740,13 @@ bool ModelEntityItem::applyNewAnimationProperties(AnimationPropertyGroup newProp } glm::vec3 ModelEntityItem::getModelScale() const { - return _modelScaleLock.resultWithReadLock([&] { - return getSNScale(); + return resultWithReadLock([&] { + return _modelScale; }); } void ModelEntityItem::setModelScale(const glm::vec3& modelScale) { - _modelScaleLock.withWriteLock([&] { - setSNScale(modelScale); + withWriteLock([&] { + _modelScale = modelScale; }); -} \ No newline at end of file +} diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 234cfa435e..0efbbbb16c 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -66,6 +66,12 @@ public: static const QString DEFAULT_MODEL_URL; QString getModelURL() const; + virtual glm::vec3 getScaledDimensions() const override; + virtual void setScaledDimensions(const glm::vec3& value) override; + + virtual const Transform getTransform(bool& success, int depth = 0) const override; + virtual const Transform getTransform() const override; + static const QString DEFAULT_COMPOUND_SHAPE_URL; QString getCompoundShapeURL() const; @@ -144,7 +150,6 @@ protected: // they aren't currently updated from data in the model/rig, and they don't have a direct effect // on what's rendered. ReadWriteLockable _jointDataLock; - ReadWriteLockable _modelScaleLock; bool _jointRotationsExplicitlySet { false }; // were the joints set as a property or just side effect of animations bool _jointTranslationsExplicitlySet{ false }; // were the joints set as a property or just side effect of animations @@ -159,6 +164,7 @@ protected: int _lastKnownCurrentFrame{-1}; glm::u8vec3 _color; + glm::vec3 _modelScale; QString _modelURL; bool _relayParentJoints; bool _groupCulled { false }; diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index b6fcd2f2ce..4229a4a152 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -263,6 +263,7 @@ enum class EntityVersion : PacketVersion { ShowKeyboardFocusHighlight, WebBillboardMode, ModelScale, + ReOrderParentIDProperties, // Add new versions above here NUM_PACKET_TYPE, diff --git a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js index e59b2e35ad..5dcfee23cb 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js @@ -117,11 +117,12 @@ Script.include("/~/system/libraries/utils.js"); this.previousParentID[this.grabbedThingID] = grabbedProperties.parentID; this.previousParentJointIndex[this.grabbedThingID] = grabbedProperties.parentJointIndex; } - Overlays.editOverlay(this.grabbedThingID, reparentProps); // resizeTablet to counter adjust offsets to account for change of scale from sensorToWorldMatrix if (HMD.tabletID && this.grabbedThingID === HMD.tabletID) { - resizeTablet(getTabletWidthFromSettings(), reparentProps.parentJointIndex); + reparentAndScaleTablet(getTabletWidthFromSettings(), reparentProps); + } else { + Entities.editEntity(this.grabbedThingID, reparentProps); } Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({ @@ -140,7 +141,7 @@ Script.include("/~/system/libraries/utils.js"); }); } else if (!this.robbed){ // before we grabbed it, overlay was a child of something; put it back. - Overlays.editOverlay(this.grabbedThingID, { + Entities.editEntity(this.grabbedThingID, { parentID: this.previousParentID[this.grabbedThingID], parentJointIndex: this.previousParentJointIndex[this.grabbedThingID] }); diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js index c0e3178521..c5ae9730f2 100644 --- a/scripts/system/libraries/WebTablet.js +++ b/scripts/system/libraries/WebTablet.js @@ -159,7 +159,7 @@ WebTablet = function (url, width, dpi, hand, location, visible) { url: url, localPosition: { x: 0, y: WEB_ENTITY_Y_OFFSET, z: -WEB_ENTITY_Z_OFFSET }, localRotation: Quat.angleAxis(180, Y_AXIS), - dimensions: {x: screenWidth, y: screenHeight, z: 0.1}, + dimensions: {x: screenWidth, y: screenHeight, z: 1.0}, dpi: tabletDpi, color: { red: 255, green: 255, blue: 255 }, alpha: 1.0, diff --git a/scripts/system/libraries/utils.js b/scripts/system/libraries/utils.js index 931c346299..6f74b43a8e 100644 --- a/scripts/system/libraries/utils.js +++ b/scripts/system/libraries/utils.js @@ -395,7 +395,7 @@ resizeTablet = function (width, newParentJointIndex, sensorToWorldScaleOverride) var tabletDpi = DEFAULT_DPI * (DEFAULT_WIDTH / tabletWidth); // update tablet model dimensions - Overlays.editOverlay(HMD.tabletID, { + Entities.editEntity(HMD.tabletID, { dimensions: { x: tabletWidth, y: tabletHeight, z: tabletDepth } }); @@ -405,9 +405,9 @@ resizeTablet = function (width, newParentJointIndex, sensorToWorldScaleOverride) var screenWidth = 0.9367 * tabletWidth; var screenHeight = 0.9000 * tabletHeight; var landscape = Tablet.getTablet("com.highfidelity.interface.tablet.system").landscape; - Overlays.editOverlay(HMD.tabletScreenID, { + Entities.editEntity(HMD.tabletScreenID, { localPosition: { x: 0, y: WEB_ENTITY_Y_OFFSET, z: -WEB_ENTITY_Z_OFFSET}, - dimensions: {x: landscape ? screenHeight : screenWidth, y: landscape ? screenWidth : screenHeight, z: 0.1}, + dimensions: {x: landscape ? screenHeight : screenWidth, y: landscape ? screenWidth : screenHeight, z: 1.0}, dpi: tabletDpi }); @@ -416,19 +416,83 @@ resizeTablet = function (width, newParentJointIndex, sensorToWorldScaleOverride) var HOME_BUTTON_X_OFFSET = 0.00079 * sensorScaleOffsetOverride * sensorScaleFactor; var HOME_BUTTON_Y_OFFSET = -1 * ((tabletHeight / 2) - (4.0 * tabletScaleFactor / 2)) * sensorScaleOffsetOverride; var HOME_BUTTON_Z_OFFSET = (tabletDepth / 1.9) * sensorScaleOffsetOverride; - Overlays.editOverlay(HMD.homeButtonID, { + Entities.editEntity(HMD.homeButtonID, { localPosition: { x: HOME_BUTTON_X_OFFSET, y: HOME_BUTTON_Y_OFFSET, z: -HOME_BUTTON_Z_OFFSET }, localRotation: { x: 0, y: 1, z: 0, w: 0 }, dimensions: { x: homeButtonDim, y: homeButtonDim, z: homeButtonDim } }); - Overlays.editOverlay(HMD.homeButtonHighlightID, { + Entities.editEntity(HMD.homeButtonHighlightID, { localPosition: { x: -HOME_BUTTON_X_OFFSET, y: HOME_BUTTON_Y_OFFSET, z: -HOME_BUTTON_Z_OFFSET }, localRotation: { x: 0, y: 1, z: 0, w: 0 }, dimensions: { x: homeButtonDim, y: homeButtonDim, z: homeButtonDim } }); }; + +reparentAndScaleTablet = function(width, reparentProps) { + + if (!HMD.tabletID || !HMD.tabletScreenID || !HMD.homeButtonID || !HMD.homeButtonHighlightID) { + return; + } + var sensorScaleFactor = MyAvatar.sensorToWorldScale; + var sensorScaleOffsetOverride = 1; + var SENSOR_TO_ROOM_MATRIX = 65534; + var parentJointIndex = reparentProps.parentJointIndex; + if (parentJointIndex === SENSOR_TO_ROOM_MATRIX) { + sensorScaleOffsetOverride = 1 / sensorScaleFactor; + } + + + // will need to be recaclulated if dimensions of fbx model change. + var TABLET_NATURAL_DIMENSIONS = {x: 32.083, y: 48.553, z: 2.269}; + var DEFAULT_DPI = 31; + var DEFAULT_WIDTH = 0.4375; + + // scale factor of natural tablet dimensions. + var tabletWidth = (width || DEFAULT_WIDTH) * sensorScaleFactor; + var tabletScaleFactor = tabletWidth / TABLET_NATURAL_DIMENSIONS.x; + var tabletHeight = TABLET_NATURAL_DIMENSIONS.y * tabletScaleFactor; + var tabletDepth = TABLET_NATURAL_DIMENSIONS.z * tabletScaleFactor; + var tabletDpi = DEFAULT_DPI * (DEFAULT_WIDTH / tabletWidth); + + // update tablet model dimensions + + Entities.editEntity(HMD.tabletID, { + parentID: reparentProps.parentID, + parentJointIndex: reparentProps.parentJointIndex, + dimensions: { x: tabletWidth, y: tabletHeight, z: tabletDepth} + }); + // update webOverlay + var WEB_ENTITY_Z_OFFSET = (tabletDepth / 2.5) * sensorScaleOffsetOverride; + var WEB_ENTITY_Y_OFFSET = 1.25 * tabletScaleFactor * sensorScaleOffsetOverride; + var screenWidth = 0.9367 * tabletWidth; + var screenHeight = 0.9000 * tabletHeight; + var landscape = Tablet.getTablet("com.highfidelity.interface.tablet.system").landscape; + Entities.editEntity(HMD.tabletScreenID, { + localPosition: { x: 0, y: WEB_ENTITY_Y_OFFSET, z: -WEB_ENTITY_Z_OFFSET}, + dimensions: {x: landscape ? screenHeight : screenWidth, y: landscape ? screenWidth : screenHeight, z: 1.0}, + dpi: tabletDpi + }); + + // update homeButton + var homeButtonDim = 4.0 * tabletScaleFactor / 1.5; + var HOME_BUTTON_X_OFFSET = 0.00079 * sensorScaleOffsetOverride * sensorScaleFactor; + var HOME_BUTTON_Y_OFFSET = -1 * ((tabletHeight / 2) - (4.0 * tabletScaleFactor / 2)) * sensorScaleOffsetOverride; + var HOME_BUTTON_Z_OFFSET = (tabletDepth / 1.9) * sensorScaleOffsetOverride; + Entities.editEntity(HMD.homeButtonID, { + localPosition: { x: HOME_BUTTON_X_OFFSET, y: HOME_BUTTON_Y_OFFSET, z: -HOME_BUTTON_Z_OFFSET }, + localRotation: { x: 0, y: 1, z: 0, w: 0 }, + dimensions: { x: homeButtonDim, y: homeButtonDim, z: homeButtonDim } + }); + + Entities.editEntity(HMD.homeButtonHighlightID, { + localPosition: { x: -HOME_BUTTON_X_OFFSET, y: HOME_BUTTON_Y_OFFSET, z: -HOME_BUTTON_Z_OFFSET }, + localRotation: { x: 0, y: 1, z: 0, w: 0 }, + dimensions: { x: homeButtonDim, y: homeButtonDim, z: homeButtonDim } + }); +} + getMainTabletIDs = function () { var tabletIDs = []; if (HMD.tabletID) { From 15064f0097d49126271e9187800360120b75dce2 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 28 Feb 2019 14:04:22 -0800 Subject: [PATCH 07/20] fix lasers and keyboard on reload --- interface/src/Application.cpp | 5 +++++ interface/src/ui/Keyboard.cpp | 8 ++++++++ interface/src/ui/Keyboard.h | 2 ++ 3 files changed, 15 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ebc1176ee1..bfae3e7303 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5770,6 +5770,11 @@ void Application::reloadResourceCaches() { DependencyManager::get()->reset(); // Force redownload of .fst models + DependencyManager::get()->reloadAllScripts(); + getOffscreenUI()->clearCache(); + + DependencyManager::get()->createKeyboard(); + getMyAvatar()->resetFullAvatarURL(); } diff --git a/interface/src/ui/Keyboard.cpp b/interface/src/ui/Keyboard.cpp index 1ff1c0248b..d344e27d54 100644 --- a/interface/src/ui/Keyboard.cpp +++ b/interface/src/ui/Keyboard.cpp @@ -259,6 +259,12 @@ void Keyboard::setUse3DKeyboard(bool use) { void Keyboard::createKeyboard() { auto pointerManager = DependencyManager::get(); + if (_created) { + pointerManager->removePointer(_leftHandStylus); + pointerManager->removePointer(_rightHandStylus); + clearKeyboardKeys(); + } + QVariantMap modelProperties { { "url", MALLET_MODEL_URL } }; @@ -289,6 +295,8 @@ void Keyboard::createKeyboard() { loadKeyboardFile(keyboardSvg); _keySound = DependencyManager::get()->getSound(SOUND_FILE); + + _created = true; } bool Keyboard::isRaised() const { diff --git a/interface/src/ui/Keyboard.h b/interface/src/ui/Keyboard.h index 627eb68dfd..b3358e486d 100644 --- a/interface/src/ui/Keyboard.h +++ b/interface/src/ui/Keyboard.h @@ -193,6 +193,8 @@ private: QSet _itemsToIgnore; std::vector> _keyboardLayers; + + bool _created { false }; }; #endif From 7d9efe4c091521e8c3a0362a8cd673410a072263 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 28 Feb 2019 14:20:11 -0800 Subject: [PATCH 08/20] avoid mem-leak for serverless domains --- interface/src/Application.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 83b287b7ae..9913e0d128 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3773,9 +3773,12 @@ std::map Application::prepareServerlessDomainContents(QUrl dom tmpTree->reaverageOctreeElements(); tmpTree->sendEntities(&_entityEditSender, getEntities()->getTree(), 0, 0, 0); } + std::map namedPaths = tmpTree->getNamedPaths(); - return tmpTree->getNamedPaths(); + // we must manually eraseAllOctreeElements(false) else the tmpTree will mem-leak + tmpTree->eraseAllOctreeElements(false); + return namedPaths; } void Application::loadServerlessDomain(QUrl domainURL) { From ed9ebf84c971ed040612d6cc7075ae6d9cd521bd Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 28 Feb 2019 14:21:14 -0800 Subject: [PATCH 09/20] remove unuseful log entry --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index efd1399f30..e54258fc3e 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -232,8 +232,6 @@ void EntityTreeRenderer::clearNonLocalEntities() { } } scene->enqueueTransaction(transaction); - } else { - qCWarning(entitiesrenderer) << "EntitityTreeRenderer::clear(), Unexpected null scene, possibly during application shutdown"; } _renderablesToUpdate = savedEntities; From 33d6e2ce3b2e562bdac33368d7a7750113e3bd3b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 28 Feb 2019 14:21:35 -0800 Subject: [PATCH 10/20] avoid mem-leaked entities when clearing tree --- libraries/entities/src/EntityTree.cpp | 40 +++++++++++++++++++-------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 53b4fb4fe4..8855bc28a7 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -52,7 +52,15 @@ EntityTree::EntityTree(bool shouldReaverage) : } EntityTree::~EntityTree() { - eraseAllOctreeElements(false); + // NOTE: to eraseAllOctreeElements() in this context is useless because + // any OctreeElements in the tree still have shared backpointers to this Tree + // which means the dtor never would have been called in the first place! + // + // I'm keeping this useless commented-out line to remind us: + // we don't need shared pointer overhead for EntityTrees. + // TODO: EntityTreeElement::_tree should be raw back pointer. + // AND: EntityItem::_element should be a raw back pointer. + //eraseAllOctreeElements(false); // KEEP THIS } void EntityTree::setEntityScriptSourceWhitelist(const QString& entityScriptSourceWhitelist) { @@ -74,16 +82,15 @@ void EntityTree::eraseNonLocalEntities() { emit clearingEntities(); if (_simulation) { - // This will clear all entities host types including local entities, because local entities - // are not in the physics simulation + // local entities are not in the simulation, so we clear ALL _simulation->clearEntities(); } - _staleProxies.clear(); - QHash localMap; - localMap.swap(_entityMap); - QHash savedEntities; this->withWriteLock([&] { - foreach(EntityItemPointer entity, localMap) { + QHash savedEntities; + // NOTE: lock the Tree first, then lock the _entityMap. + // It should never be done the other way around. + QReadLocker locker(&_entityMapLock); + foreach(EntityItemPointer entity, _entityMap) { EntityTreeElementPointer element = entity->getElement(); if (element) { element->cleanupNonLocalEntities(); @@ -91,11 +98,16 @@ void EntityTree::eraseNonLocalEntities() { if (entity->isLocalEntity()) { savedEntities[entity->getEntityItemID()] = entity; + } else { + int32_t spaceIndex = entity->getSpaceIndex(); + if (spaceIndex != -1) { + // stale spaceIndices will be freed later + _staleProxies.push_back(spaceIndex); + } } } + _entityMap.swap(savedEntities); }); - localMap.clear(); - _entityMap = savedEntities; resetClientEditStats(); clearDeletedEntities(); @@ -113,13 +125,13 @@ void EntityTree::eraseNonLocalEntities() { _needsParentFixup = localEntitiesNeedsParentFixup; } } + void EntityTree::eraseAllOctreeElements(bool createNewRoot) { emit clearingEntities(); if (_simulation) { _simulation->clearEntities(); } - _staleProxies.clear(); QHash localMap; localMap.swap(_entityMap); this->withWriteLock([&] { @@ -128,6 +140,11 @@ void EntityTree::eraseAllOctreeElements(bool createNewRoot) { if (element) { element->cleanupEntities(); } + int32_t spaceIndex = entity->getSpaceIndex(); + if (spaceIndex != -1) { + // assume stale spaceIndices will be freed later + _staleProxies.push_back(spaceIndex); + } } }); localMap.clear(); @@ -767,6 +784,7 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) // keep a record of valid stale spaceIndices so they can be removed from the Space int32_t spaceIndex = theEntity->getSpaceIndex(); if (spaceIndex != -1) { + // stale spaceIndices will be freed later _staleProxies.push_back(spaceIndex); } } From 8a7853a701a2b4790f77b05d49e94b7e7fbd48d6 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 28 Feb 2019 14:38:13 -0800 Subject: [PATCH 11/20] remove crufty comment --- libraries/entities/src/EntityTree.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 8855bc28a7..6e404ce690 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -781,7 +781,6 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) _simulation->prepareEntityForDelete(theEntity); } - // keep a record of valid stale spaceIndices so they can be removed from the Space int32_t spaceIndex = theEntity->getSpaceIndex(); if (spaceIndex != -1) { // stale spaceIndices will be freed later From 1476251dcb359f335084e4413f6f4c1634085a7f Mon Sep 17 00:00:00 2001 From: r3tk0n Date: Thu, 28 Feb 2019 15:21:24 -0800 Subject: [PATCH 12/20] Enable bubble on AFK, respect user setting upon return from AFK. --- scripts/system/away.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/scripts/system/away.js b/scripts/system/away.js index 45b6f43b73..3deb2249be 100644 --- a/scripts/system/away.js +++ b/scripts/system/away.js @@ -65,7 +65,7 @@ var eventMappingName = "io.highfidelity.away"; // goActive on hand controller bu var eventMapping = Controller.newMapping(eventMappingName); var avatarPosition = MyAvatar.position; var wasHmdMounted = HMD.mounted; - +var previousBubbleState = Users.getIgnoreRadiusEnabled(); // some intervals we may create/delete var avatarMovedInterval; @@ -166,7 +166,12 @@ function goAway(fromStartup) { avatarMovedInterval = Script.setInterval(ifAvatarMovedGoActive, BASIC_TIMER_INTERVAL); }, WAIT_FOR_MOVE_ON_STARTUP); } - + + previousBubbleState = Users.getIgnoreRadiusEnabled(); + if (!previousBubbleState) { + Users.toggleIgnoreRadius(); + } + UserActivityLogger.bubbleToggled(Users.getIgnoreRadiusEnabled()); UserActivityLogger.toggledAway(true); MyAvatar.isAway = true; } @@ -179,6 +184,11 @@ function goActive() { UserActivityLogger.toggledAway(false); MyAvatar.isAway = false; + if (Users.getIgnoreRadiusEnabled() !== previousBubbleState) { + Users.toggleIgnoreRadius(); + UserActivityLogger.bubbleToggled(Users.getIgnoreRadiusEnabled()); + } + if (!Window.hasFocus()) { Window.setFocus(); } From d33400f6ad114e85086d2b738e0f8f85fd94cc4b Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 28 Feb 2019 15:25:15 -0800 Subject: [PATCH 13/20] fix GCC compiler warning --- libraries/physics/src/ObjectActionTractor.cpp | 2 +- libraries/shared/src/NestableTransformNode.h | 2 +- libraries/shared/src/SpatiallyNestable.cpp | 22 +++++++++---------- libraries/shared/src/SpatiallyNestable.h | 6 ++--- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libraries/physics/src/ObjectActionTractor.cpp b/libraries/physics/src/ObjectActionTractor.cpp index a46aac3f29..c7681e217c 100644 --- a/libraries/physics/src/ObjectActionTractor.cpp +++ b/libraries/physics/src/ObjectActionTractor.cpp @@ -60,7 +60,7 @@ bool ObjectActionTractor::getTarget(float deltaTimeStep, glm::quat& rotation, gl } if (other && otherIsReady) { bool success; - glm::vec3 otherWorldPosition = other->getWorldPosition(_otherJointIndex, success); + glm::vec3 otherWorldPosition = other->getJointWorldPosition(_otherJointIndex, success); if (!success) { linearTimeScale = FLT_MAX; angularTimeScale = FLT_MAX; diff --git a/libraries/shared/src/NestableTransformNode.h b/libraries/shared/src/NestableTransformNode.h index be017a696d..a584bcd308 100644 --- a/libraries/shared/src/NestableTransformNode.h +++ b/libraries/shared/src/NestableTransformNode.h @@ -32,7 +32,7 @@ public: } bool success; - Transform jointWorldTransform = nestable->getTransform(_jointIndex, success); + Transform jointWorldTransform = nestable->getJointTransform(_jointIndex, success); if (!success) { return Transform(); diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index e7bdc87bf3..d202afc59f 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -92,7 +92,7 @@ Transform SpatiallyNestable::getParentTransform(bool& success, int depth) const return result; } if (parent) { - result = parent->getTransform(_parentJointIndex, success, depth + 1); + result = parent->getJointTransform(_parentJointIndex, success, depth + 1); if (getScalesWithParent()) { result.setScale(parent->scaleForChildren()); } @@ -203,7 +203,7 @@ glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, } if (parent) { - parentTransform = parent->getTransform(parentJointIndex, success); + parentTransform = parent->getJointTransform(parentJointIndex, success); if (!success) { return glm::vec3(0.0f); } @@ -240,7 +240,7 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, } if (parent) { - parentTransform = parent->getTransform(parentJointIndex, success); + parentTransform = parent->getJointTransform(parentJointIndex, success); if (!success) { return glm::quat(); } @@ -350,7 +350,7 @@ glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, } if (parent) { - parentTransform = parent->getTransform(parentJointIndex, success); + parentTransform = parent->getJointTransform(parentJointIndex, success); if (!success) { return glm::vec3(0.0f); } @@ -390,7 +390,7 @@ glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, } if (parent) { - parentTransform = parent->getTransform(parentJointIndex, success); + parentTransform = parent->getJointTransform(parentJointIndex, success); if (!success) { return glm::quat(); } @@ -525,8 +525,8 @@ glm::vec3 SpatiallyNestable::getWorldPosition() const { return result; } -glm::vec3 SpatiallyNestable::getWorldPosition(int jointIndex, bool& success) const { - return getTransform(jointIndex, success).getTranslation(); +glm::vec3 SpatiallyNestable::getJointWorldPosition(int jointIndex, bool& success) const { + return getJointTransform(jointIndex, success).getTranslation(); } void SpatiallyNestable::setWorldPosition(const glm::vec3& position, bool& success, bool tellPhysics) { @@ -579,7 +579,7 @@ glm::quat SpatiallyNestable::getWorldOrientation() const { } glm::quat SpatiallyNestable::getWorldOrientation(int jointIndex, bool& success) const { - return getTransform(jointIndex, success).getRotation(); + return getJointTransform(jointIndex, success).getRotation(); } void SpatiallyNestable::setWorldOrientation(const glm::quat& orientation, bool& success, bool tellPhysics) { @@ -765,7 +765,7 @@ void SpatiallyNestable::breakParentingLoop() const { } } -const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, int depth) const { +const Transform SpatiallyNestable::getJointTransform(int jointIndex, bool& success, int depth) const { // this returns the world-space transform for this object. It finds its parent's transform (which may // cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it. Transform jointInWorldFrame; @@ -832,8 +832,8 @@ glm::vec3 SpatiallyNestable::getSNScale(bool& success) const { return getTransform(success).getScale(); } -glm::vec3 SpatiallyNestable::getSNScale(int jointIndex, bool& success) const { - return getTransform(jointIndex, success).getScale(); +glm::vec3 SpatiallyNestable::getJointSNScale(int jointIndex, bool& success) const { + return getJointTransform(jointIndex, success).getScale(); } void SpatiallyNestable::setSNScale(const glm::vec3& scale) { diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index a802a25e89..6b709f0352 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -129,9 +129,9 @@ public: virtual void setSNScale(const glm::vec3& scale, bool& success); // get world-frame values for a specific joint - virtual const Transform getTransform(int jointIndex, bool& success, int depth = 0) const; - virtual glm::vec3 getWorldPosition(int jointIndex, bool& success) const; - virtual glm::vec3 getSNScale(int jointIndex, bool& success) const; + virtual const Transform getJointTransform(int jointIndex, bool& success, int depth = 0) const; + virtual glm::vec3 getJointWorldPosition(int jointIndex, bool& success) const; + virtual glm::vec3 getJointSNScale(int jointIndex, bool& success) const; // object's parent's frame virtual Transform getLocalTransform() const; From 8d5a3debfa98acce922cb41f53c0752006552471 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 28 Feb 2019 15:24:32 -0800 Subject: [PATCH 14/20] fix chat.js textSize --- scripts/system/chat.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/scripts/system/chat.js b/scripts/system/chat.js index b0a2e114a3..749665f3d8 100644 --- a/scripts/system/chat.js +++ b/scripts/system/chat.js @@ -45,6 +45,17 @@ var speechBubbleLineHeight = 0.05; // The height of a line of text in the speech bubble. var SPEECH_BUBBLE_MAX_WIDTH = 1; // meters + var textSizeOverlay = Overlays.addOverlay("text3d", { + position: MyAvatar.position, + lineHeight: speechBubbleLineHeight, + leftMargin: 0, + topMargin: 0, + rightMargin: 0, + bottomMargin: 0, + ignoreRayIntersection: true, + visible: false + }); + // Load the persistent variables from the Settings, with defaults. function loadSettings() { chatName = Settings.getValue('Chat_chatName', MyAvatar.displayName); @@ -63,6 +74,9 @@ speechBubbleOffset = Settings.getValue('Chat_speechBubbleOffset', {x: 0.0, y: 0.3, z:0.0}); speechBubbleJointName = Settings.getValue('Chat_speechBubbleJointName', 'Head'); speechBubbleLineHeight = Settings.getValue('Chat_speechBubbleLineHeight', 0.05); + Overlays.editOverlay(textSizeOverlay, { + lineHeight: speechBubbleLineHeight + }); saveSettings(); } @@ -637,7 +651,7 @@ // Only overlay text3d has a way to measure the text, not entities. // So we make a temporary one just for measuring text, then delete it. var speechBubbleTextOverlayID = Overlays.addOverlay("text3d", speechBubbleParams); - var textSize = Overlays.textSize(speechBubbleTextOverlayID, speechBubbleMessage); + var textSize = Overlays.textSize(textSizeOverlay, speechBubbleMessage); try { Overlays.deleteOverlay(speechBubbleTextOverlayID); } catch (e) {} @@ -971,6 +985,8 @@ unidentifyAvatars(); disconnectWebHandler(); + Overlays.deleteOverlay(textSizeOverlay); + if (onChatPage) { tablet.gotoHomeScreen(); onChatPage = false; From b26b02fed6d40c5acd75ccc3a4c50fea03738198 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 28 Feb 2019 16:59:31 -0800 Subject: [PATCH 15/20] potential 2d overlay threading fixes --- interface/src/ui/overlays/Overlay.cpp | 19 +--- interface/src/ui/overlays/Overlay.h | 9 +- interface/src/ui/overlays/Overlay2D.cpp | 22 +--- interface/src/ui/overlays/Overlay2D.h | 5 - interface/src/ui/overlays/Overlays.cpp | 133 +++++++++++------------ interface/src/ui/overlays/QmlOverlay.cpp | 28 ++--- interface/src/ui/overlays/QmlOverlay.h | 4 +- 7 files changed, 77 insertions(+), 143 deletions(-) diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index 714db97bc2..bf79a46dcb 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -16,8 +16,7 @@ #include "Application.h" Overlay::Overlay() : - _renderItemID(render::Item::INVALID_ITEM_ID), - _visible(true) + _renderItemID(render::Item::INVALID_ITEM_ID) { } @@ -34,20 +33,6 @@ void Overlay::setProperties(const QVariantMap& properties) { } } -QVariant Overlay::getProperty(const QString& property) { - if (property == "type") { - return QVariant(getType()); - } - if (property == "id") { - return getID(); - } - if (property == "visible") { - return _visible; - } - - return QVariant(); -} - bool Overlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { _renderItemID = scene->allocateID(); transaction.resetItem(_renderItemID, std::make_shared(overlay)); @@ -65,7 +50,7 @@ render::ItemKey Overlay::getKey() { builder.withViewSpace(); builder.withLayer(render::hifi::LAYER_2D); - if (!getVisible()) { + if (!_visible) { builder.withInvisible(); } diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index ee6e281193..72373d2d20 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -31,7 +31,6 @@ public: virtual render::ItemKey getKey(); virtual AABox getBounds() const = 0; - virtual bool supportsGetProperty() const { return true; } virtual bool addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction); virtual void removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction); @@ -42,17 +41,15 @@ public: // getters virtual QString getType() const = 0; - bool isLoaded() { return true; } bool getVisible() const { return _visible; } // setters - virtual void setVisible(bool visible) { _visible = visible; } + void setVisible(bool visible) { _visible = visible; } unsigned int getStackOrder() const { return _stackOrder; } void setStackOrder(unsigned int stackOrder) { _stackOrder = stackOrder; } - Q_INVOKABLE virtual void setProperties(const QVariantMap& properties); + Q_INVOKABLE virtual void setProperties(const QVariantMap& properties) = 0; Q_INVOKABLE virtual Overlay* createClone() const = 0; - Q_INVOKABLE virtual QVariant getProperty(const QString& property); render::ItemID getRenderItemID() const { return _renderItemID; } void setRenderItemID(render::ItemID renderItemID) { _renderItemID = renderItemID; } @@ -60,7 +57,7 @@ public: protected: render::ItemID _renderItemID { render::Item::INVALID_ITEM_ID }; - bool _visible; + bool _visible { true }; unsigned int _stackOrder { 0 }; private: diff --git a/interface/src/ui/overlays/Overlay2D.cpp b/interface/src/ui/overlays/Overlay2D.cpp index 71b74e9452..91c7198e49 100644 --- a/interface/src/ui/overlays/Overlay2D.cpp +++ b/interface/src/ui/overlays/Overlay2D.cpp @@ -65,24 +65,4 @@ void Overlay2D::setProperties(const QVariantMap& properties) { } setBounds(newBounds); } -} - -QVariant Overlay2D::getProperty(const QString& property) { - if (property == "bounds") { - return qRectToVariant(_bounds); - } - if (property == "x") { - return _bounds.x(); - } - if (property == "y") { - return _bounds.y(); - } - if (property == "width") { - return _bounds.width(); - } - if (property == "height") { - return _bounds.height(); - } - - return Overlay::getProperty(property); -} +} \ No newline at end of file diff --git a/interface/src/ui/overlays/Overlay2D.h b/interface/src/ui/overlays/Overlay2D.h index 54ab52b469..cfcb114398 100644 --- a/interface/src/ui/overlays/Overlay2D.h +++ b/interface/src/ui/overlays/Overlay2D.h @@ -26,10 +26,6 @@ public: virtual uint32_t fetchMetaSubItems(render::ItemIDs& subItems) const override { subItems.push_back(getRenderItemID()); return 1; } // getters - int getX() const { return _bounds.x(); } - int getY() const { return _bounds.y(); } - int getWidth() const { return _bounds.width(); } - int getHeight() const { return _bounds.height(); } const QRect& getBoundingRect() const { return _bounds; } // setters @@ -40,7 +36,6 @@ public: void setBounds(const QRect& bounds) { _bounds = bounds; } void setProperties(const QVariantMap& properties) override; - QVariant getProperty(const QString& property) override; protected: QRect _bounds; // where on the screen to draw diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 9b2f741531..8fd5d236a0 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -772,29 +772,29 @@ QUuid Overlays::addOverlay(const QString& type, const QVariant& properties) { return UNKNOWN_ENTITY_ID; } - if (QThread::currentThread() != thread()) { - QUuid result; - PROFILE_RANGE(script, __FUNCTION__); - BLOCKING_INVOKE_METHOD(this, "addOverlay", Q_RETURN_ARG(QUuid, result), Q_ARG(const QString&, type), Q_ARG(const QVariant&, properties)); - return result; - } - - Overlay::Pointer overlay; - if (type == ImageOverlay::TYPE) { + if (type == ImageOverlay::TYPE || type == TextOverlay::TYPE || type == RectangleOverlay::TYPE) { #if !defined(DISABLE_QML) - overlay = Overlay::Pointer(new ImageOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); -#endif - } else if (type == TextOverlay::TYPE) { -#if !defined(DISABLE_QML) - overlay = Overlay::Pointer(new TextOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); -#endif - } else if (type == RectangleOverlay::TYPE) { - overlay = Overlay::Pointer(new RectangleOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); - } + if (QThread::currentThread() != thread()) { + QUuid result; + PROFILE_RANGE(script, __FUNCTION__); + BLOCKING_INVOKE_METHOD(this, "addOverlay", Q_RETURN_ARG(QUuid, result), Q_ARG(const QString&, type), Q_ARG(const QVariant&, properties)); + return result; + } - if (overlay) { - overlay->setProperties(properties.toMap()); - return add2DOverlay(overlay); + Overlay::Pointer overlay; + if (type == ImageOverlay::TYPE) { + overlay = Overlay::Pointer(new ImageOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); + } else if (type == TextOverlay::TYPE) { + overlay = Overlay::Pointer(new TextOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); + } else if (type == RectangleOverlay::TYPE) { + overlay = Overlay::Pointer(new RectangleOverlay(), [](Overlay* ptr) { ptr->deleteLater(); }); + } + if (overlay) { + overlay->setProperties(properties.toMap()); + return add2DOverlay(overlay); + } +#endif + return QUuid(); } QString entityType = overlayToEntityType(type); @@ -835,15 +835,14 @@ QUuid Overlays::cloneOverlay(const QUuid& id) { return UNKNOWN_ENTITY_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) { + 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; + } return add2DOverlay(Overlay::Pointer(overlay->createClone(), [](Overlay* ptr) { ptr->deleteLater(); })); } @@ -919,6 +918,11 @@ void Overlays::deleteOverlay(const QUuid& id) { Overlay::Pointer overlay = take2DOverlay(id); if (overlay) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "deleteOverlay", Q_ARG(const QUuid&, id)); + return; + } + _overlaysToDelete.push_back(overlay); emit overlayDeleted(id); return; @@ -933,15 +937,14 @@ QString Overlays::getOverlayType(const QUuid& id) { return ""; } - if (QThread::currentThread() != thread()) { - QString result; - PROFILE_RANGE(script, __FUNCTION__); - BLOCKING_INVOKE_METHOD(this, "getOverlayType", Q_RETURN_ARG(QString, result), Q_ARG(const QUuid&, id)); - return result; - } - Overlay::Pointer overlay = get2DOverlay(id); if (overlay) { + if (QThread::currentThread() != thread()) { + QString result; + PROFILE_RANGE(script, __FUNCTION__); + BLOCKING_INVOKE_METHOD(this, "getOverlayType", Q_RETURN_ARG(QString, result), Q_ARG(const QUuid&, id)); + return result; + } return overlay->getType(); } @@ -949,15 +952,14 @@ QString Overlays::getOverlayType(const QUuid& 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(const QUuid&, id)); - return result; - } - Overlay::Pointer overlay = get2DOverlay(id); if (overlay) { + if (QThread::currentThread() != thread()) { + QObject* result; + PROFILE_RANGE(script, __FUNCTION__); + BLOCKING_INVOKE_METHOD(this, "getOverlayObject", Q_RETURN_ARG(QObject*, result), Q_ARG(const QUuid&, id)); + return result; + } return qobject_cast(&(*overlay)); } @@ -969,6 +971,12 @@ QUuid Overlays::getOverlayAtPoint(const glm::vec2& point) { return UNKNOWN_ENTITY_ID; } + if (QThread::currentThread() != thread()) { + QUuid result; + BLOCKING_INVOKE_METHOD(this, "getOverlayAtPoint", Q_RETURN_ARG(QUuid, result), Q_ARG(const glm::vec2&, point)); + return result; + } + QMutexLocker locker(&_mutex); QMapIterator i(_overlays); unsigned int bestStackOrder = 0; @@ -976,8 +984,7 @@ QUuid Overlays::getOverlayAtPoint(const glm::vec2& point) { while (i.hasNext()) { i.next(); auto thisOverlay = std::dynamic_pointer_cast(i.value()); - if (thisOverlay && thisOverlay->getVisible() && thisOverlay->isLoaded() && - thisOverlay->getBoundingRect().contains(point.x, point.y, false)) { + if (thisOverlay && thisOverlay->getVisible() && thisOverlay->getBoundingRect().contains(point.x, point.y, false)) { if (thisOverlay->getStackOrder() > bestStackOrder) { bestID = i.key(); bestStackOrder = thisOverlay->getStackOrder(); @@ -991,9 +998,7 @@ QUuid Overlays::getOverlayAtPoint(const glm::vec2& point) { QVariant Overlays::getProperty(const QUuid& id, const QString& property) { Overlay::Pointer overlay = get2DOverlay(id); if (overlay) { - if (overlay->supportsGetProperty()) { - return overlay->getProperty(property); - } + // We don't support getting properties from QML Overlays right now return QVariant(); } @@ -1009,12 +1014,8 @@ QVariantMap Overlays::getProperties(const QUuid& id, const QStringList& properti Overlay::Pointer overlay = get2DOverlay(id); QVariantMap result; if (overlay) { - if (overlay->supportsGetProperty()) { - for (const auto& property : properties) { - result.insert(property, overlay->getProperty(property)); - } - } - return result; + // We don't support getting properties from QML Overlays right now + return QVariantMap(); } QVariantMap overlayProperties = convertEntityToOverlayProperties(DependencyManager::get()->getEntityProperties(id)); @@ -1141,38 +1142,30 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R } 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(const QUuid&, id)); - return result; - } - Overlay::Pointer overlay = get2DOverlay(id); if (overlay) { - return overlay->isLoaded(); + return true; } return DependencyManager::get()->isLoaded(id); } 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(const QUuid&, id), Q_ARG(QString, text)); - return result; - } - Overlay::Pointer overlay = get2DOverlay(id); if (overlay) { + if (QThread::currentThread() != thread()) { + QSizeF result; + PROFILE_RANGE(script, __FUNCTION__); + BLOCKING_INVOKE_METHOD(this, "textSize", Q_RETURN_ARG(QSizeF, result), Q_ARG(const QUuid&, id), Q_ARG(QString, text)); + return result; + } if (auto textOverlay = std::dynamic_pointer_cast(overlay)) { return textOverlay->textSize(text); } return QSizeF(0.0f, 0.0f); - } else { - return DependencyManager::get()->textSize(id, text); } + + return DependencyManager::get()->textSize(id, text); } bool Overlays::isAddedOverlay(const QUuid& id) { diff --git a/interface/src/ui/overlays/QmlOverlay.cpp b/interface/src/ui/overlays/QmlOverlay.cpp index 537c421ca7..f301a23d49 100644 --- a/interface/src/ui/overlays/QmlOverlay.cpp +++ b/interface/src/ui/overlays/QmlOverlay.cpp @@ -57,29 +57,15 @@ QmlOverlay::~QmlOverlay() { // QmlOverlay replaces Overlay's properties with those defined in the QML file used but keeps Overlay2D's properties. void QmlOverlay::setProperties(const QVariantMap& properties) { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "setProperties", Q_ARG(QVariantMap, properties)); - return; - } - Overlay2D::setProperties(properties); - auto bounds = _bounds; + // check to see if qmlElement still exists if (_qmlElement) { - _qmlElement->setX(bounds.left()); - _qmlElement->setY(bounds.top()); - _qmlElement->setWidth(bounds.width()); - _qmlElement->setHeight(bounds.height()); + _qmlElement->setX(_bounds.left()); + _qmlElement->setY(_bounds.top()); + _qmlElement->setWidth(_bounds.width()); + _qmlElement->setHeight(_bounds.height()); + _qmlElement->setVisible(_visible); QMetaObject::invokeMethod(_qmlElement, "updatePropertiesFromScript", Qt::DirectConnection, Q_ARG(QVariant, properties)); } -} - -void QmlOverlay::render(RenderArgs* args) { - if (!_qmlElement) { - return; - } - - if (_visible != _qmlElement->isVisible()) { - _qmlElement->setVisible(_visible); - } -} +} \ No newline at end of file diff --git a/interface/src/ui/overlays/QmlOverlay.h b/interface/src/ui/overlays/QmlOverlay.h index 0951a04772..32badde28b 100644 --- a/interface/src/ui/overlays/QmlOverlay.h +++ b/interface/src/ui/overlays/QmlOverlay.h @@ -25,10 +25,8 @@ public: QmlOverlay(const QUrl& url, const QmlOverlay* overlay); ~QmlOverlay(); - bool supportsGetProperty() const override { return false; } - void setProperties(const QVariantMap& properties) override; - void render(RenderArgs* args) override; + void render(RenderArgs* args) override {} private: Q_INVOKABLE void qmlElementDestroyed(); From 9fe0309ae65d0ae2d42a48e43812935ebab6a752 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Thu, 28 Feb 2019 17:11:48 -0800 Subject: [PATCH 16/20] another login fix --- interface/src/Application.cpp | 8 +++++--- interface/src/Application.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ebc1176ee1..274d6919af 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4980,10 +4980,11 @@ void Application::idle() { } { - if (_keyboardFocusWaitingOnRenderable && getEntities()->renderableForEntityId(_keyboardFocusedEntity.get())) { - _keyboardFocusWaitingOnRenderable = false; - QUuid entityId = _keyboardFocusedEntity.get(); + if (_keyboardFocusWaitingOnRenderable && getEntities()->renderableForEntityId(_entityIdWaitingOnRenderable.get())) { + QUuid entityId = _entityIdWaitingOnRenderable.get(); + _entityIdWaitingOnRenderable.set(UNKNOWN_ENTITY_ID); setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); + _keyboardFocusWaitingOnRenderable = false; setKeyboardFocusEntity(entityId); } } @@ -5836,6 +5837,7 @@ void Application::setKeyboardFocusEntity(const QUuid& id) { auto entityItemRenderable = entities->renderableForEntityId(entityId); if (!entityItemRenderable) { _keyboardFocusWaitingOnRenderable = true; + _entityIdWaitingOnRenderable.set(id); } else if (entityItemRenderable->wantsKeyboardFocus()) { entities->setProxyWindow(entityId, _window->windowHandle()); if (_keyboardMouseDevice->isActive()) { diff --git a/interface/src/Application.h b/interface/src/Application.h index c16f260192..5e3090973a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -733,6 +733,7 @@ private: bool _reticleClickPressed { false }; bool _keyboardFocusWaitingOnRenderable { false }; + ThreadSafeValueCache _entityIdWaitingOnRenderable; int _avatarAttachmentRequest = 0; From 9a2bd87278e964f8623d7c5f2f7fdfde1e441834 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Thu, 28 Feb 2019 18:02:07 -0800 Subject: [PATCH 17/20] Fix for case when animated joints are missing from the target avatar skeleton By copying the animation rotations over to the target avatar in absolute frame, rather then relative, we can properly "combine" animated rotations that aren't in the target avatar skeleton. --- libraries/animation/src/AnimClip.cpp | 99 ++++++++++++++++-------- libraries/animation/src/AnimSkeleton.cpp | 11 +++ libraries/animation/src/AnimSkeleton.h | 1 + 3 files changed, 78 insertions(+), 33 deletions(-) diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index a35e0237d0..18e97cf0a1 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -95,57 +95,85 @@ void AnimClip::setCurrentFrameInternal(float frame) { _frame = ::accumulateTime(_startFrame, _endFrame, _timeScale, frame + _startFrame, dt, _loopFlag, _id, triggers); } +static std::vector buildJointIndexMap(const AnimSkeleton& dstSkeleton, const AnimSkeleton& srcSkeleton) { + std::vector jointIndexMap; + int srcJointCount = srcSkeleton.getNumJoints(); + jointIndexMap.reserve(srcJointCount); + for (int srcJointIndex = 0; srcJointIndex < srcJointCount; srcJointIndex++) { + QString srcJointName = srcSkeleton.getJointName(srcJointIndex); + int dstJointIndex = dstSkeleton.nameToJointIndex(srcJointName); + jointIndexMap.push_back(dstJointIndex); + } + return jointIndexMap; +} + void AnimClip::copyFromNetworkAnim() { assert(_networkAnim && _networkAnim->isLoaded() && _skeleton); _anim.clear(); auto avatarSkeleton = getSkeleton(); - - // build a mapping from animation joint indices to avatar joint indices. - // by matching joints with the same name. const HFMModel& animModel = _networkAnim->getHFMModel(); AnimSkeleton animSkeleton(animModel); const int animJointCount = animSkeleton.getNumJoints(); const int avatarJointCount = avatarSkeleton->getNumJoints(); - std::vector animToAvatarJointIndexMap; - animToAvatarJointIndexMap.reserve(animJointCount); - for (int animJointIndex = 0; animJointIndex < animJointCount; animJointIndex++) { - QString animJointName = animSkeleton.getJointName(animJointIndex); - int avatarJointIndex = avatarSkeleton->nameToJointIndex(animJointName); - animToAvatarJointIndexMap.push_back(avatarJointIndex); - } + + // build a mapping from animation joint indices to avatar joint indices by matching joints with the same name. + std::vector avatarToAnimJointIndexMap = buildJointIndexMap(animSkeleton, *avatarSkeleton); const int animFrameCount = animModel.animationFrames.size(); _anim.resize(animFrameCount); for (int frame = 0; frame < animFrameCount; frame++) { - const HFMAnimationFrame& animFrame = animModel.animationFrames[frame]; - // init all joints in animation to default pose - // this will give us a resonable result for bones in the avatar skeleton but not in the animation. - _anim[frame].reserve(avatarJointCount); - for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) { - _anim[frame].push_back(avatarSkeleton->getRelativeDefaultPose(avatarJointIndex)); + // extract the full rotations from the animFrame (including pre and post rotations from the animModel). + std::vector animRotations; + animRotations.reserve(animJointCount); + for (int i = 0; i < animJointCount; i++) { + animRotations.push_back(animModel.joints[i].preRotation * animFrame.rotations[i] * animModel.joints[i].postRotation); } - for (int animJointIndex = 0; animJointIndex < animJointCount; animJointIndex++) { - int avatarJointIndex = animToAvatarJointIndexMap[animJointIndex]; + // convert rotations into absolute frame + animSkeleton.convertRelativeRotationsToAbsolute(animRotations); - // skip joints that are in the animation but not in the avatar. - if (avatarJointIndex >= 0 && avatarJointIndex < avatarJointCount) { + // build absolute rotations for the avatar + std::vector avatarRotations; + avatarRotations.reserve(avatarJointCount); + for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) { + int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex]; + if (animJointIndex >= 0) { + // This joint is in both animation and avatar. + // Set the absolute rotation directly + avatarRotations.push_back(animRotations[animJointIndex]); + } else { + // This joint is NOT in the animation at all. + // Set it so that the default relative rotation remains unchanged. + glm::quat avatarRelativeDefaultRot = avatarSkeleton->getRelativeDefaultPose(avatarJointIndex).rot(); + glm::quat avatarParentAbsoluteRot; + int avatarParentJointIndex = avatarSkeleton->getParentIndex(avatarJointIndex); + if (avatarParentJointIndex >= 0) { + avatarParentAbsoluteRot = avatarRotations[avatarParentJointIndex]; + } + avatarRotations.push_back(avatarParentAbsoluteRot * avatarRelativeDefaultRot); + } + } + // convert avatar rotations into relative frame + avatarSkeleton->convertAbsoluteRotationsToRelative(avatarRotations); + + _anim[frame].reserve(avatarJointCount); + + for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) { + const AnimPose& avatarDefaultPose = avatarSkeleton->getRelativeDefaultPose(avatarJointIndex); + + // copy scale over from avatar default pose + glm::vec3 relativeScale = avatarDefaultPose.scale(); + + glm::vec3 relativeTranslation; + int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex]; + if (animJointIndex >= 0) { + // This joint is in both animation and avatar. const glm::vec3& animTrans = animFrame.translations[animJointIndex]; - const glm::quat& animRot = animFrame.rotations[animJointIndex]; - - const AnimPose& animPreRotPose = animSkeleton.getPreRotationPose(animJointIndex); - AnimPose animPostRotPose = animSkeleton.getPostRotationPose(animJointIndex); - AnimPose animRotPose(glm::vec3(1.0f), animRot, glm::vec3()); - - // adjust anim scale to equal the scale from the avatar joint. - // we do not support animated scale. - const AnimPose& avatarDefaultPose = avatarSkeleton->getRelativeDefaultPose(avatarJointIndex); - animPostRotPose.scale() = avatarDefaultPose.scale(); // retarget translation from animation to avatar const glm::vec3& animZeroTrans = animModel.animationFrames[0].translations[animJointIndex]; @@ -154,10 +182,15 @@ void AnimClip::copyFromNetworkAnim() { if (fabsf(glm::length(animZeroTrans)) > EPSILON) { boneLengthScale = glm::length(avatarDefaultPose.trans()) / glm::length(animZeroTrans); } - AnimPose animTransPose = AnimPose(glm::vec3(1.0f), glm::quat(), avatarDefaultPose.trans() + boneLengthScale * (animTrans - animZeroTrans)); - - _anim[frame][avatarJointIndex] = animTransPose * animPreRotPose * animRotPose * animPostRotPose; + relativeTranslation = avatarDefaultPose.trans() + boneLengthScale * (animTrans - animZeroTrans); + } else { + // This joint is NOT in the animation at all. + // preserve the default translation. + relativeTranslation = avatarDefaultPose.trans(); } + + // build the final pose + _anim[frame].push_back(AnimPose(relativeScale, avatarRotations[avatarJointIndex], relativeTranslation)); } } diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 03e3ac6ebd..993a2c6632 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -149,6 +149,17 @@ void AnimSkeleton::convertAbsolutePosesToRelative(AnimPoseVec& poses) const { } } +void AnimSkeleton::convertRelativeRotationsToAbsolute(std::vector& rotations) const { + // poses start off relative and leave in absolute frame + int lastIndex = std::min((int)rotations.size(), _jointsSize); + for (int i = 0; i < lastIndex; ++i) { + int parentIndex = _parentIndices[i]; + if (parentIndex != -1) { + rotations[i] = rotations[parentIndex] * rotations[i]; + } + } +} + void AnimSkeleton::convertAbsoluteRotationsToRelative(std::vector& rotations) const { // poses start off absolute and leave in relative frame int lastIndex = std::min((int)rotations.size(), _jointsSize); diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 0eefbf973e..5309d26354 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -54,6 +54,7 @@ public: void convertRelativePosesToAbsolute(AnimPoseVec& poses) const; void convertAbsolutePosesToRelative(AnimPoseVec& poses) const; + void convertRelativeRotationsToAbsolute(std::vector& rotations) const; void convertAbsoluteRotationsToRelative(std::vector& rotations) const; void saveNonMirroredPoses(const AnimPoseVec& poses) const; From 7bcf727a835cc446b1f917a130f80af45c1ddfd4 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Thu, 28 Feb 2019 18:11:51 -0800 Subject: [PATCH 18/20] review changes --- interface/src/Application.cpp | 6 ++---- interface/src/Application.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 274d6919af..248ada4376 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4980,9 +4980,8 @@ void Application::idle() { } { - if (_keyboardFocusWaitingOnRenderable && getEntities()->renderableForEntityId(_entityIdWaitingOnRenderable.get())) { - QUuid entityId = _entityIdWaitingOnRenderable.get(); - _entityIdWaitingOnRenderable.set(UNKNOWN_ENTITY_ID); + if (_keyboardFocusWaitingOnRenderable && getEntities()->renderableForEntityId(_keyboardFocusedEntity.get())) { + QUuid entityId = _keyboardFocusedEntity.get(); setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); _keyboardFocusWaitingOnRenderable = false; setKeyboardFocusEntity(entityId); @@ -5837,7 +5836,6 @@ void Application::setKeyboardFocusEntity(const QUuid& id) { auto entityItemRenderable = entities->renderableForEntityId(entityId); if (!entityItemRenderable) { _keyboardFocusWaitingOnRenderable = true; - _entityIdWaitingOnRenderable.set(id); } else if (entityItemRenderable->wantsKeyboardFocus()) { entities->setProxyWindow(entityId, _window->windowHandle()); if (_keyboardMouseDevice->isActive()) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 5e3090973a..c16f260192 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -733,7 +733,6 @@ private: bool _reticleClickPressed { false }; bool _keyboardFocusWaitingOnRenderable { false }; - ThreadSafeValueCache _entityIdWaitingOnRenderable; int _avatarAttachmentRequest = 0; From cfb84967d55748d2c24989149dfbb427f809a0f6 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 1 Mar 2019 10:54:44 -0800 Subject: [PATCH 19/20] these seemed dangerous --- .../ui/src/ui/TabletScriptingInterface.cpp | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index a78b9a17fc..7a1c37af33 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -458,6 +458,11 @@ void TabletProxy::emitWebEvent(const QVariant& msg) { } void TabletProxy::onTabletShown() { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "onTabletShown"); + return; + } + if (_tabletShown) { Setting::Handle notificationSounds{ QStringLiteral("play_notification_sounds"), true}; Setting::Handle notificationSoundTablet{ QStringLiteral("play_notification_sounds_tablet"), true}; @@ -485,7 +490,11 @@ bool TabletProxy::isPathLoaded(const QVariant& path) { } void TabletProxy::setQmlTabletRoot(OffscreenQmlSurface* qmlOffscreenSurface) { - Q_ASSERT(QThread::currentThread() == qApp->thread()); + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setQmlTabletRoot", Q_ARG(OffscreenQmlSurface*, qmlOffscreenSurface)); + return; + } + _qmlOffscreenSurface = qmlOffscreenSurface; _qmlTabletRoot = qmlOffscreenSurface ? qmlOffscreenSurface->getRootItem() : nullptr; if (_qmlTabletRoot && _qmlOffscreenSurface) { @@ -654,6 +663,11 @@ void TabletProxy::loadQMLSource(const QVariant& path, bool resizable) { } void TabletProxy::stopQMLSource() { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "stopQMLSource"); + return; + } + // For desktop toolbar mode dialogs. if (!_toolbarMode || !_desktopWindow) { qCDebug(uiLogging) << "tablet cannot clear QML because not desktop toolbar mode"; @@ -879,6 +893,12 @@ void TabletProxy::sendToQml(const QVariant& msg) { OffscreenQmlSurface* TabletProxy::getTabletSurface() { + if (QThread::currentThread() != thread()) { + OffscreenQmlSurface* result = nullptr; + BLOCKING_INVOKE_METHOD(this, "getTabletSurface", Q_RETURN_ARG(OffscreenQmlSurface*, result)); + return result; + } + return _qmlOffscreenSurface; } @@ -888,6 +908,11 @@ void TabletProxy::desktopWindowClosed() { } void TabletProxy::unfocus() { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "unfocus"); + return; + } + if (_qmlOffscreenSurface) { _qmlOffscreenSurface->lowerKeyboard(); } From 82b2050229bb0ad42d9ab3a16106fe0654ea4292 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Fri, 1 Mar 2019 11:13:56 -0800 Subject: [PATCH 20/20] code review feedback --- libraries/animation/src/AnimSkeleton.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 993a2c6632..0f1c18c9dc 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -150,7 +150,7 @@ void AnimSkeleton::convertAbsolutePosesToRelative(AnimPoseVec& poses) const { } void AnimSkeleton::convertRelativeRotationsToAbsolute(std::vector& rotations) const { - // poses start off relative and leave in absolute frame + // rotations start off relative and leave in absolute frame int lastIndex = std::min((int)rotations.size(), _jointsSize); for (int i = 0; i < lastIndex; ++i) { int parentIndex = _parentIndices[i]; @@ -161,7 +161,7 @@ void AnimSkeleton::convertRelativeRotationsToAbsolute(std::vector& ro } void AnimSkeleton::convertAbsoluteRotationsToRelative(std::vector& rotations) const { - // poses start off absolute and leave in relative frame + // rotations start off absolute and leave in relative frame int lastIndex = std::min((int)rotations.size(), _jointsSize); for (int i = lastIndex - 1; i >= 0; --i) { int parentIndex = _parentIndices[i];