diff --git a/CMakeLists.txt b/CMakeLists.txt index 3242d981ac..1555321c32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,6 +158,7 @@ option(GET_GLM "Get GLM library automatically as external project" 1) option(GET_GVERB "Get Gverb library automatically as external project" 1) option(GET_SOXR "Get Soxr library automatically as external project" 1) option(GET_TBB "Get Threading Building Blocks library automatically as external project" 1) +option(USE_NSIGHT "Attempt to find the nSight libraries" 1) if (WIN32) option(GET_GLEW "Get GLEW library automatically as external project" 1) diff --git a/examples/edit.js b/examples/edit.js index 7519f56c46..72938e5ed4 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -103,12 +103,24 @@ var isActive = false; var placingEntityID = null; -IMPORTING_SVO_OVERLAY_WIDTH = 130; +IMPORTING_SVO_OVERLAY_WIDTH = 144; IMPORTING_SVO_OVERLAY_HEIGHT = 30; -IMPORTING_SVO_OVERLAY_MARGIN = 6; -var importingSVOOverlay = Overlays.addOverlay("text", { +IMPORTING_SVO_OVERLAY_MARGIN = 5; +IMPORTING_SVO_OVERLAY_LEFT_MARGIN = 34; +var importingSVOImageOverlay = Overlays.addOverlay("image", { + imageURL: HIFI_PUBLIC_BUCKET + "images/hourglass.svg", + width: 20, + height: 20, + alpha: 1.0, + color: { red: 255, green: 255, blue: 255 }, + x: Window.innerWidth - IMPORTING_SVO_OVERLAY_WIDTH, + y: Window.innerHeight - IMPORTING_SVO_OVERLAY_HEIGHT, + visible: false, +}); +var importingSVOTextOverlay = Overlays.addOverlay("text", { font: { size: 14 }, text: "Importing SVO...", + leftMargin: IMPORTING_SVO_OVERLAY_LEFT_MARGIN, x: Window.innerWidth - IMPORTING_SVO_OVERLAY_WIDTH - IMPORTING_SVO_OVERLAY_MARGIN, y: Window.innerHeight - IMPORTING_SVO_OVERLAY_HEIGHT - IMPORTING_SVO_OVERLAY_MARGIN, width: IMPORTING_SVO_OVERLAY_WIDTH, @@ -754,6 +766,10 @@ function setupModelMenus() { afterItem: "Allow Selecting of Large Models", isCheckable: true, isChecked: true }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Allow Selecting of Lights", shortcutKey: "CTRL+SHIFT+META+L", afterItem: "Allow Selecting of Small Models", isCheckable: true }); + Menu.addMenuItem({ menuName: "Edit", menuItemName: "Select All Entities In Box", shortcutKey: "CTRL+SHIFT+META+A", + afterItem: "Allow Selecting of Lights" }); + Menu.addMenuItem({ menuName: "Edit", menuItemName: "Select All Entities Touching Box", shortcutKey: "CTRL+SHIFT+META+T", + afterItem: "Select All Entities In Box" }); Menu.addMenuItem({ menuName: "File", menuItemName: "Models", isSeparator: true, beforeItem: "Settings" }); Menu.addMenuItem({ menuName: "File", menuItemName: "Export Entities", shortcutKey: "CTRL+META+E", afterItem: "Models" }); @@ -783,6 +799,8 @@ function cleanupModelMenus() { Menu.removeMenuItem("Edit", "Allow Selecting of Large Models"); Menu.removeMenuItem("Edit", "Allow Selecting of Small Models"); Menu.removeMenuItem("Edit", "Allow Selecting of Lights"); + Menu.removeMenuItem("Edit", "Select All Entities In Box"); + Menu.removeMenuItem("Edit", "Select All Entities Touching Box"); Menu.removeSeparator("File", "Models"); Menu.removeMenuItem("File", "Export Entities"); @@ -807,7 +825,8 @@ Script.scriptEnding.connect(function() { selectionDisplay.cleanup(); Entities.setLightsArePickable(originalLightsArePickable); - Overlays.deleteOverlay(importingSVOOverlay); + Overlays.deleteOverlay(importingSVOImageOverlay); + Overlays.deleteOverlay(importingSVOTextOverlay); }); // Do some stuff regularly, like check for placement of various overlays @@ -817,6 +836,45 @@ Script.update.connect(function (deltaTime) { selectionDisplay.checkMove(); }); +function insideBox(center, dimensions, point) { + return (Math.abs(point.x - center.x) <= (dimensions.x / 2.0)) + && (Math.abs(point.y - center.y) <= (dimensions.y / 2.0)) + && (Math.abs(point.z - center.z) <= (dimensions.z / 2.0)); +} + +function selectAllEtitiesInCurrentSelectionBox(keepIfTouching) { + if (selectionManager.hasSelection()) { + // Get all entities touching the bounding box of the current selection + var boundingBoxCorner = Vec3.subtract(selectionManager.worldPosition, + Vec3.multiply(selectionManager.worldDimensions, 0.5)); + var entities = Entities.findEntitiesInBox(boundingBoxCorner, selectionManager.worldDimensions); + + if (!keepIfTouching) { + var isValid; + if (selectionManager.localPosition === null) { + isValid = function(position) { + return insideBox(selectionManager.worldPosition, selectionManager.worldDimensions, position); + } + } else { + isValid = function(position) { + var localPosition = Vec3.multiplyQbyV(Quat.inverse(selectionManager.localRotation), + Vec3.subtract(position, + selectionManager.localPosition)); + return insideBox({ x: 0, y: 0, z: 0 }, selectionManager.localDimensions, localPosition); + } + } + for (var i = 0; i < entities.length; ++i) { + var properties = Entities.getEntityProperties(entities[i]); + if (!isValid(properties.position)) { + entities.splice(i, 1); + --i; + } + } + } + selectionManager.setSelections(entities); + } +} + function deleteSelectedEntities() { if (SelectionManager.hasSelection()) { print(" Delete Entities"); @@ -875,6 +933,10 @@ function handeMenuEvent(menuItem) { } } else if (menuItem == "Entity List...") { entityListTool.toggleVisible(); + } else if (menuItem == "Select All Entities In Box") { + selectAllEtitiesInCurrentSelectionBox(false); + } else if (menuItem == "Select All Entities Touching Box") { + selectAllEtitiesInCurrentSelectionBox(true); } else if (menuItem == MENU_SHOW_LIGHTS_IN_EDIT_MODE) { lightOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_IN_EDIT_MODE)); } @@ -882,7 +944,8 @@ function handeMenuEvent(menuItem) { } function importSVO(importURL) { - Overlays.editOverlay(importingSVOOverlay, { visible: true }); + Overlays.editOverlay(importingSVOTextOverlay, { visible: true }); + Overlays.editOverlay(importingSVOImageOverlay, { visible: true }); var success = Clipboard.importEntities(importURL); @@ -907,7 +970,8 @@ function importSVO(importURL) { Window.alert("There was an error importing the entity file."); } - Overlays.editOverlay(importingSVOOverlay, { visible: false }); + Overlays.editOverlay(importingSVOTextOverlay, { visible: false }); + Overlays.editOverlay(importingSVOImageOverlay, { visible: false }); } Window.svoImportRequested.connect(importSVO); diff --git a/examples/users.js b/examples/users.js index d9da6c89ae..dec141127e 100644 --- a/examples/users.js +++ b/examples/users.js @@ -106,6 +106,9 @@ var usersWindow = (function () { var displayText = "", myUsername, user, + userText, + textWidth, + maxTextWidth, i; myUsername = GlobalServices.username; @@ -113,12 +116,27 @@ var usersWindow = (function () { for (i = 0; i < usersOnline.length; i += 1) { user = usersOnline[i]; if (user.username !== myUsername && user.online) { - usersOnline[i].usernameWidth = Overlays.textSize(windowPane2D, user.username).width; - linesOfUsers.push(i); - displayText += "\n" + user.username; + userText = user.username; if (user.location.root) { - displayText += " @ " + user.location.root.name; + userText += " @ " + user.location.root.name; } + textWidth = Overlays.textSize(windowPane2D, userText).width; + + maxTextWidth = WINDOW_WIDTH_2D - 2 * WINDOW_MARGIN_2D; + if (textWidth > maxTextWidth) { + // Trim and append "..." to fit window width + maxTextWidth = maxTextWidth - Overlays.textSize(windowPane2D, "...").width; + while (textWidth > maxTextWidth) { + userText = userText.slice(0, -1); + textWidth = Overlays.textSize(windowPane2D, userText).width; + } + userText += "..."; + textWidth = Overlays.textSize(windowPane2D, userText).width; + } + + usersOnline[i].textWidth = textWidth; + linesOfUsers.push(i); + displayText += "\n" + userText; } } @@ -253,7 +271,7 @@ var usersWindow = (function () { } if (0 <= lineClicked && lineClicked < linesOfUsers.length - && overlayX <= usersOnline[linesOfUsers[lineClicked]].usernameWidth) { + && 0 <= overlayX && overlayX <= usersOnline[linesOfUsers[lineClicked]].textWidth) { //print("Go to " + usersOnline[linesOfUsers[lineClicked]].username); location.goToUser(usersOnline[linesOfUsers[lineClicked]].username); } @@ -262,7 +280,7 @@ var usersWindow = (function () { visibilityChanged = false; for (i = 0; i < visibilityControls2D.length; i += 1) { // Don't need to test radioOverlay if it us under textOverlay. - if (clickedOverlay === visibilityControls2D[i].textOverlay) { + if (clickedOverlay === visibilityControls2D[i].textOverlay && event.x <= visibilityControls2D[i].optionWidth) { GlobalServices.findableBy = VISIBILITY_VALUES[i]; visibilityChanged = true; } @@ -286,7 +304,8 @@ var usersWindow = (function () { } function setUp() { - var textSizeOverlay; + var textSizeOverlay, + optionText; textSizeOverlay = Overlays.addOverlay("text", { font: WINDOW_FONT_2D, visible: false }); windowTextHeight = Math.floor(Overlays.textSize(textSizeOverlay, "1").height); @@ -351,6 +370,7 @@ var usersWindow = (function () { myVisibility = ""; } + optionText = "everyone"; visibilityControls2D = [{ radioOverlay: Overlays.addOverlay("image", { // Create first so that it is under textOverlay. x: WINDOW_MARGIN_2D, @@ -377,24 +397,34 @@ var usersWindow = (function () { color: WINDOW_HEADING_COLOR_2D, alpha: WINDOW_FOREGROUND_ALPHA_2D, backgroundAlpha: 0.0, - text: "everyone", + text: optionText, font: WINDOW_FONT_2D, visible: isVisible }), selected: myVisibility === VISIBILITY_VALUES[0] - } ]; + }]; + visibilityControls2D[0].optionWidth = WINDOW_MARGIN_2D + VISIBILITY_RADIO_SPACE + + Overlays.textSize(visibilityControls2D[0].textOverlay, optionText).width; + + optionText = "my friends"; visibilityControls2D[1] = { radioOverlay: Overlays.cloneOverlay(visibilityControls2D[0].radioOverlay), textOverlay: Overlays.cloneOverlay(visibilityControls2D[0].textOverlay), selected: myVisibility === VISIBILITY_VALUES[1] }; - Overlays.editOverlay(visibilityControls2D[1].textOverlay, { text: "my friends" }); + Overlays.editOverlay(visibilityControls2D[1].textOverlay, { text: optionText }); + visibilityControls2D[1].optionWidth = WINDOW_MARGIN_2D + VISIBILITY_RADIO_SPACE + + Overlays.textSize(visibilityControls2D[1].textOverlay, optionText).width; + + optionText = "no one"; visibilityControls2D[2] = { radioOverlay: Overlays.cloneOverlay(visibilityControls2D[0].radioOverlay), textOverlay: Overlays.cloneOverlay(visibilityControls2D[0].textOverlay), selected: myVisibility === VISIBILITY_VALUES[2] }; - Overlays.editOverlay(visibilityControls2D[2].textOverlay, { text: "no one" }); + Overlays.editOverlay(visibilityControls2D[2].textOverlay, { text: optionText }); + visibilityControls2D[2].optionWidth = WINDOW_MARGIN_2D + VISIBILITY_RADIO_SPACE + + Overlays.textSize(visibilityControls2D[2].textOverlay, optionText).width; updateVisibilityControls(); diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 62e12d88b1..dfe9689b27 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -220,15 +220,17 @@ else (APPLE) find_package(GLEW REQUIRED) target_include_directories(${TARGET_NAME} PRIVATE ${GLEW_INCLUDE_DIRS}) - target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARIES} ${NSIGHT_LIBRARIES} wsock32.lib opengl32.lib Winmm.lib) + target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARIES} wsock32.lib opengl32.lib Winmm.lib) - # try to find the Nsight package and add it to the build if we find it - find_package(NSIGHT) - if (NSIGHT_FOUND) - include_directories(${NSIGHT_INCLUDE_DIRS}) - add_definitions(-DNSIGHT_FOUND) - target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") - endif () + if (USE_NSIGHT) + # try to find the Nsight package and add it to the build if we find it + find_package(NSIGHT) + if (NSIGHT_FOUND) + include_directories(${NSIGHT_INCLUDE_DIRS}) + add_definitions(-DNSIGHT_FOUND) + target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") + endif () + endif() endif() endif (APPLE) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0c27ecb7de..184d1bf940 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2137,10 +2137,12 @@ void Application::updateCursor(float deltaTime) { } void Application::updateCursorVisibility() { - if (!_cursorVisible || Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode)) { - _glWidget->setCursor(Qt::BlankCursor); + if (!_cursorVisible || + Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode) || + Menu::getInstance()->isOptionChecked(MenuOption::Enable3DTVMode)) { + _window->setCursor(Qt::BlankCursor); } else { - _glWidget->unsetCursor(); + _window->unsetCursor(); } } diff --git a/interface/src/ui/DataWebPage.cpp b/interface/src/ui/DataWebPage.cpp index de97ab94a6..bec2c98f55 100644 --- a/interface/src/ui/DataWebPage.cpp +++ b/interface/src/ui/DataWebPage.cpp @@ -47,6 +47,6 @@ bool DataWebPage::acceptNavigationRequest(QWebFrame* frame, const QNetworkReques } } -QString DataWebPage::userAgentForUrl(const QUrl & url) const { - return INTERFACE_USER_AGENT; +QString DataWebPage::userAgentForUrl(const QUrl& url) const { + return HIGH_FIDELITY_USER_AGENT; } diff --git a/interface/src/ui/DataWebPage.h b/interface/src/ui/DataWebPage.h index 03c6781d05..c1c343a216 100644 --- a/interface/src/ui/DataWebPage.h +++ b/interface/src/ui/DataWebPage.h @@ -14,15 +14,13 @@ #include -const QString INTERFACE_USER_AGENT = "HighFidelityInterface/1.0"; - class DataWebPage : public QWebPage { public: DataWebPage(QObject* parent = 0); protected: void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID); bool acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, QWebPage::NavigationType type); - virtual QString userAgentForUrl(const QUrl & url) const; + virtual QString userAgentForUrl(const QUrl& url) const; }; #endif // hifi_DataWebPage_h diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 639798527a..2585b5d33e 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -204,8 +204,7 @@ EntityItemID EntityScriptingInterface::findClosestEntity(const glm::vec3& center const EntityItem* closestEntity = _entityTree->findClosestEntity(center, radius); _entityTree->unlock(); if (closestEntity) { - result.id = closestEntity->getID(); - result.isKnownID = true; + result = closestEntity->getEntityItemID(); } } return result; @@ -227,10 +226,25 @@ QVector EntityScriptingInterface::findEntities(const glm::vec3& ce QVector entities; _entityTree->findEntities(center, radius, entities); _entityTree->unlock(); - + foreach (const EntityItem* entity, entities) { - EntityItemID thisEntityItemID(entity->getID(), UNKNOWN_ENTITY_TOKEN, true); - result << thisEntityItemID; + result << entity->getEntityItemID(); + } + } + return result; +} + +QVector EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corner, const glm::vec3& dimensions) const { + QVector result; + if (_entityTree) { + _entityTree->lockForRead(); + AABox box(corner, dimensions); + QVector entities; + _entityTree->findEntities(box, entities); + _entityTree->unlock(); + + foreach (const EntityItem* entity, entities) { + result << entity->getEntityItemID(); } } return result; diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 9300149a98..5e75e2ae0d 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -87,10 +87,14 @@ public slots: /// will return a EntityItemID.isKnownID = false if no models are in the radius /// this function will not find any models in script engine contexts which don't have access to models Q_INVOKABLE EntityItemID findClosestEntity(const glm::vec3& center, float radius) const; - + /// finds models within the search sphere specified by the center point and radius /// this function will not find any models in script engine contexts which don't have access to models Q_INVOKABLE QVector findEntities(const glm::vec3& center, float radius) const; + + /// finds models within the search sphere specified by the center point and radius + /// this function will not find any models in script engine contexts which don't have access to models + Q_INVOKABLE QVector findEntitiesInBox(const glm::vec3& corner, const glm::vec3& dimensions) const; /// If the scripting context has visible entities, this will determine a ray intersection, the results /// may be inaccurate if the engine is unable to access the visible entities, in which case result.accurate diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index e5a7fbee2f..9be004828b 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -236,21 +236,28 @@ void EntityTree::setSimulation(EntitySimulation* simulation) { _simulation = simulation; } -void EntityTree::deleteEntity(const EntityItemID& entityID, bool force) { +void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ignoreWarnings) { EntityTreeElement* containingElement = getContainingElement(entityID); if (!containingElement) { - qDebug() << "UNEXPECTED!!!! EntityTree::deleteEntity() entityID doesn't exist!!! entityID=" << entityID; + if (!ignoreWarnings) { + qDebug() << "UNEXPECTED!!!! EntityTree::deleteEntity() entityID doesn't exist!!! entityID=" << entityID; + } return; } EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID); if (!existingEntity) { - qDebug() << "UNEXPECTED!!!! don't call EntityTree::deleteEntity() on entity items that don't exist. entityID=" << entityID; + if (!ignoreWarnings) { + qDebug() << "UNEXPECTED!!!! don't call EntityTree::deleteEntity() on entity items that don't exist. " + "entityID=" << entityID; + } return; } if (existingEntity->getLocked() && !force) { - qDebug() << "ERROR! EntityTree::deleteEntity() trying to delete locked entity. entityID=" << entityID; + if (!ignoreWarnings) { + qDebug() << "ERROR! EntityTree::deleteEntity() trying to delete locked entity. entityID=" << entityID; + } return; } @@ -263,24 +270,31 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force) { _isDirty = true; } -void EntityTree::deleteEntities(QSet entityIDs, bool force) { +void EntityTree::deleteEntities(QSet entityIDs, bool force, bool ignoreWarnings) { // NOTE: callers must lock the tree before using this method DeleteEntityOperator theOperator(this); foreach(const EntityItemID& entityID, entityIDs) { EntityTreeElement* containingElement = getContainingElement(entityID); if (!containingElement) { - qDebug() << "UNEXPECTED!!!! EntityTree::deleteEntities() entityID doesn't exist!!! entityID=" << entityID; + if (!ignoreWarnings) { + qDebug() << "UNEXPECTED!!!! EntityTree::deleteEntities() entityID doesn't exist!!! entityID=" << entityID; + } continue; } EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID); if (!existingEntity) { - qDebug() << "UNEXPECTED!!!! don't call EntityTree::deleteEntities() on entity items that don't exist. entityID=" << entityID; + if (!ignoreWarnings) { + qDebug() << "UNEXPECTED!!!! don't call EntityTree::deleteEntities() on entity items that don't exist. " + "entityID=" << entityID; + } continue; } if (existingEntity->getLocked() && !force) { - qDebug() << "ERROR! EntityTree::deleteEntities() trying to delete locked entity. entityID=" << entityID; + if (!ignoreWarnings) { + qDebug() << "ERROR! EntityTree::deleteEntities() trying to delete locked entity. entityID=" << entityID; + } continue; } @@ -528,6 +542,35 @@ void EntityTree::findEntities(const AACube& cube, QVector& foundEnt foundEntities.swap(args._foundEntities); } +class FindEntitiesInBoxArgs { +public: + FindEntitiesInBoxArgs(const AABox& box) + : _box(box), _foundEntities() { + } + + AABox _box; + QVector _foundEntities; +}; + +bool EntityTree::findInBoxOperation(OctreeElement* element, void* extraData) { + FindEntitiesInBoxArgs* args = static_cast(extraData); + if (element->getAACube().touches(args->_box)) { + EntityTreeElement* entityTreeElement = static_cast(element); + entityTreeElement->getEntities(args->_box, args->_foundEntities); + return true; + } + return false; +} + +// NOTE: assumes caller has handled locking +void EntityTree::findEntities(const AABox& box, QVector& foundEntities) { + FindEntitiesInBoxArgs args(box); + // NOTE: This should use recursion, since this is a spatial operation + recurseTreeWithOperation(findInBoxOperation, &args); + // swap the two lists of entity pointers instead of copy + foundEntities.swap(args._foundEntities); +} + EntityItem* EntityTree::findEntityByID(const QUuid& id) { EntityItemID entityID(id); return findEntityByEntityItemID(entityID); @@ -849,10 +892,9 @@ int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const Share EntityItemID entityItemID(entityID); entityItemIDsToDelete << entityItemID; } - deleteEntities(entityItemIDsToDelete); + deleteEntities(entityItemIDsToDelete, true, true); } unlock(); - return processedBytes; } @@ -889,7 +931,7 @@ int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, cons EntityItemID entityItemID(entityID); entityItemIDsToDelete << entityItemID; } - deleteEntities(entityItemIDsToDelete); + deleteEntities(entityItemIDsToDelete, true, true); } return processedBytes; } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 5126682a99..75a5daab4e 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -92,8 +92,8 @@ public: // use this method if you have a pointer to the entity (avoid an extra entity lookup) bool updateEntity(EntityItem* entity, const EntityItemProperties& properties, bool allowLockChange); - void deleteEntity(const EntityItemID& entityID, bool force = false); - void deleteEntities(QSet entityIDs, bool force = false); + void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = false); + void deleteEntities(QSet entityIDs, bool force = false, bool ignoreWarnings = false); void removeEntityFromSimulation(EntityItem* entity); /// \param position point of query in world-frame (meters) @@ -111,12 +111,18 @@ public: /// \param foundEntities[out] vector of const EntityItem* /// \remark Side effect: any initial contents in foundEntities will be lost void findEntities(const glm::vec3& center, float radius, QVector& foundEntities); - + /// finds all entities that touch a cube /// \param cube the query cube in world-frame (meters) /// \param foundEntities[out] vector of non-const EntityItem* /// \remark Side effect: any initial contents in entities will be lost void findEntities(const AACube& cube, QVector& foundEntities); + + /// finds all entities that touch a box + /// \param box the query box in world-frame (meters) + /// \param foundEntities[out] vector of non-const EntityItem* + /// \remark Side effect: any initial contents in entities will be lost + void findEntities(const AABox& box, QVector& foundEntities); void addNewlyCreatedHook(NewlyCreatedEntityHook* hook); void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook); @@ -173,6 +179,7 @@ private: static bool findNearPointOperation(OctreeElement* element, void* extraData); static bool findInSphereOperation(OctreeElement* element, void* extraData); static bool findInCubeOperation(OctreeElement* element, void* extraData); + static bool findInBoxOperation(OctreeElement* element, void* extraData); static bool sendEntitiesOperation(OctreeElement* element, void* extraData); void notifyNewlyCreatedEntity(const EntityItem& newEntity, const SharedNodePointer& senderNode); diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index b98ea961f9..0aaf8772a2 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -307,25 +307,14 @@ FBXGeometry readOBJ(QIODevice* device, const QVariantHash& mapping) { geometry.joints.resize(1); geometry.joints[0].isFree = false; - // geometry.joints[0].freeLineage; geometry.joints[0].parentIndex = -1; geometry.joints[0].distanceToParent = 0; geometry.joints[0].boneRadius = 0; geometry.joints[0].translation = glm::vec3(0, 0, 0); - // geometry.joints[0].preTransform = ; - geometry.joints[0].preRotation = glm::quat(1, 0, 0, 0); - geometry.joints[0].rotation = glm::quat(1, 0, 0, 0); - geometry.joints[0].postRotation = glm::quat(1, 0, 0, 0); - // geometry.joints[0].postTransform = ; - // geometry.joints[0].transform = ; geometry.joints[0].rotationMin = glm::vec3(0, 0, 0); geometry.joints[0].rotationMax = glm::vec3(0, 0, 0); - geometry.joints[0].inverseDefaultRotation = glm::quat(1, 0, 0, 0); - geometry.joints[0].inverseBindRotation = glm::quat(1, 0, 0, 0); - // geometry.joints[0].bindTransform = ; geometry.joints[0].name = "OBJ"; geometry.joints[0].shapePosition = glm::vec3(0, 0, 0); - geometry.joints[0].shapeRotation = glm::quat(1, 0, 0, 0); geometry.joints[0].shapeType = SPHERE_SHAPE; geometry.joints[0].isSkeletonJoint = true; @@ -343,11 +332,9 @@ FBXGeometry readOBJ(QIODevice* device, const QVariantHash& mapping) { // run through all the faces, look-up (or determine) a normal and set the normal for the points // that make up each face. QVector pointNormalsSums; - QVector pointNormalsCounts; mesh.normals.fill(glm::vec3(0,0,0), mesh.vertices.count()); pointNormalsSums.fill(glm::vec3(0,0,0), mesh.vertices.count()); - pointNormalsCounts.fill(0, mesh.vertices.count()); foreach (FBXMeshPart meshPart, mesh.parts) { int triCount = meshPart.triangleIndices.count() / 3; @@ -382,15 +369,13 @@ FBXGeometry readOBJ(QIODevice* device, const QVariantHash& mapping) { pointNormalsSums[p0Index] += n0; pointNormalsSums[p1Index] += n1; pointNormalsSums[p2Index] += n2; - pointNormalsCounts[p0Index]++; - pointNormalsCounts[p1Index]++; - pointNormalsCounts[p2Index]++; } int vertCount = mesh.vertices.count(); for (int i = 0; i < vertCount; i++) { - if (pointNormalsCounts[i] > 0) { - mesh.normals[i] = glm::normalize(pointNormalsSums[i] / (float)(pointNormalsCounts[i])); + float length = glm::length(pointNormalsSums[i]); + if (length > FLT_EPSILON) { + mesh.normals[i] = glm::normalize(pointNormalsSums[i]); } } diff --git a/libraries/gpu/CMakeLists.txt b/libraries/gpu/CMakeLists.txt index 4a23631dfb..30949b83e1 100644 --- a/libraries/gpu/CMakeLists.txt +++ b/libraries/gpu/CMakeLists.txt @@ -19,13 +19,15 @@ elseif (WIN32) target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARIES} opengl32.lib) - # try to find the Nsight package and add it to the build if we find it - find_package(NSIGHT) - if (NSIGHT_FOUND) - include_directories(${NSIGHT_INCLUDE_DIRS}) - add_definitions(-DNSIGHT_FOUND) - target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") - endif () + if (USE_NSIGHT) + # try to find the Nsight package and add it to the build if we find it + find_package(NSIGHT) + if (NSIGHT_FOUND) + include_directories(${NSIGHT_INCLUDE_DIRS}) + add_definitions(-DNSIGHT_FOUND) + target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") + endif () + endif() elseif (ANDROID) target_link_libraries(${TARGET_NAME} "-lGLESv3" "-lEGL") else () diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index f6abfa0d44..0458a5e912 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -27,8 +27,7 @@ const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager"; const QString SETTINGS_CURRENT_ADDRESS_KEY = "address"; -Setting::Handle currentAddressHandle(QStringList() << ADDRESS_MANAGER_SETTINGS_GROUP << "address"); - +Setting::Handle currentAddressHandle(QStringList() << ADDRESS_MANAGER_SETTINGS_GROUP << "address", DEFAULT_HIFI_ADDRESS); AddressManager::AddressManager() : _rootPlaceName(), diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index f09ff9bd72..9cf76dd1dc 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -68,7 +68,7 @@ static const quint64 USECS_PER_SECOND = USECS_PER_MSEC * MSECS_PER_SECOND; const int BITS_IN_BYTE = 8; // Use a custom User-Agent to avoid ModSecurity filtering, e.g. by hosting providers. -const QByteArray HIGH_FIDELITY_USER_AGENT = "Mozilla/5.0 (HighFidelity)"; +const QByteArray HIGH_FIDELITY_USER_AGENT = "Mozilla/5.0 (HighFidelityInterface)"; quint64 usecTimestampNow(bool wantDebug = false); void usecTimestampNowForceClockSkew(int clockSkew);