From 197662fd5e18c7a3a7b0c24d3fa7d3ca1f6cb086 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 27 Mar 2018 15:22:22 -0700 Subject: [PATCH 01/17] fix contextOverlay highlighing all entities --- interface/src/ui/overlays/ContextOverlayInterface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index dd05e5c6a8..f0c16fb977 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -254,7 +254,8 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveOverlay(const OverlayID& void ContextOverlayInterface::contextOverlays_hoverEnterEntity(const EntityItemID& entityID, const PointerEvent& event) { bool isMouse = event.getID() == PointerManager::MOUSE_POINTER_ID || DependencyManager::get()->isMouse(event.getID()); - if (contextOverlayFilterPassed(entityID) && _enabled && !isMouse) { + if (_currentEntityWithContextOverlay == entityID && contextOverlayFilterPassed(entityID) + && _enabled && !isMouse) { enableEntityHighlight(entityID); } } From cb07fc47dc58e86c4982105a04e02e721dfb60db Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 27 Mar 2018 13:27:02 -0700 Subject: [PATCH 02/17] Fix ESS remote method calls for connect only users --- .../src/scripts/EntityScriptServer.cpp | 9 +---- domain-server/src/DomainServer.cpp | 38 +------------------ 2 files changed, 4 insertions(+), 43 deletions(-) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 1255c18e71..d242b393bf 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -105,8 +105,6 @@ EntityScriptServer::~EntityScriptServer() { static const QString ENTITY_SCRIPT_SERVER_LOGGING_NAME = "entity-script-server"; void EntityScriptServer::handleReloadEntityServerScriptPacket(QSharedPointer message, SharedNodePointer senderNode) { - // These are temporary checks until we can ensure that nodes eventually disconnect if the Domain Server stops telling them - // about each other. if (senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified()) { auto entityID = QUuid::fromRfc4122(message->read(NUM_BYTES_RFC4122_UUID)); @@ -119,8 +117,6 @@ void EntityScriptServer::handleReloadEntityServerScriptPacket(QSharedPointer message, SharedNodePointer senderNode) { - // These are temporary checks until we can ensure that nodes eventually disconnect if the Domain Server stops telling them - // about each other. if (senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified()) { MessageID messageID; message->readPrimitive(&messageID); @@ -190,15 +186,14 @@ void EntityScriptServer::updateEntityPPS() { } void EntityScriptServer::handleEntityServerScriptLogPacket(QSharedPointer message, SharedNodePointer senderNode) { - // These are temporary checks until we can ensure that nodes eventually disconnect if the Domain Server stops telling them - // about each other. + bool canRezAny = senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified(); bool enable = false; message->readPrimitive(&enable); auto senderUUID = senderNode->getUUID(); auto it = _logListeners.find(senderUUID); - if (enable && senderNode->getCanRez()) { + if (enable && canRezAny) { if (it == std::end(_logListeners)) { _logListeners.insert(senderUUID); qCInfo(entity_script_server) << "Node" << senderUUID << "subscribed to log stream"; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 197ac7eac2..dbf2907cc0 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1042,41 +1042,7 @@ void DomainServer::processListRequestPacket(QSharedPointer mess bool DomainServer::isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB) { auto nodeAData = static_cast(nodeA->getLinkedData()); - auto nodeBData = static_cast(nodeB->getLinkedData()); - - // if we have no linked data for node A then B can't possibly be in the interest set - if (!nodeAData) { - return false; - } - - // first check if the general interest set A contains the type for B - if (nodeAData->getNodeInterestSet().contains(nodeB->getType())) { - // given that there is a match in the general interest set, do any special checks - - // (1/19/17) Agents only need to connect to Entity Script Servers to perform administrative tasks - // related to entity server scripts. Only agents with rez permissions should be doing that, so - // if the agent does not have those permissions, we do not want them and the server to incur the - // overhead of connecting to one another. Additionally we exclude agents that do not care about the - // Entity Script Server and won't attempt to connect to it. - - bool isAgentWithoutRights = nodeA->getType() == NodeType::Agent - && nodeB->getType() == NodeType::EntityScriptServer - && !nodeA->getCanRez() && !nodeA->getCanRezTmp() - && !nodeA->getCanRezCertified() && !nodeA->getCanRezTmpCertified(); - - if (isAgentWithoutRights) { - return false; - } - - bool isScriptServerForIneffectiveAgent = - (nodeA->getType() == NodeType::EntityScriptServer && nodeB->getType() == NodeType::Agent) - && ((nodeBData && !nodeBData->getNodeInterestSet().contains(NodeType::EntityScriptServer)) - || (!nodeB->getCanRez() && !nodeB->getCanRezTmp() && !nodeB->getCanRezCertified() && !nodeB->getCanRezTmpCertified())); - - return !isScriptServerForIneffectiveAgent; - } else { - return false; - } + return nodeAData && nodeAData->getNodeInterestSet().contains(nodeB->getType()); } unsigned int DomainServer::countConnectedUsers() { @@ -3476,4 +3442,4 @@ void DomainServer::handleOctreeFileReplacementRequest(QSharedPointergetCanReplaceContent()) { handleOctreeFileReplacement(message->readAll()); } -} \ No newline at end of file +} From 35ee1bec09963cc27135512eaa2a82a085fd295d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 28 Mar 2018 14:47:09 -0700 Subject: [PATCH 03/17] fix cmake changes for script copy for dev builds --- interface/CMakeLists.txt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index e316556d29..fe00d86c3a 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -312,7 +312,7 @@ if (APPLE) COMPONENT ${CLIENT_COMPONENT} ) - set(RESOURCES_INSTALL_DIR "${INTERFACE_INSTALL_APP_PATH}/Contents/Resources") + set(SCRIPTS_INSTALL_DIR "${INTERFACE_INSTALL_APP_PATH}/Contents/Resources") set(RESOURCES_DEV_DIR "$/../Resources") # copy script files beside the executable @@ -326,13 +326,14 @@ if (APPLE) fixup_interface() else() - set(RESOURCES_DEV_DIR "$/resources") + set(INTERFACE_EXEC_DIR "$") + set(RESOURCES_DEV_DIR "${INTERFACE_EXEC_DIR}/resources") # copy the resources files beside the executable add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${RESOURCES_RCC}" - "$" + "${INTERFACE_EXEC_DIR}" # FIXME, the edit script code loads HTML from the scripts folder # which in turn relies on CSS that refers to the fonts. In theory # we should be able to modify the CSS to reference the QRC path to @@ -340,13 +341,13 @@ else() # so we have to retain a copy of the fonts outside of the resources binary COMMAND "${CMAKE_COMMAND}" -E copy_directory "${PROJECT_SOURCE_DIR}/resources/fonts" - "$/resources/fonts" + "${RESOURCES_DEV_DIR}/fonts" COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_SOURCE_DIR}/scripts" - "${RESOURCES_DEV_DIR}/scripts" + "${INTERFACE_EXEC_DIR}/scripts" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${PROJECT_SOURCE_DIR}/resources/serverless/tutorial.json" - "$/resources/serverless/tutorial.json" + "${RESOURCES_DEV_DIR}/serverless/tutorial.json" ) # link target to external libraries @@ -363,7 +364,7 @@ else() PATTERN "*.exp" EXCLUDE ) - set(RESOURCES_INSTALL_DIR "${INTERFACE_INSTALL_DIR}") + set(SCRIPTS_INSTALL_DIR "${INTERFACE_INSTALL_DIR}") set(EXECUTABLE_COMPONENT ${CLIENT_COMPONENT}) @@ -371,11 +372,11 @@ else() endif() endif() -if (RESOURCES_INSTALL_DIR) +if (SCRIPTS_INSTALL_DIR) # setup install of scripts beside interface executable install( DIRECTORY "${CMAKE_SOURCE_DIR}/scripts/" - DESTINATION ${RESOURCES_INSTALL_DIR}/scripts + DESTINATION ${SCRIPTS_INSTALL_DIR}/scripts COMPONENT ${CLIENT_COMPONENT} ) endif() From 8cdb59413d7c3ad06d90a082239261756990ecf5 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 29 Mar 2018 09:26:05 -0700 Subject: [PATCH 04/17] fix-qml-confict --- interface/resources/qml/{AudioScope.qml => AudioScopeUI.qml} | 1 + scripts/developer/utilities/audio/audioScope.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) rename interface/resources/qml/{AudioScope.qml => AudioScopeUI.qml} (99%) diff --git a/interface/resources/qml/AudioScope.qml b/interface/resources/qml/AudioScopeUI.qml similarity index 99% rename from interface/resources/qml/AudioScope.qml rename to interface/resources/qml/AudioScopeUI.qml index aa181dbf8d..b009c249bc 100644 --- a/interface/resources/qml/AudioScope.qml +++ b/interface/resources/qml/AudioScopeUI.qml @@ -12,6 +12,7 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import "styles-uit" import "controls-uit" as HifiControlsUit +import "." as HifiRoot Item { id: root diff --git a/scripts/developer/utilities/audio/audioScope.js b/scripts/developer/utilities/audio/audioScope.js index 00c9e4b725..63cbf0a6e2 100644 --- a/scripts/developer/utilities/audio/audioScope.js +++ b/scripts/developer/utilities/audio/audioScope.js @@ -1,4 +1,4 @@ -var qml = Script.resourcesPath() + '/qml/AudioScope.qml'; +var qml = Script.resourcesPath() + '/qml/AudioScopeUI.qml'; var window = new OverlayWindow({ title: 'Audio Scope', source: qml, @@ -14,4 +14,4 @@ window.closed.connect(function () { AudioScope.setServerEcho(false); AudioScope.selectAudioScopeFiveFrames(); Script.stop(); -}); \ No newline at end of file +}); From 0bdf26faaf321d09d9501830862aafd778d7adcc Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 29 Mar 2018 09:29:01 -0700 Subject: [PATCH 05/17] minimize diff --- interface/resources/qml/AudioScopeUI.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/resources/qml/AudioScopeUI.qml b/interface/resources/qml/AudioScopeUI.qml index b009c249bc..aa181dbf8d 100644 --- a/interface/resources/qml/AudioScopeUI.qml +++ b/interface/resources/qml/AudioScopeUI.qml @@ -12,7 +12,6 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import "styles-uit" import "controls-uit" as HifiControlsUit -import "." as HifiRoot Item { id: root From afe39aba46b9c69e3ba6a4c6981f8f8da37c5ac1 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 28 Mar 2018 13:47:31 -0700 Subject: [PATCH 06/17] fix octal code char issue --- libraries/entities/src/EntityTree.cpp | 6 +++--- libraries/entities/src/UpdateEntityOperator.cpp | 2 +- libraries/shared/src/OctalCode.cpp | 6 +++--- libraries/shared/src/OctalCode.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 75f024d0b9..2cf66911a4 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -425,8 +425,8 @@ bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperti if (!childEntity) { continue; } - EntityTreeElementPointer containingElement = childEntity->getElement(); - if (!containingElement) { + EntityTreeElementPointer childContainingElement = childEntity->getElement(); + if (!childContainingElement) { continue; } @@ -440,7 +440,7 @@ bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperti addToNeedsParentFixupList(childEntity); } - UpdateEntityOperator theChildOperator(getThisPointer(), containingElement, childEntity, queryCube); + UpdateEntityOperator theChildOperator(getThisPointer(), childContainingElement, childEntity, queryCube); recurseTreeWithOperator(&theChildOperator); foreach (SpatiallyNestablePointer childChild, childEntity->getChildren()) { if (childChild && childChild->getNestableType() == NestableType::Entity) { diff --git a/libraries/entities/src/UpdateEntityOperator.cpp b/libraries/entities/src/UpdateEntityOperator.cpp index fa7e5ca38f..32bd2f06ba 100644 --- a/libraries/entities/src/UpdateEntityOperator.cpp +++ b/libraries/entities/src/UpdateEntityOperator.cpp @@ -288,7 +288,7 @@ OctreeElementPointer UpdateEntityOperator::possiblyCreateChildAt(const OctreeEle int indexOfChildContainingNewEntity = element->getMyChildContaining(_newEntityBox); if (childIndex == indexOfChildContainingNewEntity) { - return element->addChildAtIndex(childIndex);; + return element->addChildAtIndex(childIndex); } } } diff --git a/libraries/shared/src/OctalCode.cpp b/libraries/shared/src/OctalCode.cpp index 1a0a19bf44..ae4338be6f 100644 --- a/libraries/shared/src/OctalCode.cpp +++ b/libraries/shared/src/OctalCode.cpp @@ -46,7 +46,7 @@ void printOctalCode(const unsigned char* octalCode) { } char sectionValue(const unsigned char* startByte, char startIndexInByte) { - char rightShift = 8 - startIndexInByte - 3; + int8_t rightShift = 8 - startIndexInByte - 3; if (rightShift < 0) { return ((startByte[0] << -rightShift) & 7) + (startByte[1] >> (8 + rightShift)); @@ -73,7 +73,7 @@ int branchIndexWithDescendant(const unsigned char* ancestorOctalCode, const unsi return sectionValue(descendantOctalCode + 1 + (branchStartBit / 8), branchStartBit % 8); } -unsigned char* childOctalCode(const unsigned char* parentOctalCode, char childNumber) { +unsigned char* childOctalCode(const unsigned char* parentOctalCode, int childNumber) { // find the length (in number of three bit code sequences) // in the parent @@ -111,7 +111,7 @@ unsigned char* childOctalCode(const unsigned char* parentOctalCode, char childNu // calculate the amount of left shift required // this will be -1 or -2 if there's wrap - char leftShift = 8 - (startBit % 8) - 3; + int8_t leftShift = 8 - (startBit % 8) - 3; if (leftShift < 0) { // we have a wrap-around to accomodate diff --git a/libraries/shared/src/OctalCode.h b/libraries/shared/src/OctalCode.h index a0d86f32d2..89c5e6d74e 100644 --- a/libraries/shared/src/OctalCode.h +++ b/libraries/shared/src/OctalCode.h @@ -30,7 +30,7 @@ using OctalCodePtrList = std::vector; void printOctalCode(const unsigned char* octalCode); size_t bytesRequiredForCodeLength(unsigned char threeBitCodes); int branchIndexWithDescendant(const unsigned char* ancestorOctalCode, const unsigned char* descendantOctalCode); -unsigned char* childOctalCode(const unsigned char* parentOctalCode, char childNumber); +unsigned char* childOctalCode(const unsigned char* parentOctalCode, int childNumber); const int OVERFLOWED_OCTCODE_BUFFER = -1; const int UNKNOWN_OCTCODE_LENGTH = -2; From dcfebde54a7ea2f66b2abd1f2abb5ac205b9dfe5 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 29 Mar 2018 10:50:43 -0700 Subject: [PATCH 07/17] put back the pre serverless-domain behavior for when a json file is dragged-and-dropped into the interface window -- import the json rather than load as a serverless-domain --- interface/src/Application.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7e6c65f8f4..af0ac5bc78 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6275,8 +6275,9 @@ bool Application::canAcceptURL(const QString& urlString) const { bool Application::acceptURL(const QString& urlString, bool defaultUpload) { QUrl url(urlString); - if (isDomainURL(url)) { - // this is a URL for a domain, either hifi:// or serverless - have the AddressManager handle it + + if (url.scheme() == URL_SCHEME_HIFI) { + // this is a hifi URL - have the AddressManager handle it QMetaObject::invokeMethod(DependencyManager::get().data(), "handleLookupString", Qt::AutoConnection, Q_ARG(const QString&, urlString)); return true; From e738274e907f3243a3da7e5da64fc22784b1288a Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 29 Mar 2018 11:10:39 -0700 Subject: [PATCH 08/17] map flying down back to C key --- interface/resources/controllers/keyboardMouse.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/controllers/keyboardMouse.json b/interface/resources/controllers/keyboardMouse.json index 174f9af7d7..660bc281e3 100644 --- a/interface/resources/controllers/keyboardMouse.json +++ b/interface/resources/controllers/keyboardMouse.json @@ -114,7 +114,7 @@ { "from": "Keyboard.W", "when": "!Keyboard.Control", "to": "Actions.LONGITUDINAL_FORWARD" }, { "from": "Keyboard.S", "when": "!Keyboard.Control", "to": "Actions.LONGITUDINAL_BACKWARD" }, { "from": "Keyboard.Shift", "when": ["!Keyboard.Left", "!Keyboard.Right"], "to": "Actions.SPRINT" }, - { "from": "Keyboard.Control", "to": "Actions.VERTICAL_DOWN" }, + { "from": "Keyboard.C", "to": "Actions.VERTICAL_DOWN" }, { "from": "Keyboard.Left", "when": "Keyboard.Shift", "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.Right", "when": "Keyboard.Shift", "to": "Actions.LATERAL_RIGHT" }, { "from": "Keyboard.Up", "when": "Application.CameraFirstPerson", "to": "Actions.LONGITUDINAL_FORWARD" }, From 5a7e9d8e3eb185e086f674b5d5984adf3d5e8457 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 30 Mar 2018 09:48:04 -0700 Subject: [PATCH 09/17] fix shadows on primitives --- libraries/entities-renderer/src/RenderableShapeEntityItem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index b05854da4e..feb88bed4b 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -131,6 +131,8 @@ ItemKey ShapeEntityRenderer::getKey() { withReadLock([&] { if (isTransparent()) { builder.withTransparent(); + } else if (_canCastShadow) { + builder.withShadowCaster(); } }); From c99676b51010245393fbc2bff31e1c51a1053653 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 30 Mar 2018 13:44:54 -0700 Subject: [PATCH 10/17] atlernate fix for selected entities --- interface/src/raypick/LaserPointer.cpp | 70 +++++++++++++------ interface/src/raypick/LaserPointer.h | 1 + .../ui/overlays/ContextOverlayInterface.cpp | 3 +- libraries/pointers/src/Pointer.cpp | 5 +- libraries/pointers/src/Pointer.h | 1 + 5 files changed, 53 insertions(+), 27 deletions(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index a4fe516590..7b99c37679 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -81,6 +81,50 @@ void LaserPointer::editRenderState(const std::string& state, const QVariant& sta }); } +PickResultPointer LaserPointer::getVisualPickResult(const PickResultPointer& pickResult) { + PickResultPointer visualPickResult = pickResult; + auto rayPickResult = std::static_pointer_cast(visualPickResult); + IntersectionType type = rayPickResult ? rayPickResult->type : IntersectionType::NONE; + + if (type != IntersectionType::HUD) { + if (!_lockEndObject.id.isNull()) { + PickRay pickRay = rayPickResult ? PickRay(rayPickResult->pickVariant) : PickRay(); + glm::vec3 endVec; + glm::vec3 pos; + glm::quat rot; + glm::vec3 dim; + glm::vec3 registrationPoint; + if (_lockEndObject.isOverlay) { + pos = vec3FromVariant(qApp->getOverlays().getProperty(_lockEndObject.id, "position").value); + rot = quatFromVariant(qApp->getOverlays().getProperty(_lockEndObject.id, "rotation").value); + dim = vec3FromVariant(qApp->getOverlays().getProperty(_lockEndObject.id, "dimensions").value); + registrationPoint = glm::vec3(0.5f); + } else { + EntityItemProperties props = DependencyManager::get()->getEntityProperties(_lockEndObject.id); + glm::mat4 entityMat = createMatFromQuatAndPos(props.getRotation(), props.getPosition()); + glm::mat4 finalPosAndRotMat = entityMat * _lockEndObject.offsetMat; + pos = extractTranslation(finalPosAndRotMat); + rot = glmExtractRotation(finalPosAndRotMat); + dim = props.getDimensions(); + registrationPoint = props.getRegistrationPoint(); + } + const glm::vec3 DEFAULT_REGISTRATION_POINT = glm::vec3(0.5f); + endVec = pos + rot * (dim * (DEFAULT_REGISTRATION_POINT - registrationPoint)); + glm::vec3 direction = endVec - pickRay.origin; + float distance = glm::distance(pickRay.origin, endVec); + glm::vec3 normalizedDirection = glm::normalize(direction); + + rayPickResult->type = _lockEndObject.isOverlay ? IntersectionType::OVERLAY : IntersectionType::ENTITY; + rayPickResult->objectID = _lockEndObject.id; + rayPickResult->intersection = endVec; + rayPickResult->distance = distance; + rayPickResult->surfaceNormal = -normalizedDirection; + rayPickResult->pickVariant["direction"] = vec3toVariant(normalizedDirection); + } + } + return visualPickResult; +} + void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& props) { if (!id.isNull() && props.isValid()) { QVariantMap propMap = props.toMap(); @@ -102,26 +146,7 @@ void LaserPointer::updateRenderState(const RenderState& renderState, const Inter endVec = pickRay.origin + pickRay.direction * distance; } else { if (!_lockEndObject.id.isNull()) { - glm::vec3 pos; - glm::quat rot; - glm::vec3 dim; - glm::vec3 registrationPoint; - if (_lockEndObject.isOverlay) { - pos = vec3FromVariant(qApp->getOverlays().getProperty(_lockEndObject.id, "position").value); - rot = quatFromVariant(qApp->getOverlays().getProperty(_lockEndObject.id, "rotation").value); - dim = vec3FromVariant(qApp->getOverlays().getProperty(_lockEndObject.id, "dimensions").value); - registrationPoint = glm::vec3(0.5f); - } else { - EntityItemProperties props = DependencyManager::get()->getEntityProperties(_lockEndObject.id); - glm::mat4 entityMat = createMatFromQuatAndPos(props.getRotation(), props.getPosition()); - glm::mat4 finalPosAndRotMat = entityMat * _lockEndObject.offsetMat; - pos = extractTranslation(finalPosAndRotMat); - rot = glmExtractRotation(finalPosAndRotMat); - dim = props.getDimensions(); - registrationPoint = props.getRegistrationPoint(); - } - const glm::vec3 DEFAULT_REGISTRATION_POINT = glm::vec3(0.5f); - endVec = pos + rot * (dim * (DEFAULT_REGISTRATION_POINT - registrationPoint)); + endVec = pickRay.origin + pickRay.direction * distance; } else { if (type == IntersectionType::ENTITY) { endVec = DependencyManager::get()->getEntityTransform(objectID)[3]; @@ -132,7 +157,6 @@ void LaserPointer::updateRenderState(const RenderState& renderState, const Inter } } } - QVariant end = vec3toVariant(endVec); if (!renderState.getPathID().isNull()) { QVariantMap pathProps; @@ -195,7 +219,7 @@ void LaserPointer::updateVisuals(const PickResultPointer& pickResult) { IntersectionType type = rayPickResult ? rayPickResult->type : IntersectionType::NONE; if (_enabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && (type != IntersectionType::NONE || _laserLength > 0.0f || !_lockEndObject.id.isNull())) { - PickRay pickRay(rayPickResult->pickVariant); + PickRay pickRay = rayPickResult ? PickRay(rayPickResult->pickVariant): PickRay(); QUuid uid = rayPickResult->objectID; float distance = _laserLength > 0.0f ? _laserLength : rayPickResult->distance; updateRenderState(_renderStates[_currentRenderState], type, distance, uid, pickRay, false); @@ -386,4 +410,4 @@ glm::vec2 LaserPointer::findPos2D(const PickedObject& pickedObject, const glm::v default: return glm::vec2(NAN); } -} \ No newline at end of file +} diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index efc5c02729..78c84e5f80 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -82,6 +82,7 @@ public: protected: PointerEvent buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult, const std::string& button = "", bool hover = true) override; + PickResultPointer getVisualPickResult(const PickResultPointer& pickResult) override; PickedObject getHoveredObject(const PickResultPointer& pickResult) override; Pointer::Buttons getPressedButtons(const PickResultPointer& pickResult) override; diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index f0c16fb977..dd05e5c6a8 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -254,8 +254,7 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveOverlay(const OverlayID& void ContextOverlayInterface::contextOverlays_hoverEnterEntity(const EntityItemID& entityID, const PointerEvent& event) { bool isMouse = event.getID() == PointerManager::MOUSE_POINTER_ID || DependencyManager::get()->isMouse(event.getID()); - if (_currentEntityWithContextOverlay == entityID && contextOverlayFilterPassed(entityID) - && _enabled && !isMouse) { + if (contextOverlayFilterPassed(entityID) && _enabled && !isMouse) { enableEntityHighlight(entityID); } } diff --git a/libraries/pointers/src/Pointer.cpp b/libraries/pointers/src/Pointer.cpp index 5307e17355..031baece5f 100644 --- a/libraries/pointers/src/Pointer.cpp +++ b/libraries/pointers/src/Pointer.cpp @@ -68,8 +68,9 @@ void Pointer::update(unsigned int pointerID) { // This only needs to be a read lock because update won't change any of the properties that can be modified from scripts withReadLock([&] { auto pickResult = getPrevPickResult(); - updateVisuals(pickResult); - generatePointerEvents(pointerID, pickResult); + auto visualPickResult = getVisualPickResult(pickResult); + updateVisuals(visualPickResult); + generatePointerEvents(pointerID, visualPickResult); }); } diff --git a/libraries/pointers/src/Pointer.h b/libraries/pointers/src/Pointer.h index 3197c80cad..0c842dbd88 100644 --- a/libraries/pointers/src/Pointer.h +++ b/libraries/pointers/src/Pointer.h @@ -89,6 +89,7 @@ protected: virtual bool shouldHover(const PickResultPointer& pickResult) { return true; } virtual bool shouldTrigger(const PickResultPointer& pickResult) { return true; } + virtual PickResultPointer getVisualPickResult(const PickResultPointer& pickResult) { return pickResult; }; static const float POINTER_MOVE_DELAY; static const float TOUCH_PRESS_TO_MOVE_DEADSPOT_SQUARED; From 16749df83a4e931769389e80fb7f731e61be739d Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 30 Mar 2018 14:14:13 -0700 Subject: [PATCH 11/17] fix highlighting edge case --- .../controllers/controllerModules/farActionGrabEntity.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 09cea58cea..b20712eacd 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -14,7 +14,7 @@ PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic, getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI - Picks, makeLaserLockInfo Xform, makeLaserParams, AddressManager, getEntityParents + Picks, makeLaserLockInfo Xform, makeLaserParams, AddressManager, getEntityParents, Selection */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -467,8 +467,10 @@ Script.include("/~/system/libraries/Xform.js"); Script.clearTimeout(this.contextOverlayTimer); } this.contextOverlayTimer = false; - if (entityID !== this.entityWithContextOverlay) { + if (entityID === this.entityWithContextOverlay) { this.destroyContextOverlay(); + } else { + Selection.removeFromSelectedItemsList("contextOverlayHighlightList", "entity", entityID); } var targetEntity = this.targetObject.getTargetEntity(); From 4b7e2cb331c13aee070b9e5b6cb5401a3a672b20 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 30 Mar 2018 15:15:17 -0700 Subject: [PATCH 12/17] made requested changes --- interface/src/raypick/LaserPointer.cpp | 43 +++++++++++++------------- interface/src/raypick/LaserPointer.h | 2 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 7b99c37679..011b9e55e6 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -87,9 +87,9 @@ PickResultPointer LaserPointer::getVisualPickResult(const PickResultPointer& pic IntersectionType type = rayPickResult ? rayPickResult->type : IntersectionType::NONE; if (type != IntersectionType::HUD) { + glm::vec3 endVec; + PickRay pickRay = rayPickResult ? PickRay(rayPickResult->pickVariant) : PickRay(); if (!_lockEndObject.id.isNull()) { - PickRay pickRay = rayPickResult ? PickRay(rayPickResult->pickVariant) : PickRay(); - glm::vec3 endVec; glm::vec3 pos; glm::quat rot; glm::vec3 dim; @@ -120,6 +120,21 @@ PickResultPointer LaserPointer::getVisualPickResult(const PickResultPointer& pic rayPickResult->distance = distance; rayPickResult->surfaceNormal = -normalizedDirection; rayPickResult->pickVariant["direction"] = vec3toVariant(normalizedDirection); + } else if (_lockEnd) { + if (type == IntersectionType::ENTITY) { + endVec = DependencyManager::get()->getEntityTransform(rayPickResult->objectID)[3]; + } else if (type == IntersectionType::OVERLAY) { + endVec = vec3FromVariant(qApp->getOverlays().getProperty(rayPickResult->objectID, "position").value); + } else if (type == IntersectionType::AVATAR) { + endVec = DependencyManager::get()->getAvatar(rayPickResult->objectID)->getPosition(); + } + glm::vec3 direction = endVec - pickRay.origin; + float distance = glm::distance(pickRay.origin, endVec); + glm::vec3 normalizedDirection = glm::normalize(direction); + rayPickResult->intersection = endVec; + rayPickResult->distance = distance; + rayPickResult->surfaceNormal = -normalizedDirection; + rayPickResult->pickVariant["direction"] = vec3toVariant(normalizedDirection); } } return visualPickResult; @@ -133,7 +148,7 @@ void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& } } -void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, float distance, const QUuid& objectID, const PickRay& pickRay, bool defaultState) { +void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, float distance, const QUuid& objectID, const PickRay& pickRay) { if (!renderState.getStartID().isNull()) { QVariantMap startProps; startProps.insert("position", vec3toVariant(pickRay.origin)); @@ -141,22 +156,8 @@ void LaserPointer::updateRenderState(const RenderState& renderState, const Inter startProps.insert("ignoreRayIntersection", renderState.doesStartIgnoreRays()); qApp->getOverlays().editOverlay(renderState.getStartID(), startProps); } - glm::vec3 endVec; - if (((defaultState || !_lockEnd) && _lockEndObject.id.isNull()) || type == IntersectionType::HUD) { - endVec = pickRay.origin + pickRay.direction * distance; - } else { - if (!_lockEndObject.id.isNull()) { - endVec = pickRay.origin + pickRay.direction * distance; - } else { - if (type == IntersectionType::ENTITY) { - endVec = DependencyManager::get()->getEntityTransform(objectID)[3]; - } else if (type == IntersectionType::OVERLAY) { - endVec = vec3FromVariant(qApp->getOverlays().getProperty(objectID, "position").value); - } else if (type == IntersectionType::AVATAR) { - endVec = DependencyManager::get()->getAvatar(objectID)->getPosition(); - } - } - } + glm::vec3 endVec = pickRay.origin + pickRay.direction * distance; + QVariant end = vec3toVariant(endVec); if (!renderState.getPathID().isNull()) { QVariantMap pathProps; @@ -222,12 +223,12 @@ void LaserPointer::updateVisuals(const PickResultPointer& pickResult) { PickRay pickRay = rayPickResult ? PickRay(rayPickResult->pickVariant): PickRay(); QUuid uid = rayPickResult->objectID; float distance = _laserLength > 0.0f ? _laserLength : rayPickResult->distance; - updateRenderState(_renderStates[_currentRenderState], type, distance, uid, pickRay, false); + updateRenderState(_renderStates[_currentRenderState], type, distance, uid, pickRay); disableRenderState(_defaultRenderStates[_currentRenderState].second); } else if (_enabled && !_currentRenderState.empty() && _defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { disableRenderState(_renderStates[_currentRenderState]); PickRay pickRay = rayPickResult ? PickRay(rayPickResult->pickVariant) : PickRay(); - updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), pickRay, true); + updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), pickRay); } else if (!_currentRenderState.empty()) { disableRenderState(_renderStates[_currentRenderState]); disableRenderState(_defaultRenderStates[_currentRenderState].second); diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 78c84e5f80..964881be42 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -103,7 +103,7 @@ private: LockEndObject _lockEndObject; void updateRenderStateOverlay(const OverlayID& id, const QVariant& props); - void updateRenderState(const RenderState& renderState, const IntersectionType type, float distance, const QUuid& objectID, const PickRay& pickRay, bool defaultState); + void updateRenderState(const RenderState& renderState, const IntersectionType type, float distance, const QUuid& objectID, const PickRay& pickRay); void disableRenderState(const RenderState& renderState); struct TriggerState { From d5496d68fd84456c2abb96e0c338345e4510b172 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 30 Mar 2018 16:58:41 -0700 Subject: [PATCH 13/17] FIx the mac crash when in front of a mirror by using the VIewFrustum stack correctly --- libraries/render-utils/src/AntialiasingEffect.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index 4a9b69c099..ba5036ad68 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -380,6 +380,8 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const batch.setResourceTexture(AntialiasingPass_VelocityMapSlot, nullptr); batch.setResourceTexture(AntialiasingPass_NextMapSlot, nullptr); }); + + args->popViewFrustum(); } @@ -520,7 +522,7 @@ void JitterSample::run(const render::RenderContextPointer& renderContext) { viewFrustum.setProjection(projMat); viewFrustum.calculate(); - args->setViewFrustum(viewFrustum); + args->pushViewFrustum(viewFrustum); } else { mat4 projMats[2]; args->_context->getStereoProjections(projMats); @@ -538,4 +540,4 @@ void JitterSample::run(const render::RenderContextPointer& renderContext) { } -#endif \ No newline at end of file +#endif From a9a53c7d64249d8d78e188efc4411063d3fa3013 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 2 Apr 2018 10:51:39 -0700 Subject: [PATCH 14/17] make resquested changes --- interface/src/raypick/LaserPointer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 011b9e55e6..bd71e47cf0 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -120,7 +120,7 @@ PickResultPointer LaserPointer::getVisualPickResult(const PickResultPointer& pic rayPickResult->distance = distance; rayPickResult->surfaceNormal = -normalizedDirection; rayPickResult->pickVariant["direction"] = vec3toVariant(normalizedDirection); - } else if (_lockEnd) { + } else if (type != IntersectionType::NONE && _lockEnd) { if (type == IntersectionType::ENTITY) { endVec = DependencyManager::get()->getEntityTransform(rayPickResult->objectID)[3]; } else if (type == IntersectionType::OVERLAY) { From ccea3efe1e1d0714303d9c7aff54dc7a13db7b2c Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Mon, 2 Apr 2018 00:23:25 +0300 Subject: [PATCH 15/17] FB13789 - Log in/Sign up dialog is missing "Forgot Username?" and "Forgot Password?" links --- interface/resources/qml/controls-uit/TextField.qml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/controls-uit/TextField.qml b/interface/resources/qml/controls-uit/TextField.qml index f94541897b..6743d08275 100644 --- a/interface/resources/qml/controls-uit/TextField.qml +++ b/interface/resources/qml/controls-uit/TextField.qml @@ -163,10 +163,18 @@ TextField { text: textField.label colorScheme: textField.colorScheme anchors.left: parent.left - anchors.right: parent.right + + Binding on anchors.right { + when: parent.right + value: parent.right + } + Binding on wrapMode { + when: parent.right + value: Text.WordWrap + } + anchors.bottom: parent.top anchors.bottomMargin: 3 - wrapMode: Text.WordWrap visible: label != "" } } From 08b7326bd18d38d611a55e4ba59fd4be85ef2372 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 3 Apr 2018 11:11:51 -0700 Subject: [PATCH 16/17] when moving a group of selections, don't move a child if a parent is being moved --- scripts/system/libraries/entitySelectionTool.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index fced5fc4e9..4fc767634b 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1618,8 +1618,16 @@ SelectionDisplay = (function() { grid.snapToGrid(Vec3.sum(cornerPosition, vector), constrainMajorOnly), cornerPosition); - for (var i = 0; i < SelectionManager.selections.length; i++) { - var properties = SelectionManager.savedProperties[SelectionManager.selections[i]]; + var toMove = SelectionManager.selections.filter(function (selection) { + if (SelectionManager.selections.indexOf(SelectionManager.savedProperties[selection].parentID) >= 0) { + return false; // a parent is also being moved, so don't issue an edit for this entity + } else { + return true; + } + }); + + for (var i = 0; i < toMove.length; i++) { + var properties = SelectionManager.savedProperties[toMove[i]]; if (!properties) { continue; } @@ -1628,7 +1636,7 @@ SelectionDisplay = (function() { y: 0, z: vector.z }); - Entities.editEntity(SelectionManager.selections[i], { + Entities.editEntity(toMove[i], { position: newPosition }); From 249a97b5d0e474f3197c17d263910bbbdf3104ce Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 3 Apr 2018 12:02:12 -0700 Subject: [PATCH 17/17] don't move or rotate children if a parent is being changed by the same action --- .../system/libraries/entitySelectionTool.js | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 4fc767634b..c84ecef722 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1618,6 +1618,8 @@ SelectionDisplay = (function() { grid.snapToGrid(Vec3.sum(cornerPosition, vector), constrainMajorOnly), cornerPosition); + // editing a parent will cause all the children to automatically follow along, so don't + // edit any entity who has an ancestor in SelectionManager.selections var toMove = SelectionManager.selections.filter(function (selection) { if (SelectionManager.selections.indexOf(SelectionManager.savedProperties[selection].parentID) >= 0) { return false; // a parent is also being moved, so don't issue an edit for this entity @@ -1735,9 +1737,19 @@ SelectionDisplay = (function() { Vec3.print(" newIntersection:", newIntersection); Vec3.print(" vector:", vector); } - - for (var i = 0; i < SelectionManager.selections.length; i++) { - var id = SelectionManager.selections[i]; + + // editing a parent will cause all the children to automatically follow along, so don't + // edit any entity who has an ancestor in SelectionManager.selections + var toMove = SelectionManager.selections.filter(function (selection) { + if (SelectionManager.selections.indexOf(SelectionManager.savedProperties[selection].parentID) >= 0) { + return false; // a parent is also being moved, so don't issue an edit for this entity + } else { + return true; + } + }); + + for (var i = 0; i < toMove.length; i++) { + var id = toMove[i]; var properties = SelectionManager.savedProperties[id]; var newPosition = Vec3.sum(properties.position, vector); Entities.editEntity(id, { position: newPosition }); @@ -2174,8 +2186,19 @@ SelectionDisplay = (function() { // the selections center point. Otherwise, the rotation will be around the entities // registration point which does not need repositioning. var reposition = (SelectionManager.selections.length > 1); - for (var i = 0; i < SelectionManager.selections.length; i++) { - var entityID = SelectionManager.selections[i]; + + // editing a parent will cause all the children to automatically follow along, so don't + // edit any entity who has an ancestor in SelectionManager.selections + var toRotate = SelectionManager.selections.filter(function (selection) { + if (SelectionManager.selections.indexOf(SelectionManager.savedProperties[selection].parentID) >= 0) { + return false; // a parent is also being moved, so don't issue an edit for this entity + } else { + return true; + } + }); + + for (var i = 0; i < toRotate.length; i++) { + var entityID = toRotate[i]; var initialProperties = SelectionManager.savedProperties[entityID]; var newProperties = {