diff --git a/CMakeLists.txt b/CMakeLists.txt index b7c0a24863..16eed7b0fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets") project(hifi) add_definitions(-DGLM_FORCE_RADIANS) +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") if (WIN32) add_definitions(-DNOMINMAX -D_CRT_SECURE_NO_WARNINGS) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 7cca9d3ef5..266183745f 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "../AssignmentClient.h" @@ -252,7 +253,7 @@ OctreeServer::OctreeServer(const QByteArray& packet) : // make sure the AccountManager has an Auth URL for payment redemptions - AccountManager::getInstance().setAuthURL(DEFAULT_NODE_AUTH_URL); + AccountManager::getInstance().setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); } OctreeServer::~OctreeServer() { diff --git a/cmake/externals/tbb/CMakeLists.txt b/cmake/externals/tbb/CMakeLists.txt index ad46196b95..b9b2b65010 100644 --- a/cmake/externals/tbb/CMakeLists.txt +++ b/cmake/externals/tbb/CMakeLists.txt @@ -13,16 +13,28 @@ if (ANDROID) BUILD_COMMAND ${NDK_BUILD_COMMAND} --directory=jni target=android tbb tbbmalloc arch=arm BUILD_IN_SOURCE 1 CONFIGURE_COMMAND "" - INSTALL_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/AndroidTBBLibCopy.cmake + INSTALL_COMMAND ${CMAKE_COMMAND} -DTBB_LIBS_SUFFIX=so -P ${CMAKE_CURRENT_SOURCE_DIR}/TBBLibCopy.cmake + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 + ) +elseif (APPLE) + find_program(MAKE_COMMAND NAMES make DOC "Path to the make command") + + ExternalProject_Add( + ${EXTERNAL_NAME} + URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_src.tgz + URL_MD5 bf090eaa86cf89ea014b7b462786a440 + BUILD_COMMAND ${MAKE_COMMAND} tbb_os=macos + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + INSTALL_COMMAND ${CMAKE_COMMAND} -DTBB_LIBS_SUFFIX=dylib -P ${CMAKE_CURRENT_SOURCE_DIR}/TBBLibCopy.cmake LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 ) else () - if (APPLE) - set(DOWNLOAD_URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_osx.tgz) - set(DOWNLOAD_MD5 25a36ebff070ff801760ec658079f6aa) - elseif (WIN32) + if (WIN32) set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150316oss_win.zip) set(DOWNLOAD_MD5 d250d40bb93b255f75bcbb19e976a440) else () @@ -46,7 +58,7 @@ ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) if (APPLE) - set(_TBB_LIB_DIR "${SOURCE_DIR}/lib/libc++") + set(_TBB_LIB_DIR "${SOURCE_DIR}/lib") set(_LIB_PREFIX "lib") set(_LIB_EXT "dylib") @@ -95,14 +107,8 @@ elseif (UNIX) endif () if (DEFINED _TBB_LIB_DIR) - if (NOT APPLE) - set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb_debug.${_LIB_EXT} CACHE FILEPATH "TBB debug library location") - set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc_debug.${_LIB_EXT} CACHE FILEPATH "TBB malloc debug library location") - else () - set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE FILEPATH "TBB debug library location") - set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_DEBUG "" CACHE FILEPATH "TBB malloc debug library location") - endif () - + set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb_debug.${_LIB_EXT} CACHE FILEPATH "TBB debug library location") + set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc_debug.${_LIB_EXT} CACHE FILEPATH "TBB malloc debug library location") set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb.${_LIB_EXT} CACHE FILEPATH "TBB release library location") set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc.${_LIB_EXT} CACHE FILEPATH "TBB malloc release library location") endif () diff --git a/cmake/externals/tbb/OSXTBBInstallNameChange.cmake b/cmake/externals/tbb/OSXTBBInstallNameChange.cmake index c263ed7d2e..cc4df46812 100644 --- a/cmake/externals/tbb/OSXTBBInstallNameChange.cmake +++ b/cmake/externals/tbb/OSXTBBInstallNameChange.cmake @@ -10,9 +10,11 @@ # # first find the so files in the source dir -set(_TBB_LIBRARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/libc++) +set(_TBB_LIBRARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib) file(GLOB_RECURSE _TBB_LIBRARIES "${_TBB_LIBRARY_DIR}/*.dylib") +message(${_TBB_LIBRARIES}) + # raise an error if we found none if (NOT _TBB_LIBRARIES) message(FATAL_ERROR "Did not find any TBB libraries") @@ -28,20 +30,6 @@ find_program(LIPO_COMMAND NAMES lipo DOC "Path to the lipo command") foreach(_TBB_LIBRARY ${_TBB_LIBRARIES}) get_filename_component(_TBB_LIBRARY_FILENAME ${_TBB_LIBRARY} NAME) - set(_LIPO_ARGS -remove i386 ${_TBB_LIBRARY_FILENAME} -output ${_TBB_LIBRARY_FILENAME}) - message(STATUS "${LIPO_COMMAND} ${_LIPO_ARGS}") - - # first we use lipo to remove i386 from each dylib - execute_process( - COMMAND ${LIPO_COMMAND} ${_LIPO_ARGS} - WORKING_DIRECTORY ${_TBB_LIBRARY_DIR} - ERROR_VARIABLE _LIPO_ERROR - ) - - if (_LIPO_ERROR) - message(FATAL_ERROR "There was an error removing i386 for ${_TBB_LIBRARY_FILENAME} - ${_LIPO_ERROR}") - endif () - set(_INSTALL_NAME_ARGS ${INSTALL_NAME_TOOL_COMMAND} -id ${_TBB_LIBRARY} ${_TBB_LIBRARY_FILENAME}) message(STATUS "${INSTALL_NAME_COMMAND} ${_INSTALL_NAME_ARGS}") diff --git a/cmake/externals/tbb/AndroidTBBLibCopy.cmake b/cmake/externals/tbb/TBBLibCopy.cmake similarity index 94% rename from cmake/externals/tbb/AndroidTBBLibCopy.cmake rename to cmake/externals/tbb/TBBLibCopy.cmake index 1c7697ab54..8f5423750b 100644 --- a/cmake/externals/tbb/AndroidTBBLibCopy.cmake +++ b/cmake/externals/tbb/TBBLibCopy.cmake @@ -1,5 +1,5 @@ # -# AndroidTBBLibCopy.cmake +# TBBLibCopy.cmake # cmake/externals/tbb # # Copyright 2015 High Fidelity, Inc. @@ -10,7 +10,7 @@ # # first find the so files in the source dir -file(GLOB_RECURSE _TBB_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/build/*.so") +file(GLOB_RECURSE _TBB_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/build/*.${TBB_LIBS_SUFFIX}") # raise an error if we found none if (NOT _TBB_LIBRARIES) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 0918b85a63..263444f30a 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -181,7 +182,7 @@ bool DomainServer::optionallySetupOAuth() { // if we don't have an oauth provider URL then we default to the default node auth url if (_oauthProviderURL.isEmpty()) { - _oauthProviderURL = DEFAULT_NODE_AUTH_URL; + _oauthProviderURL = NetworkingConstants::METAVERSE_SERVER_URL; } AccountManager& accountManager = AccountManager::getInstance(); diff --git a/examples/blocks.js b/examples/blocks.js index 30c2126096..7bc52824db 100644 --- a/examples/blocks.js +++ b/examples/blocks.js @@ -43,8 +43,8 @@ var floor = Entities.addEntity( var edge1 = Entities.addEntity( { type: "Box", position: Vec3.sum(center, { x: FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }), - dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE }, - color: { red: 128, green: 128, blue: 128 }, + dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE + EDGE_THICKESS }, + color: { red: 100, green: 100, blue: 100 }, gravity: { x: 0, y: 0, z: 0 }, ignoreCollisions: false, visible: true, @@ -54,8 +54,8 @@ var edge1 = Entities.addEntity( var edge2 = Entities.addEntity( { type: "Box", position: Vec3.sum(center, { x: -FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }), - dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE }, - color: { red: 128, green: 128, blue: 128 }, + dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE + EDGE_THICKESS }, + color: { red: 100, green: 100, blue: 100 }, gravity: { x: 0, y: 0, z: 0 }, ignoreCollisions: false, visible: true, @@ -65,8 +65,8 @@ var edge2 = Entities.addEntity( var edge3 = Entities.addEntity( { type: "Box", position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: -FLOOR_SIZE / 2.0 }), - dimensions: { x: FLOOR_SIZE, y: EDGE_THICKESS, z: EDGE_THICKESS }, - color: { red: 128, green: 128, blue: 128 }, + dimensions: { x: FLOOR_SIZE + EDGE_THICKESS, y: EDGE_THICKESS, z: EDGE_THICKESS }, + color: { red: 100, green: 100, blue: 100 }, gravity: { x: 0, y: 0, z: 0 }, ignoreCollisions: false, visible: true, @@ -76,8 +76,8 @@ var edge3 = Entities.addEntity( var edge4 = Entities.addEntity( { type: "Box", position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: FLOOR_SIZE / 2.0 }), - dimensions: { x: FLOOR_SIZE, y: EDGE_THICKESS, z: EDGE_THICKESS }, - color: { red: 128, green: 128, blue: 128 }, + dimensions: { x: FLOOR_SIZE + EDGE_THICKESS, y: EDGE_THICKESS, z: EDGE_THICKESS }, + color: { red: 100, green: 100, blue: 100 }, gravity: { x: 0, y: 0, z: 0 }, ignoreCollisions: false, visible: true, @@ -97,6 +97,7 @@ for (var i = 0; i < NUM_BLOCKS; i++) { dimensions: { x: type.x * SCALE, y: type.y * SCALE, z: type.z * SCALE }, color: { red: type.red, green: type.green, blue: type.blue }, gravity: { x: 0, y: GRAVITY, z: 0 }, + velocity: { x: 0, y: 0.05, z: 0 }, ignoreCollisions: false, damping: DAMPING, lifetime: LIFETIME, @@ -104,6 +105,11 @@ for (var i = 0; i < NUM_BLOCKS; i++) { } function scriptEnding() { + Entities.editEntity(edge1, { locked: false }); + Entities.editEntity(edge2, { locked: false }); + Entities.editEntity(edge3, { locked: false }); + Entities.editEntity(edge4, { locked: false }); + Entities.editEntity(floor, { locked: false }); Entities.deleteEntity(edge1); Entities.deleteEntity(edge2); Entities.deleteEntity(edge3); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 572fb8ab17..109e865030 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -136,6 +137,13 @@ #include "ui/StandAloneJSConsole.h" #include "ui/Stats.h" +// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU +#if defined(Q_OS_WIN) +extern "C" { + _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; +} +#endif + using namespace std; // Starfield information @@ -418,7 +426,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle); // set the account manager's root URL and trigger a login request if we don't have the access token - accountManager.setAuthURL(DEFAULT_NODE_AUTH_URL); + accountManager.setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); UserActivityLogger::getInstance().launch(applicationVersion()); // once the event loop has started, check and signal for an access token @@ -646,6 +654,11 @@ void Application::initializeGL() { } #endif + qDebug() << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); + qDebug() << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); + qDebug() << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR)); + qDebug() << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER)); + #ifdef WIN32 GLenum err = glewInit(); if (GLEW_OK != err) { diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 3a61f69dee..dc5427ab48 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -685,6 +685,10 @@ void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) { * joint.preTransform * glm::mat4_cast(modifiedRotation) * joint.postTransform; } + // Each joint contributes its point to the bounding box + glm::vec3 jointPosition = extractTranslation(transforms[i]); + totalExtents.addPoint(jointPosition); + Shape* shape = _shapes[i]; if (!shape) { continue; @@ -694,8 +698,6 @@ void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) { // that contains the sphere centered at the end of the joint with radius of the bone. // TODO: skip hand and arm shapes for bounding box calculation - glm::vec3 jointPosition = extractTranslation(transforms[i]); - int type = shape->getType(); if (type == CAPSULE_SHAPE) { // add the two furthest surface points of the capsule diff --git a/interface/src/ui/DataWebDialog.cpp b/interface/src/ui/DataWebDialog.cpp index e28dcf8df7..f405ef50c5 100644 --- a/interface/src/ui/DataWebDialog.cpp +++ b/interface/src/ui/DataWebDialog.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include "Application.h" #include "DataWebPage.h" @@ -39,7 +39,7 @@ DataWebDialog* DataWebDialog::dialogForPath(const QString& path, connect(dialogWebView->page()->mainFrame(), &QWebFrame::javaScriptWindowObjectCleared, dialogWebView, &DataWebDialog::addJavascriptObjectsToWindow); - QUrl dataWebUrl(DEFAULT_NODE_AUTH_URL); + QUrl dataWebUrl(NetworkingConstants::METAVERSE_SERVER_URL); dataWebUrl.setPath(path); qDebug() << "Opening a data web dialog for" << dataWebUrl.toString(); diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index 4e7a4a7dc9..690489fdb2 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include "Application.h" @@ -23,7 +24,7 @@ #include "LoginDialog.h" #include "UIUtil.h" -const QString FORGOT_PASSWORD_URL = "https://metaverse.highfidelity.com/users/password/new"; +const QString FORGOT_PASSWORD_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/users/password/new"; LoginDialog::LoginDialog(QWidget* parent) : FramelessDialog(parent, 0, FramelessDialog::POSITION_TOP), diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 2b65081185..2353a20e7d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -61,7 +61,7 @@ void RenderableModelEntityItem::remapTextures() { } if (!_model->isLoadedWithTextures()) { - return; // nothing to do if the model has not yet loaded it's default textures + return; // nothing to do if the model has not yet loaded its default textures } if (!_originalTexturesRead && _model->isLoadedWithTextures()) { @@ -220,7 +220,7 @@ Model* RenderableModelEntityItem::getModel(EntityTreeRenderer* renderer) { // if we have a URL, then we will want to end up returning a model... if (!getModelURL().isEmpty()) { - // if we have a previously allocated model, but it's URL doesn't match + // if we have a previously allocated model, but its URL doesn't match // then we need to let our renderer update our model for us. if (_model && QUrl(getModelURL()) != _model->getURL()) { result = _model = _myRenderer->updateModel(_model, getModelURL(), getCollisionModelURL()); @@ -293,7 +293,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() { } if (_model->getCollisionURL().isEmpty()) { - // no model url, so we're ready to compute a shape. + // no collision-model url, so we're ready to compute a shape (of type None). return true; } @@ -312,35 +312,30 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { info.setParams(getShapeType(), 0.5f * getDimensions()); } else { const QSharedPointer collisionNetworkGeometry = _model->getCollisionGeometry(); - const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry(); + const FBXGeometry& collisionGeometry = collisionNetworkGeometry->getFBXGeometry(); + + const QSharedPointer renderNetworkGeometry = _model->getGeometry(); + const FBXGeometry& renderGeometry = renderNetworkGeometry->getFBXGeometry(); - AABox aaBox; _points.clear(); unsigned int i = 0; // the way OBJ files get read, each section under a "g" line is its own meshPart. We only expect // to find one actual "mesh" (with one or more meshParts in it), but we loop over the meshes, just in case. - foreach (const FBXMesh& mesh, fbxGeometry.meshes) { + foreach (const FBXMesh& mesh, collisionGeometry.meshes) { // each meshPart is a convex hull foreach (const FBXMeshPart &meshPart, mesh.parts) { QVector pointsInPart; // run through all the triangles and (uniquely) add each point to the hull unsigned int triangleCount = meshPart.triangleIndices.size() / 3; - assert((unsigned int)meshPart.triangleIndices.size() == triangleCount*3); for (unsigned int j = 0; j < triangleCount; j++) { unsigned int p0Index = meshPart.triangleIndices[j*3]; unsigned int p1Index = meshPart.triangleIndices[j*3+1]; unsigned int p2Index = meshPart.triangleIndices[j*3+2]; - assert(p0Index < (unsigned int)mesh.vertices.size()); - assert(p1Index < (unsigned int)mesh.vertices.size()); - assert(p2Index < (unsigned int)mesh.vertices.size()); glm::vec3 p0 = mesh.vertices[p0Index]; glm::vec3 p1 = mesh.vertices[p1Index]; glm::vec3 p2 = mesh.vertices[p2Index]; - aaBox += p0; - aaBox += p1; - aaBox += p2; if (!pointsInPart.contains(p0)) { pointsInPart << p0; } @@ -360,18 +355,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { unsigned int p1Index = meshPart.quadIndices[j*4+1]; unsigned int p2Index = meshPart.quadIndices[j*4+2]; unsigned int p3Index = meshPart.quadIndices[j*4+3]; - assert(p0Index < (unsigned int)mesh.vertices.size()); - assert(p1Index < (unsigned int)mesh.vertices.size()); - assert(p2Index < (unsigned int)mesh.vertices.size()); - assert(p3Index < (unsigned int)mesh.vertices.size()); glm::vec3 p0 = mesh.vertices[p0Index]; glm::vec3 p1 = mesh.vertices[p1Index]; glm::vec3 p2 = mesh.vertices[p2Index]; glm::vec3 p3 = mesh.vertices[p3Index]; - aaBox += p0; - aaBox += p1; - aaBox += p2; - aaBox += p3; if (!pointsInPart.contains(p0)) { pointsInPart << p0; } @@ -386,6 +373,11 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { } } + if (pointsInPart.size() == 0) { + qDebug() << "Warning -- meshPart has no faces"; + continue; + } + // add next convex hull QVector newMeshPoints; _points << newMeshPoints; @@ -394,11 +386,14 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { } } - // make sure we aren't about to divide by zero - glm::vec3 aaBoxDim = aaBox.getDimensions(); - aaBoxDim = glm::clamp(aaBoxDim, glm::vec3(FLT_EPSILON), aaBoxDim); + // We expect that the collision model will have the same units and will be displaced + // from its origin in the same way the visual model is. The visual model has + // been centered and probably scaled. We take the scaling and offset which were applied + // to the visual model and apply them to the collision model (without regard for the + // collision model's extents). + + glm::vec3 scale = _dimensions / renderGeometry.getUnscaledMeshExtents().size(); - glm::vec3 scale = _dimensions / aaBoxDim; // multiply each point by scale before handing the point-set off to the physics engine for (int i = 0; i < _points.size(); i++) { for (int j = 0; j < _points[i].size(); j++) { diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index db2733f27b..c87a942baa 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -27,7 +27,8 @@ public: enum SpecialToken { NO_TOKEN = -1, NO_PUSHBACKED_TOKEN = -1, - DATUM_TOKEN = 0x100 + DATUM_TOKEN = 0x100, + COMMENT_TOKEN = 0x101 }; int nextToken(); const QByteArray& getDatum() const { return _datum; } @@ -35,11 +36,13 @@ public: void skipLine() { _device->readLine(); } void pushBackToken(int token) { _pushedBackToken = token; } void ungetChar(char ch) { _device->ungetChar(ch); } + const QString getComment() const { return _comment; } private: QIODevice* _device; QByteArray _datum; int _pushedBackToken; + QString _comment; }; @@ -56,9 +59,11 @@ int OBJTokenizer::nextToken() { continue; // skip whitespace } switch (ch) { - case '#': - _device->readLine(); // skip the comment - break; + case '#': { + _comment = _device->readLine(); // skip the comment + qDebug() << "COMMENT:" << _comment; + return COMMENT_TOKEN; + } case '\"': _datum = ""; @@ -104,7 +109,8 @@ bool OBJTokenizer::isNextTokenFloat() { } bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping, - FBXGeometry &geometry, QVector& faceNormals, QVector& faceNormalIndexes) { + FBXGeometry &geometry, QVector& faceNormals, QVector& faceNormalIndexes, + float& scaleGuess) { FBXMesh &mesh = geometry.meshes[0]; mesh.parts.append(FBXMeshPart()); FBXMeshPart &meshPart = mesh.parts.last(); @@ -128,7 +134,17 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping, meshPart._material->setEmissive(glm::vec3(0.0, 0.0, 0.0)); while (true) { - if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) { + int tokenType = tokenizer.nextToken(); + if (tokenType == OBJTokenizer::COMMENT_TOKEN) { + if (tokenizer.getComment().contains("This file uses centimeters as units")) { + scaleGuess = 1.0f / 100.0f; + } + if (tokenizer.getComment().contains("This file uses millimeters as units")) { + scaleGuess = 1.0f / 1000.0f; + } + continue; + } + if (tokenType != OBJTokenizer::DATUM_TOKEN) { result = false; break; } @@ -192,6 +208,7 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping, while (true) { if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) { if (indices.count() == 0) { + // nonsense, bail out. goto done; } break; @@ -266,22 +283,22 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping, } } else { // something we don't (yet) care about - qDebug() << "OBJ parser is skipping a line with" << token; + // qDebug() << "OBJ parser is skipping a line with" << token; tokenizer.skipLine(); } } done: + + if (meshPart.triangleIndices.size() == 0 && meshPart.quadIndices.size() == 0) { + // empty mesh? + mesh.parts.pop_back(); + } + return result; } -FBXGeometry extractOBJGeometry(const FBXNode& node, const QVariantHash& mapping) { - FBXGeometry geometry; - return geometry; -} - - FBXGeometry readOBJ(const QByteArray& model, const QVariantHash& mapping) { QBuffer buffer(const_cast(&model)); buffer.open(QIODevice::ReadOnly); @@ -294,24 +311,30 @@ FBXGeometry readOBJ(QIODevice* device, const QVariantHash& mapping) { OBJTokenizer tokenizer(device); QVector faceNormalIndexes; QVector faceNormals; + float scaleGuess = 1.0f; faceNormalIndexes.clear(); geometry.meshExtents.reset(); geometry.meshes.append(FBXMesh()); - - try { // call parseOBJGroup as long as it's returning true. Each successful call will // add a new meshPart to the geometry's single mesh. bool success = true; while (success) { - success = parseOBJGroup(tokenizer, mapping, geometry, faceNormals, faceNormalIndexes); + success = parseOBJGroup(tokenizer, mapping, geometry, faceNormals, faceNormalIndexes, scaleGuess); } FBXMesh &mesh = geometry.meshes[0]; + // if we got a hint about units, scale all the points + if (scaleGuess != 1.0f) { + for (int i = 0; i < mesh.vertices.size(); i++) { + mesh.vertices[i] *= scaleGuess; + } + } + mesh.meshExtents.reset(); foreach (const glm::vec3& vertex, mesh.vertices) { mesh.meshExtents.addPoint(vertex); diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 3c27c4644c..f8b297c025 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -33,8 +33,7 @@ AddressManager::AddressManager() : _rootPlaceName(), _rootPlaceID(), _positionGetter(NULL), - _orientationGetter(NULL), - _localDSPortSharedMem(NULL) + _orientationGetter(NULL) { connect(qApp, &QCoreApplication::aboutToQuit, this, &AddressManager::storeCurrentAddress); } @@ -331,13 +330,6 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString) { quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT; - if (domainHostname == "localhost") { - auto nodeList = DependencyManager::get(); - nodeList->getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, - _localDSPortSharedMem, - domainPort); - } - if (!hostnameRegex.cap(2).isEmpty()) { domainPort = (qint16) hostnameRegex.cap(2).toInt(); } diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index a2522afcbc..db1cd6a3c8 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -95,8 +95,6 @@ private: QUuid _rootPlaceID; PositionGetter _positionGetter; OrientationGetter _orientationGetter; - - QSharedMemory* _localDSPortSharedMem; // memory shared with domain server }; #endif // hifi_AddressManager_h diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 0877f657e1..35ef7d8e2c 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -47,6 +47,7 @@ public: void setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname); unsigned short getPort() const { return _sockAddr.getPort(); } + void setPort(quint16 port) { _sockAddr.setPort(port); } const QUuid& getAssignmentUUID() const { return _assignmentUUID; } void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index ebd10b67a6..bb946e28db 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -36,8 +36,6 @@ const char SOLO_NODE_TYPES[2] = { NodeType::AudioMixer }; -const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://metaverse.highfidelity.com"); - LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) : linkedDataCreateCallback(NULL), _sessionUUID(), @@ -392,8 +390,9 @@ void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) { _nodeMutex.unlock(); - QWriteLocker writeLocker(&_nodeMutex); + _nodeMutex.lockForWrite(); _nodeHash.unsafe_erase(it); + _nodeMutex.unlock(); handleNodeKill(matchingNode); } else { diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 532e8ffcf4..be142fb036 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -42,8 +42,6 @@ const quint64 NODE_SILENCE_THRESHOLD_MSECS = 2 * 1000; extern const char SOLO_NODE_TYPES[2]; -extern const QUrl DEFAULT_NODE_AUTH_URL; - const char DEFAULT_ASSIGNMENT_SERVER_HOSTNAME[] = "localhost"; const char STUN_SERVER_HOSTNAME[] = "stun.highfidelity.io"; diff --git a/libraries/networking/src/NetworkingConstants.h b/libraries/networking/src/NetworkingConstants.h new file mode 100644 index 0000000000..a1940611bc --- /dev/null +++ b/libraries/networking/src/NetworkingConstants.h @@ -0,0 +1,21 @@ +// +// NetworkingConstants.h +// libraries/networking/src +// +// Created by Stephen Birarda on 2015-03-31. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_NetworkingConstants_h +#define hifi_NetworkingConstants_h + +#include + +namespace NetworkingConstants { + const QUrl METAVERSE_SERVER_URL = QUrl("https://metaverse.highfidelity.com"); +} + +#endif // hifi_NetworkingConstants_h \ No newline at end of file diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index e63f230f6e..83424d7688 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -277,6 +277,23 @@ void NodeList::sendDomainServerCheckIn() { if (!_domainHandler.isConnected()) { qDebug() << "Sending connect request to domain-server at" << _domainHandler.getHostname(); + + // is this our localhost domain-server? + // if so we need to make sure we have an up-to-date local port in case it restarted + + if (_domainHandler.getSockAddr().getAddress() == QHostAddress::LocalHost + || _domainHandler.getHostname() == "localhost") { + + static QSharedMemory* localDSPortSharedMem = NULL; + + quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT; + getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, + localDSPortSharedMem, + domainPort); + qDebug() << "Local domain-server port read from shared memory (or default) is" << domainPort; + _domainHandler.setPort(domainPort); + } + } // construct the DS check in packet diff --git a/libraries/networking/src/OAuthNetworkAccessManager.cpp b/libraries/networking/src/OAuthNetworkAccessManager.cpp index 89a73d5984..fa6f3b8340 100644 --- a/libraries/networking/src/OAuthNetworkAccessManager.cpp +++ b/libraries/networking/src/OAuthNetworkAccessManager.cpp @@ -15,6 +15,7 @@ #include "AccountManager.h" #include "LimitedNodeList.h" +#include "NetworkingConstants.h" #include "SharedUtil.h" #include "OAuthNetworkAccessManager.h" @@ -33,7 +34,8 @@ QNetworkReply* OAuthNetworkAccessManager::createRequest(QNetworkAccessManager::O QIODevice* outgoingData) { AccountManager& accountManager = AccountManager::getInstance(); - if (accountManager.hasValidAccessToken() && req.url().host() == DEFAULT_NODE_AUTH_URL.host()) { + if (accountManager.hasValidAccessToken() + && req.url().host() == NetworkingConstants::METAVERSE_SERVER_URL.host()) { QNetworkRequest authenticatedRequest(req); authenticatedRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); authenticatedRequest.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 83f473d8c5..9cf0d53244 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -70,6 +70,7 @@ QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& bool delayLoad, void* extra) { QSharedPointer resource = _resources.value(url); if (!resource.isNull()) { + removeUnusedResource(resource); return resource; } @@ -83,16 +84,14 @@ QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& return getResource(fallback, QUrl(), delayLoad); } - if (resource.isNull()) { - resource = createResource(url, fallback.isValid() ? - getResource(fallback, QUrl(), true) : QSharedPointer(), delayLoad, extra); - resource->setSelf(resource); - resource->setCache(this); - _resources.insert(url, resource); - - } else { - removeUnusedResource(resource); - } + resource = createResource(url, fallback.isValid() ? + getResource(fallback, QUrl(), true) : QSharedPointer(), delayLoad, extra); + resource->setSelf(resource); + resource->setCache(this); + _resources.insert(url, resource); + removeUnusedResource(resource); + resource->ensureLoading(); + return resource; } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index ffa84adbdf..f46bd689d4 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -535,10 +535,13 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit } void DeferredLightingEffect::setAmbientLightMode(int preset) { - if ((preset >= -1) && (preset < model::SphericalHarmonics::NUM_PRESET)) { + if ((preset >= 0) && (preset < model::SphericalHarmonics::NUM_PRESET)) { _ambientLightMode = preset; auto light = _allocatedLights.front(); light->setAmbientSpherePreset(model::SphericalHarmonics::Preset(preset % model::SphericalHarmonics::NUM_PRESET)); + } else { + // force to preset 0 + setAmbientLightMode(0); } } diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index c74f714e8d..98843cc87f 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -1775,10 +1775,10 @@ QSharedPointer GeometryCache::getGeometry(const QUrl& url, cons return getResource(url, fallback, delayLoad, NULL).staticCast(); } -QSharedPointer GeometryCache::createResource(const QUrl& url, - const QSharedPointer& fallback, bool delayLoad, const void* extra) { +QSharedPointer GeometryCache::createResource(const QUrl& url, const QSharedPointer& fallback, + bool delayLoad, const void* extra) { QSharedPointer geometry(new NetworkGeometry(url, fallback.staticCast(), delayLoad), - &Resource::allReferencesCleared); + &Resource::allReferencesCleared); geometry->setLODParent(geometry); return geometry.staticCast(); } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 81c9f9448c..e9cfdaf345 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2372,7 +2372,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args, - bool forceRenderSomeMeshes) { + bool forceRenderMeshes) { PROFILE_RANGE(__FUNCTION__); int meshPartsRendered = 0; @@ -2395,7 +2395,7 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations, skinLocations); meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, - args, locations, skinLocations, forceRenderSomeMeshes); + args, locations, skinLocations, forceRenderMeshes); GLBATCH(glUseProgram)(0); return meshPartsRendered; @@ -2403,7 +2403,7 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args, - Locations* locations, SkinLocations* skinLocations, bool forceRenderSomeMeshes) { + Locations* locations, SkinLocations* skinLocations, bool forceRenderMeshes) { PROFILE_RANGE(__FUNCTION__); auto textureCache = DependencyManager::get(); @@ -2439,21 +2439,14 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod // if we got here, then check to see if this mesh is in view if (args) { bool shouldRender = true; - bool forceRender = false; args->_meshesConsidered++; if (args->_viewFrustum) { - // NOTE: This is a hack to address the fact that for avatar meshes, the _calculatedMeshBoxes can be wrong - // for some meshes. Those meshes where the mesh's modelTransform is the identity matrix, and will have - // incorrectly calculated mesh boxes. In this case, we will ignore the box and assume it's visible. - if (forceRenderSomeMeshes && (geometry.meshes.at(i).modelTransform == glm::mat4())) { - forceRender = true; - } - - shouldRender = forceRender || args->_viewFrustum->boxInFrustum(_calculatedMeshBoxes.at(i)) != ViewFrustum::OUTSIDE; + shouldRender = forceRenderMeshes || + args->_viewFrustum->boxInFrustum(_calculatedMeshBoxes.at(i)) != ViewFrustum::OUTSIDE; - if (shouldRender && !forceRender) { + if (shouldRender && !forceRenderMeshes) { float distance = args->_viewFrustum->distanceToCamera(_calculatedMeshBoxes.at(i).calcCenter()); shouldRender = !_viewState ? false : _viewState->shouldRenderMesh(_calculatedMeshBoxes.at(i).getLargestDimension(), distance); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 3b4cbdd450..299853ec9d 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -460,14 +460,14 @@ private: bool renderCore(float alpha, RenderMode mode, RenderArgs* args); int renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL, - bool forceRenderSomeMeshes = false); + bool forceRenderMeshes = false); void setupBatchTransform(gpu::Batch& batch); QVector* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned); int renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args, Locations* locations, SkinLocations* skinLocations, - bool forceRenderSomeMeshes = false); + bool forceRenderMeshes = false); static void pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args, diff --git a/libraries/script-engine/src/XMLHttpRequestClass.cpp b/libraries/script-engine/src/XMLHttpRequestClass.cpp index 3054472a3c..ae0486dd0c 100644 --- a/libraries/script-engine/src/XMLHttpRequestClass.cpp +++ b/libraries/script-engine/src/XMLHttpRequestClass.cpp @@ -17,12 +17,13 @@ #include #include +#include #include #include "XMLHttpRequestClass.h" #include "ScriptEngine.h" -const QString METAVERSE_API_URL = "https://metaverse.highfidelity.com/api/"; +const QString METAVERSE_API_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/api/"; Q_DECLARE_METATYPE(QByteArray*) diff --git a/libraries/shared/src/Extents.h b/libraries/shared/src/Extents.h index 66b33114f7..024d72013a 100644 --- a/libraries/shared/src/Extents.h +++ b/libraries/shared/src/Extents.h @@ -48,7 +48,7 @@ public: void rotate(const glm::quat& rotation); glm::vec3 size() const { return maximum - minimum; } - float largestDimension () const {glm::vec3 s = size(); return glm::max(s[0], s[1], s[2]); } + float largestDimension() const {glm::vec3 s = size(); return glm::max(s[0], s[1], s[2]); } /// \return new Extents which is original rotated around orign by rotation Extents getRotated(const glm::quat& rotation) const { diff --git a/libraries/shared/src/StreamUtils.cpp b/libraries/shared/src/StreamUtils.cpp index f58115d288..b2ea5d95a4 100644 --- a/libraries/shared/src/StreamUtils.cpp +++ b/libraries/shared/src/StreamUtils.cpp @@ -66,7 +66,9 @@ QDataStream& operator>>(QDataStream& in, glm::quat& quaternion) { } // less common utils can be enabled with DEBUG -#ifdef DEBUG +// FIXME, remove the second defined clause once these compile, or remove the +// functions. +#if defined(DEBUG) && defined(FIXED_STREAMS) std::ostream& operator<<(std::ostream& s, const CollisionInfo& c) { s << "{penetration=" << c._penetration