From e1421f2e3afb7a9f682fdb790a66e9bbdac2805e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 28 Feb 2018 10:45:08 -0800 Subject: [PATCH 01/44] switch back to app-local VC runtimes and UCRT --- cmake/macros/GenerateInstallers.cmake | 7 ++++--- cmake/macros/PackageLibrariesForDeployment.cmake | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index 702636dd01..2f3493c52e 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -46,9 +46,10 @@ macro(GENERATE_INSTALLERS) set(UNINSTALLER_HEADER_IMAGE "") fix_path_for_nsis(${_UNINSTALLER_HEADER_BAD_PATH} UNINSTALLER_HEADER_IMAGE) - # grab the latest VC redist (2017) and add it to the installer, our NSIS template - # will call it during the install - install(CODE "file(DOWNLOAD https://go.microsoft.com/fwlink/?LinkId=746572 \"\${CMAKE_INSTALL_PREFIX}/vcredist_x64.exe\")") + set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ${INTERFACE_INSTALL_DIR}) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT ${CLIENT_COMPONENT}) + include(InstallRequiredSystemLibraries) elseif (APPLE) # produce a drag and drop DMG on OS X set(CPACK_GENERATOR "DragNDrop") diff --git a/cmake/macros/PackageLibrariesForDeployment.cmake b/cmake/macros/PackageLibrariesForDeployment.cmake index d324776572..0fb03feeac 100644 --- a/cmake/macros/PackageLibrariesForDeployment.cmake +++ b/cmake/macros/PackageLibrariesForDeployment.cmake @@ -39,7 +39,7 @@ macro(PACKAGE_LIBRARIES_FOR_DEPLOYMENT) add_custom_command( TARGET ${TARGET_NAME} POST_BUILD - COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND} ${EXTRA_DEPLOY_OPTIONS} $<$,$,$>:--release> \"$\"" + COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND} ${EXTRA_DEPLOY_OPTIONS} $<$,$,$>:--release> --no-compiler-runtime \"$\"" ) set(QTAUDIO_PATH "$/audio") From 0d7d382540f7316af7ab9d61503500fd85be09d4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 28 Feb 2018 16:42:25 -0800 Subject: [PATCH 02/44] pass additional exclusions to windeployqt --- cmake/macros/PackageLibrariesForDeployment.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/macros/PackageLibrariesForDeployment.cmake b/cmake/macros/PackageLibrariesForDeployment.cmake index 0fb03feeac..29f4617a6f 100644 --- a/cmake/macros/PackageLibrariesForDeployment.cmake +++ b/cmake/macros/PackageLibrariesForDeployment.cmake @@ -39,7 +39,9 @@ macro(PACKAGE_LIBRARIES_FOR_DEPLOYMENT) add_custom_command( TARGET ${TARGET_NAME} POST_BUILD - COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND} ${EXTRA_DEPLOY_OPTIONS} $<$,$,$>:--release> --no-compiler-runtime \"$\"" + COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND}\ + ${EXTRA_DEPLOY_OPTIONS} $<$,$,$>:--release>\ + --no-compiler-runtime --no-opengl-sw --no-angle -no-system-d3d-compiler \"$\"" ) set(QTAUDIO_PATH "$/audio") From 287ea8eff2b2635ef953bf5029fc16fdf65fbf9b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 2 Mar 2018 15:40:49 +1300 Subject: [PATCH 03/44] Fix Window.setFocus() unsetting focus if Interface has focus --- interface/src/Application.cpp | 10 ++++++++++ interface/src/Application.h | 1 + interface/src/scripting/WindowScriptingInterface.cpp | 4 +--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 34cdf3cda8..06d1be6997 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7329,6 +7329,16 @@ bool Application::hasFocus() const { return (QApplication::activeWindow() != nullptr); } +void Application::setFocus() { + // Note: Windows doesn't allow a user focus to be taken away from another application. Instead, it changes the color of and + // flashes the taskbar icon. + auto window = qApp->getWindow(); + window->activateWindow(); + + // Do NOT do the following because it takes focus away from the _displayPlugin. + //window->setFocus(); +} + void Application::setMaxOctreePacketsPerSecond(int maxOctreePPS) { if (maxOctreePPS != _maxOctreePPS) { _maxOctreePPS = maxOctreePPS; diff --git a/interface/src/Application.h b/interface/src/Application.h index ad12a4dc67..c673138369 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -160,6 +160,7 @@ public: QRect getRecommendedHUDRect() const; glm::vec2 getDeviceSize() const; bool hasFocus() const; + void setFocus(); void showCursor(const Cursor::Icon& cursor); diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index 12b20566ed..1c98f5190d 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -74,9 +74,7 @@ QScriptValue WindowScriptingInterface::hasFocus() { void WindowScriptingInterface::setFocus() { // It's forbidden to call focus() from another thread. qApp->postLambdaEvent([] { - auto window = qApp->getWindow(); - window->activateWindow(); - window->setFocus(); + qApp->setFocus(); }); } From 19e4fb2355f6948ddadf4ee19a09652c3a3e842d Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 7 Mar 2018 12:22:17 -0800 Subject: [PATCH 04/44] materials on primitives --- .../src/RenderableMaterialEntityItem.cpp | 144 +----------- .../src/RenderableMaterialEntityItem.h | 14 -- .../src/RenderableShapeEntityItem.cpp | 95 +++++++- .../src/RenderableShapeEntityItem.h | 6 + libraries/render-utils/src/GeometryCache.cpp | 216 +++++++++++++++--- libraries/render-utils/src/GeometryCache.h | 4 +- .../render-utils/src/MaterialTextures.slh | 14 +- .../src/forward_model_normal_map.slf | 2 +- .../src/model_lightmap_normal_map.slf | 6 +- .../src/model_lightmap_normal_map_fade.slf | 6 +- .../render-utils/src/model_normal_map.slf | 6 +- .../src/model_normal_map_fade.slf | 6 +- .../src/model_translucent_normal_map.slf | 2 +- .../src/model_translucent_normal_map_fade.slf | 2 +- libraries/shared/src/shared/Shapes.cpp | 111 ++++++++- libraries/shared/src/shared/Shapes.h | 2 + 16 files changed, 418 insertions(+), 218 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 119a46b68f..8566b9bae8 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -9,6 +9,7 @@ #include "RenderableMaterialEntityItem.h" #include "RenderPipelines.h" +#include "GeometryCache.h" using namespace render; using namespace render::entities; @@ -90,138 +91,6 @@ ShapeKey MaterialEntityRenderer::getShapeKey() { return builder.build(); } -glm::vec3 MaterialEntityRenderer::getVertexPos(float phi, float theta) { - return glm::vec3(glm::sin(theta) * glm::cos(phi), glm::cos(theta), glm::sin(theta) * glm::sin(phi)); -} - -glm::vec3 MaterialEntityRenderer::getTangent(float phi, float theta) { - return glm::vec3(-glm::cos(theta) * glm::cos(phi), glm::sin(theta), -glm::cos(theta) * glm::sin(phi)); -} - -void MaterialEntityRenderer::addVertex(std::vector& buffer, const glm::vec3& pos, const glm::vec3& tan, const glm::vec2 uv) { - buffer.push_back(pos.x); buffer.push_back(pos.y); buffer.push_back(pos.z); - buffer.push_back(tan.x); buffer.push_back(tan.y); buffer.push_back(tan.z); - buffer.push_back(uv.x); buffer.push_back(uv.y); -} - -void MaterialEntityRenderer::addTriangleFan(std::vector& buffer, int stack, int step) { - float v1 = ((float)stack) / STACKS; - float theta1 = v1 * (float)M_PI; - glm::vec3 tip = getVertexPos(0, theta1); - float v2 = ((float)(stack + step)) / STACKS; - float theta2 = v2 * (float)M_PI; - for (int i = 0; i < SLICES; i++) { - float u1 = ((float)i) / SLICES; - float u2 = ((float)(i + step)) / SLICES; - float phi1 = u1 * M_PI_TIMES_2; - float phi2 = u2 * M_PI_TIMES_2; - /* (flipped for negative step) - p1 - / \ - / \ - / \ - p3 ------ p2 - */ - - glm::vec3 pos2 = getVertexPos(phi2, theta2); - glm::vec3 pos3 = getVertexPos(phi1, theta2); - - glm::vec3 tan1 = getTangent(0, theta1); - glm::vec3 tan2 = getTangent(phi2, theta2); - glm::vec3 tan3 = getTangent(phi1, theta2); - - glm::vec2 uv1 = glm::vec2((u1 + u2) / 2.0f, v1); - glm::vec2 uv2 = glm::vec2(u2, v2); - glm::vec2 uv3 = glm::vec2(u1, v2); - - addVertex(buffer, tip, tan1, uv1); - addVertex(buffer, pos2, tan2, uv2); - addVertex(buffer, pos3, tan3, uv3); - - _numVertices += 3; - } -} - -int MaterialEntityRenderer::_numVertices = 0; -std::shared_ptr MaterialEntityRenderer::_streamFormat = nullptr; -std::shared_ptr MaterialEntityRenderer::_stream = nullptr; -std::shared_ptr MaterialEntityRenderer::_verticesBuffer = nullptr; - -void MaterialEntityRenderer::generateMesh() { - _streamFormat = std::make_shared(); - _stream = std::make_shared(); - _verticesBuffer = std::make_shared(); - - const int NUM_POS_COORDS = 3; - const int NUM_TANGENT_COORDS = 3; - const int VERTEX_TANGENT_OFFSET = NUM_POS_COORDS * sizeof(float); - const int VERTEX_TEXCOORD_OFFSET = VERTEX_TANGENT_OFFSET + NUM_TANGENT_COORDS * sizeof(float); - - _streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); - _streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); - _streamFormat->setAttribute(gpu::Stream::TANGENT, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_TANGENT_OFFSET); - _streamFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), VERTEX_TEXCOORD_OFFSET); - - _stream->addBuffer(_verticesBuffer, 0, _streamFormat->getChannels().at(0)._stride); - - std::vector vertexBuffer; - - // Top - addTriangleFan(vertexBuffer, 0, 1); - - // Middle section - for (int j = 1; j < STACKS - 1; j++) { - float v1 = ((float)j) / STACKS; - float v2 = ((float)(j + 1)) / STACKS; - float theta1 = v1 * (float)M_PI; - float theta2 = v2 * (float)M_PI; - for (int i = 0; i < SLICES; i++) { - float u1 = ((float)i) / SLICES; - float u2 = ((float)(i + 1)) / SLICES; - float phi1 = u1 * M_PI_TIMES_2; - float phi2 = u2 * M_PI_TIMES_2; - - /* - p2 ---- p3 - | / | - | / | - | / | - p1 ---- p4 - */ - - glm::vec3 pos1 = getVertexPos(phi1, theta2); - glm::vec3 pos2 = getVertexPos(phi1, theta1); - glm::vec3 pos3 = getVertexPos(phi2, theta1); - glm::vec3 pos4 = getVertexPos(phi2, theta2); - - glm::vec3 tan1 = getTangent(phi1, theta2); - glm::vec3 tan2 = getTangent(phi1, theta1); - glm::vec3 tan3 = getTangent(phi2, theta1); - glm::vec3 tan4 = getTangent(phi2, theta2); - - glm::vec2 uv1 = glm::vec2(u1, v2); - glm::vec2 uv2 = glm::vec2(u1, v1); - glm::vec2 uv3 = glm::vec2(u2, v1); - glm::vec2 uv4 = glm::vec2(u2, v2); - - addVertex(vertexBuffer, pos1, tan1, uv1); - addVertex(vertexBuffer, pos2, tan2, uv2); - addVertex(vertexBuffer, pos3, tan3, uv3); - - addVertex(vertexBuffer, pos3, tan3, uv3); - addVertex(vertexBuffer, pos4, tan4, uv4); - addVertex(vertexBuffer, pos1, tan1, uv1); - - _numVertices += 6; - } - } - - // Bottom - addTriangleFan(vertexBuffer, STACKS, -1); - - _verticesBuffer->append(vertexBuffer.size() * sizeof(float), (gpu::Byte*) vertexBuffer.data()); -} - void MaterialEntityRenderer::doRender(RenderArgs* args) { PerformanceTimer perfTimer("RenderableMaterialEntityItem::render"); Q_ASSERT(args->_batch); @@ -252,14 +121,7 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { args->_details._materialSwitches++; // Draw! - if (_numVertices == 0) { - generateMesh(); - } + DependencyManager::get()->renderSphere(batch); - batch.setInputFormat(_streamFormat); - batch.setInputStream(0, *_stream); - batch.draw(gpu::TRIANGLES, _numVertices, 0); - - const int NUM_VERTICES_PER_TRIANGLE = 3; - args->_details._trianglesRendered += _numVertices / NUM_VERTICES_PER_TRIANGLE; + args->_details._trianglesRendered += DependencyManager::get()->getSphereTriangleCount(); } diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index fef1a41138..8de2190a0c 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -40,20 +40,6 @@ private: Transform _renderTransform; std::shared_ptr _drawMaterial; - - static int _numVertices; - static std::shared_ptr _streamFormat; - static std::shared_ptr _stream; - static std::shared_ptr _verticesBuffer; - - void generateMesh(); - void addTriangleFan(std::vector& buffer, int stack, int step); - static glm::vec3 getVertexPos(float phi, float theta); - static glm::vec3 getTangent(float phi, float theta); - static void addVertex(std::vector& buffer, const glm::vec3& pos, const glm::vec3& tan, const glm::vec2 uv); - const int SLICES = 15; - const int STACKS = 9; - const float M_PI_TIMES_2 = 2.0f * (float)M_PI; }; } } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 22cd98b08a..b14e201366 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -19,6 +19,8 @@ #include "render-utils/simple_vert.h" #include "render-utils/simple_frag.h" +#include "RenderPipelines.h" + //#define SHAPE_ENTITY_USE_FADE_EFFECT #ifdef SHAPE_ENTITY_USE_FADE_EFFECT #include @@ -108,11 +110,93 @@ bool ShapeEntityRenderer::isTransparent() const { if (_procedural.isEnabled() && _procedural.isFading()) { return Interpolate::calculateFadeRatio(_procedural.getFadeStartTime()) < 1.0f; } - - // return _entity->getLocalRenderAlpha() < 1.0f || Parent::isTransparent(); + + auto mat = _materials.find("0"); + if (mat != _materials.end()) { + if (mat->second.top().material) { + auto matKey = mat->second.top().material->getKey(); + if (matKey.isTranslucent()) { + return true; + } + } + } + return Parent::isTransparent(); } +ItemKey ShapeEntityRenderer::getKey() { + ItemKey::Builder builder; + builder.withTypeShape().withTypeMeta().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1); + + withReadLock([&] { + if (isTransparent()) { + builder.withTransparent(); + } + }); + + return builder.build(); +} + +bool ShapeEntityRenderer::useMaterialPipeline() const { + withReadLock([&] { + if (_procedural.isReady()) { + return false; + } + }); + + graphics::MaterialKey drawMaterialKey; + auto mat = _materials.find("0"); + if (mat != _materials.end() && mat->second.top().material) { + drawMaterialKey = mat->second.top().material->getKey(); + } + + if (drawMaterialKey.isEmissive() || drawMaterialKey.isUnlit() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) { + return true; + } + + // If the material is using any map, we need to use a material ShapeKey + for (int i = 0; i < graphics::Material::MapChannel::NUM_MAP_CHANNELS; i++) { + if (drawMaterialKey.isMapChannel(graphics::Material::MapChannel(i))) { + return true; + } + } + return false; +} + +ShapeKey ShapeEntityRenderer::getShapeKey() { + if (useMaterialPipeline()) { + graphics::MaterialKey drawMaterialKey; + if (_materials["0"].top().material) { + drawMaterialKey = _materials["0"].top().material->getKey(); + } + + bool isTranslucent = drawMaterialKey.isTranslucent(); + bool hasTangents = drawMaterialKey.isNormalMap(); + bool hasLightmap = drawMaterialKey.isLightmapMap(); + bool isUnlit = drawMaterialKey.isUnlit(); + + ShapeKey::Builder builder; + builder.withMaterial(); + + if (isTranslucent) { + builder.withTranslucent(); + } + if (hasTangents) { + builder.withTangents(); + } + if (hasLightmap) { + builder.withLightmap(); + } + if (isUnlit) { + builder.withUnlit(); + } + + return builder.build(); + } else { + return Parent::getShapeKey(); + } +} + void ShapeEntityRenderer::doRender(RenderArgs* args) { PerformanceTimer perfTimer("RenderableShapeEntityItem::render"); Q_ASSERT(args->_batch); @@ -149,7 +233,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { } else { geometryCache->renderShape(batch, geometryShape, outColor); } - } else { + } else if (!useMaterialPipeline()) { // FIXME, support instanced multi-shape rendering using multidraw indirect outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; auto pipeline = outColor.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline(); @@ -158,6 +242,11 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { } else { geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, pipeline); } + } else { + RenderPipelines::bindMaterial(mat, batch, args->_enableTexturing); + args->_details._materialSwitches++; + + geometryCache->renderShape(batch, geometryShape); } const auto triCount = geometryCache->getShapeTriangleCount(geometryShape); diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.h b/libraries/entities-renderer/src/RenderableShapeEntityItem.h index de855ce0c6..463ef187fc 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.h +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.h @@ -24,6 +24,10 @@ public: virtual scriptable::ScriptableModelBase getScriptableModel() override; +protected: + ItemKey getKey() override; + ShapeKey getShapeKey() override; + private: virtual bool needsRenderUpdate() const override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; @@ -32,6 +36,8 @@ private: virtual void doRender(RenderArgs* args) override; virtual bool isTransparent() const override; + bool useMaterialPipeline() const; + Procedural _procedural; QString _lastUserData; Transform _renderTransform; diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 7455da13b6..61fcdafd39 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -126,6 +126,8 @@ static const int VERTICES_PER_TRIANGLE = 3; static const gpu::Element POSITION_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; static const gpu::Element NORMAL_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; +static const gpu::Element TEXCOORD0_ELEMENT { gpu::VEC2, gpu::FLOAT, gpu::UV }; +static const gpu::Element TANGENT_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; static const gpu::Element COLOR_ELEMENT { gpu::VEC4, gpu::NUINT8, gpu::RGBA }; static const gpu::Element TEXCOORD4_ELEMENT { gpu::VEC4, gpu::FLOAT, gpu::XYZW }; @@ -133,8 +135,10 @@ static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT; static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT; static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT; -static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals +static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 3 + sizeof(glm::vec2); // position, normal, texcoords, tangent static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3); +static const uint SHAPE_TEXCOORD0_OFFSET = sizeof(glm::vec3) * 2; +static const uint SHAPE_TANGENT_OFFSET = sizeof(glm::vec3) * 2 + sizeof(glm::vec2); void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, const glm::vec3 &entityExtents, QVector &outPointList) { @@ -193,7 +197,18 @@ std::vector polygon() { return result; } -void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const geometry::VertexVector& vertices) { +void addVec3ToVector(std::vector& vertices, glm::vec3 vec) { + vertices.push_back(vec.x); + vertices.push_back(vec.y); + vertices.push_back(vec.z); +} + +void addVec2ToVector(std::vector& vertices, glm::vec2 vec) { + vertices.push_back(vec.x); + vertices.push_back(vec.y); +} + +void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices) { gpu::Buffer::Size offset = vertexBuffer->getSize(); vertexBuffer->append(vertices); @@ -203,6 +218,10 @@ void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, c viewSize, SHAPE_VERTEX_STRIDE, POSITION_ELEMENT); _normalView = gpu::BufferView(vertexBuffer, offset + SHAPE_NORMALS_OFFSET, viewSize, SHAPE_VERTEX_STRIDE, NORMAL_ELEMENT); + _texCoordView = gpu::BufferView(vertexBuffer, offset + SHAPE_TEXCOORD0_OFFSET, + viewSize, SHAPE_VERTEX_STRIDE, TEXCOORD0_ELEMENT); + _tangentView = gpu::BufferView(vertexBuffer, offset + SHAPE_TANGENT_OFFSET, + viewSize, SHAPE_VERTEX_STRIDE, TANGENT_ELEMENT); } void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices) { @@ -228,6 +247,8 @@ void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, con void GeometryCache::ShapeData::setupBatch(gpu::Batch& batch) const { batch.setInputBuffer(gpu::Stream::POSITION, _positionView); batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); + batch.setInputBuffer(gpu::Stream::TEXCOORD, _texCoordView); + batch.setInputBuffer(gpu::Stream::TANGENT, _tangentView); batch.setIndexBuffer(_indicesView); } @@ -294,7 +315,7 @@ static IndexPair indexToken(geometry::Index a, geometry::Index b) { template void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - VertexVector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; IndexPairs wireSeenIndices; @@ -310,11 +331,38 @@ void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - VertexVector vertices; - vertices.reserve(shape.vertices.size() * 2); + std::vector vertices; + vertices.reserve(shape.vertices.size() * SHAPE_VERTEX_STRIDE / sizeof(float)); for (const auto& vertex : shape.vertices) { - vertices.push_back(vertex); - vertices.push_back(vertex); + addVec3ToVector(vertices, vertex); + addVec3ToVector(vertices, vertex); + vec2 uv = calculateSphereTexCoord(vertex); + addVec2ToVector(vertices, calculateSphereTexCoord(vertex)); + // We'll fill in the correct tangents later, once we correct the UVs + addVec3ToVector(vertices, vec3(0.0f)); + } + + // We need to fix up the sphere's UVs because it's actually a tesselated icosahedron. See http://mft-dev.dk/uv-mapping-sphere/ + size_t faceCount = shape.faces.size(); + for (size_t f = 0; f < faceCount; f++) { + // Fix zipper + { + float& u1 = vertices[shape.faces[f][0] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + float& u2 = vertices[shape.faces[f][1] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + float& u3 = vertices[shape.faces[f][2] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + + if (glm::isnan(u1)) { + u1 = (u2 + u3) / 2.0f; + } + if (glm::isnan(u2)) { + u2 = (u1 + u3) / 2.0f; + } + if (glm::isnan(u3)) { + u3 = (u1 + u2) / 2.0f; + } + + const float U_THRESHOLD = 0.25f; + float max = glm::max(u1, glm::max(u2, u3)); + float min = glm::min(u1, glm::min(u2, u3)); + + if (max - min > U_THRESHOLD) { + if (u1 < U_THRESHOLD) { + u1 += 1.0f; + } + if (u2 < U_THRESHOLD) { + u2 += 1.0f; + } + if (u3 < U_THRESHOLD) { + u3 += 1.0f; + } + } + } + + // Fix swirling at poles + for (Index i = 0; i < N; i++) { + Index originalIndex = shape.faces[f][i]; + if (shape.vertices[originalIndex].y == 1.0f || shape.vertices[originalIndex].y == -1.0f) { + float uSum = 0.0f; + for (Index i2 = 1; i2 <= N - 1; i2++) { + float u = vertices[shape.faces[f][(i + i2) % N] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + uSum += u; + } + uSum /= (float)(N - 1); + vertices[originalIndex * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)] = uSum; + break; + } + } + + // Fill in tangents + for (Index i = 0; i < N; i++) { + vec3 tangent = calculateSphereTangent(vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]); + vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float)] = tangent.x; + vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float) + 1] = tangent.y; + vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float) + 2] = tangent.z; + } } IndexVector solidIndices, wireIndices; IndexPairs wireSeenIndices; - size_t faceCount = shape.faces.size(); size_t faceIndexCount = triangulatedFaceIndexCount(); solidIndices.reserve(faceIndexCount * faceCount); @@ -391,25 +517,31 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid template void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer, bool isConical = false) { using namespace geometry; - VertexVector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; // Top (if not conical) and bottom faces std::vector shape = polygon(); if (isConical) { for (uint32_t i = 0; i < N; i++) { - vertices.push_back(vec3(0.0f, 0.5f, 0.0f)); - vertices.push_back(vec3(0.0f, 1.0f, 0.0f)); + addVec3ToVector(vertices, vec3(0.0f, 0.5f, 0.0f)); + addVec3ToVector(vertices, vec3(0.0f, 1.0f, 0.0f)); + addVec2ToVector(vertices, vec2(i / (float)N, 1.0f)); + addVec3ToVector(vertices, vec3(0.0f)); } } else { for (const vec3& v : shape) { - vertices.push_back(vec3(v.x, 0.5f, v.z)); - vertices.push_back(vec3(0.0f, 1.0f, 0.0f)); + addVec3ToVector(vertices, vec3(v.x, 0.5f, v.z)); + addVec3ToVector(vertices, vec3(0.0f, 1.0f, 0.0f)); + addVec2ToVector(vertices, vec2(v.x, v.z) + vec2(0.5f)); + addVec3ToVector(vertices, vec3(1.0f, 0.0f, 0.0f)); } } for (const vec3& v : shape) { - vertices.push_back(vec3(v.x, -0.5f, v.z)); - vertices.push_back(vec3(0.0f, -1.0f, 0.0f)); + addVec3ToVector(vertices, vec3(v.x, -0.5f, v.z)); + addVec3ToVector(vertices, vec3(0.0f, -1.0f, 0.0f)); + addVec2ToVector(vertices, vec2(-v.x, v.z) + vec2(0.5f)); + addVec3ToVector(vertices, vec3(-1.0f, 0.0f, 0.0f)); } Index baseVertex = 0; for (uint32_t i = 2; i < N; i++) { @@ -438,15 +570,28 @@ void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& ver vec3 topRight = (isConical ? vec3(0.0f, 0.5f, 0.0f) : vec3(right.x, 0.5f, right.z)); vec3 bottomLeft = vec3(left.x, -0.5f, left.z); vec3 bottomRight = vec3(right.x, -0.5f, right.z); + vec3 tangent = glm::normalize(bottomLeft - bottomRight); - vertices.push_back(topLeft); - vertices.push_back(normal); - vertices.push_back(bottomLeft); - vertices.push_back(normal); - vertices.push_back(topRight); - vertices.push_back(normal); - vertices.push_back(bottomRight); - vertices.push_back(normal); + // Our tex coords go in the opposite direction as our vertices + float u = 1.0f - i / (float)N; + float u2 = 1.0f - (i + 1) / (float)N; + + addVec3ToVector(vertices, topLeft); + addVec3ToVector(vertices, normal); + addVec2ToVector(vertices, vec2(u, 0.0f)); + addVec3ToVector(vertices, tangent); + addVec3ToVector(vertices, bottomLeft); + addVec3ToVector(vertices, normal); + addVec2ToVector(vertices, vec2(u, 1.0f)); + addVec3ToVector(vertices, tangent); + addVec3ToVector(vertices, topRight); + addVec3ToVector(vertices, normal); + addVec2ToVector(vertices, vec2(u2, 0.0f)); + addVec3ToVector(vertices, tangent); + addVec3ToVector(vertices, bottomRight); + addVec3ToVector(vertices, normal); + addVec2ToVector(vertices, vec2(u2, 1.0f)); + addVec3ToVector(vertices, tangent); solidIndices.push_back(baseVertex + 0); solidIndices.push_back(baseVertex + 2); @@ -469,14 +614,16 @@ void drawCircle(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexB // Draw a circle with radius 1/4th the size of the bounding box using namespace geometry; - VertexVector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; const int NUM_CIRCLE_VERTICES = 64; std::vector shape = polygon(); for (const vec3& v : shape) { - vertices.push_back(vec3(v.x, 0.0f, v.z)); - vertices.push_back(vec3(0.0f, 0.0f, 0.0f)); + addVec3ToVector(vertices, vec3(v.x, 0.0f, v.z)); + addVec3ToVector(vertices, vec3(0.0f, 0.0f, 0.0f)); + addVec2ToVector(vertices, vec2(v.x, v.z) + vec2(0.5f)); + addVec3ToVector(vertices, vec3(1.0f, 0.0f, 0.0f)); } Index baseVertex = 0; @@ -532,9 +679,9 @@ void GeometryCache::buildShapes() { // Line { ShapeData& shapeData = _shapes[Line]; - shapeData.setupVertices(_shapeVertices, VertexVector { - vec3(-0.5f, 0.0f, 0.0f), vec3(-0.5f, 0.0f, 0.0f), - vec3(0.5f, 0.0f, 0.0f), vec3(0.5f, 0.0f, 0.0f) + shapeData.setupVertices(_shapeVertices, std::vector { + -0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }); IndexVector wireIndices; // Only two indices @@ -598,6 +745,8 @@ gpu::Stream::FormatPointer& getSolidStreamFormat() { SOLID_STREAM_FORMAT = std::make_shared(); // 1 for everyone SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT); SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT); + SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD0, gpu::Stream::TEXCOORD0, TEXCOORD0_ELEMENT); + SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::TANGENT, gpu::Stream::TANGENT, TANGENT_ELEMENT); } return SOLID_STREAM_FORMAT; } @@ -607,6 +756,8 @@ gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() { INSTANCED_SOLID_STREAM_FORMAT = std::make_shared(); // 1 for everyone INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT); INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT); + INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD0, gpu::Stream::TEXCOORD0, TEXCOORD0_ELEMENT); + INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::TANGENT, gpu::Stream::TANGENT, TANGENT_ELEMENT); INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE); } return INSTANCED_SOLID_STREAM_FORMAT; @@ -617,6 +768,8 @@ gpu::Stream::FormatPointer& getInstancedSolidFadeStreamFormat() { INSTANCED_SOLID_FADE_STREAM_FORMAT = std::make_shared(); // 1 for everyone INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT); INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT); + INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD0, gpu::Stream::TEXCOORD0, TEXCOORD0_ELEMENT); + INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TANGENT, gpu::Stream::TANGENT, TANGENT_ELEMENT); INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE); INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD2, gpu::Stream::TEXCOORD2, TEXCOORD4_ELEMENT, 0, gpu::Stream::PER_INSTANCE); INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD3, gpu::Stream::TEXCOORD3, TEXCOORD4_ELEMENT, 0, gpu::Stream::PER_INSTANCE); @@ -919,6 +1072,7 @@ void GeometryCache::updateVertices(int id, const QVector& points, con details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ), 0); details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET); + // TODO: circle3D overlays use this to define their vertices, so they need tex coords details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride); diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 998043b80e..b0caaf113c 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -357,10 +357,12 @@ public: struct ShapeData { gpu::BufferView _positionView; gpu::BufferView _normalView; + gpu::BufferView _texCoordView; + gpu::BufferView _tangentView; gpu::BufferView _indicesView; gpu::BufferView _wireIndicesView; - void setupVertices(gpu::BufferPointer& vertexBuffer, const geometry::VertexVector& vertices); + void setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices); void setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices); void setupBatch(gpu::Batch& batch) const; void draw(gpu::Batch& batch) const; diff --git a/libraries/render-utils/src/MaterialTextures.slh b/libraries/render-utils/src/MaterialTextures.slh index b3662385b0..26bb85a853 100644 --- a/libraries/render-utils/src/MaterialTextures.slh +++ b/libraries/render-utils/src/MaterialTextures.slh @@ -148,25 +148,25 @@ vec3 fetchLightmapMap(vec2 uv) { } <@endfunc@> -<@func tangentToViewSpace(fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@> +<@func evalMaterialNormal(fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@> { vec3 normalizedNormal = normalize(<$interpolatedNormal$>.xyz); vec3 normalizedTangent = normalize(<$interpolatedTangent$>.xyz); - vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); + vec3 normalizedBitangent = cross(normalizedNormal, normalizedTangent); vec3 localNormal = <$fetchedNormal$>; - <$normal$> = vec3(normalizedTangent * localNormal.x + normalizedNormal * localNormal.y + normalizedBitangent * localNormal.z); + <$normal$> = vec3(normalizedBitangent * localNormal.x + normalizedNormal * localNormal.y + normalizedTangent * localNormal.z); } <@endfunc@> -<@func tangentToViewSpaceLOD(fragPos, fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@> +<@func evalMaterialNormalLOD(fragPos, fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@> { vec3 normalizedNormal = normalize(<$interpolatedNormal$>.xyz); vec3 normalizedTangent = normalize(<$interpolatedTangent$>.xyz); - vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); + vec3 normalizedBitangent = cross(normalizedNormal, normalizedTangent); // attenuate the normal map divergence from the mesh normal based on distance - // THe attenuation range [20,100] meters from the eye is arbitrary for now + // The attenuation range [20,100] meters from the eye is arbitrary for now vec3 localNormal = mix(<$fetchedNormal$>, vec3(0.0, 1.0, 0.0), smoothstep(20.0, 100.0, (-<$fragPos$>).z)); - <$normal$> = vec3(normalizedTangent * localNormal.x + normalizedNormal * localNormal.y + normalizedBitangent * localNormal.z); + <$normal$> = vec3(normalizedBitangent * localNormal.x + normalizedNormal * localNormal.y + normalizedTangent * localNormal.z); } <@endfunc@> diff --git a/libraries/render-utils/src/forward_model_normal_map.slf b/libraries/render-utils/src/forward_model_normal_map.slf index b32ed862d6..0ba464d3f0 100644 --- a/libraries/render-utils/src/forward_model_normal_map.slf +++ b/libraries/render-utils/src/forward_model_normal_map.slf @@ -58,7 +58,7 @@ void main(void) { vec3 fragPosition = _position.xyz; vec3 fragNormal; - <$tangentToViewSpace(normalTex, _normal, _tangent, fragNormal)$> + <$evalMaterialNormal(normalTex, _normal, _tangent, fragNormal)$> TransformCamera cam = getTransformCamera(); diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slf b/libraries/render-utils/src/model_lightmap_normal_map.slf index 8734ea74b8..eecde59e54 100644 --- a/libraries/render-utils/src/model_lightmap_normal_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map.slf @@ -33,11 +33,11 @@ void main(void) { <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness, normalTexel, metallicTex)$> <$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$> - vec3 viewNormal; - <$tangentToViewSpaceLOD(_position, normalTexel, _normal, _tangent, viewNormal)$> + vec3 fragNormal; + <$evalMaterialNormalLOD(_position, normalTexel, _normal, _tangent, fragNormal)$> packDeferredFragmentLightmap( - normalize(viewNormal.xyz), + normalize(fragNormal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a), getMaterialAlbedo(mat) * albedo.rgb * _color, getMaterialRoughness(mat) * roughness, diff --git a/libraries/render-utils/src/model_lightmap_normal_map_fade.slf b/libraries/render-utils/src/model_lightmap_normal_map_fade.slf index e6cb35ec4f..af497f90c6 100644 --- a/libraries/render-utils/src/model_lightmap_normal_map_fade.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map_fade.slf @@ -43,11 +43,11 @@ void main(void) { <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness, normalTexel, metallicTex)$> <$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$> - vec3 viewNormal; - <$tangentToViewSpaceLOD(_position, normalTexel, _normal, _tangent, viewNormal)$> + vec3 fragNormal; + <$evalMaterialNormalLOD(_position, normalTexel, _normal, _tangent, fragNormal)$> packDeferredFragmentLightmap( - normalize(viewNormal.xyz), + normalize(fragNormal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a), getMaterialAlbedo(mat) * albedo.rgb * _color, getMaterialRoughness(mat) * roughness, diff --git a/libraries/render-utils/src/model_normal_map.slf b/libraries/render-utils/src/model_normal_map.slf index 82f667bf73..49613eca6a 100644 --- a/libraries/render-utils/src/model_normal_map.slf +++ b/libraries/render-utils/src/model_normal_map.slf @@ -46,8 +46,8 @@ void main(void) { vec3 emissive = getMaterialEmissive(mat); <$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>; - vec3 viewNormal; - <$tangentToViewSpaceLOD(_position, normalTex, _normal, _tangent, viewNormal)$> + vec3 fragNormal; + <$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$> float metallic = getMaterialMetallic(mat); <$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>; @@ -56,7 +56,7 @@ void main(void) { <$evalMaterialScattering(scatteringTex, scattering, matKey, scattering)$>; packDeferredFragment( - normalize(viewNormal.xyz), + normalize(fragNormal.xyz), opacity, albedo, roughness, diff --git a/libraries/render-utils/src/model_normal_map_fade.slf b/libraries/render-utils/src/model_normal_map_fade.slf index 67bea98cf0..bf6222652c 100644 --- a/libraries/render-utils/src/model_normal_map_fade.slf +++ b/libraries/render-utils/src/model_normal_map_fade.slf @@ -56,8 +56,8 @@ void main(void) { vec3 emissive = getMaterialEmissive(mat); <$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>; - vec3 viewNormal; - <$tangentToViewSpaceLOD(_position, normalTex, _normal, _tangent, viewNormal)$> + vec3 fragNormal; + <$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$> float metallic = getMaterialMetallic(mat); <$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>; @@ -65,7 +65,7 @@ void main(void) { float scattering = getMaterialScattering(mat); packDeferredFragment( - normalize(viewNormal.xyz), + normalize(fragNormal.xyz), opacity, albedo, roughness, diff --git a/libraries/render-utils/src/model_translucent_normal_map.slf b/libraries/render-utils/src/model_translucent_normal_map.slf index 759007d93e..52015660c6 100644 --- a/libraries/render-utils/src/model_translucent_normal_map.slf +++ b/libraries/render-utils/src/model_translucent_normal_map.slf @@ -61,7 +61,7 @@ void main(void) { vec3 fragPosition = _position.xyz; vec3 fragNormal; - <$tangentToViewSpaceLOD(_position, normalTex, _normal, _tangent, fragNormal)$> + <$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$> TransformCamera cam = getTransformCamera(); vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0)); diff --git a/libraries/render-utils/src/model_translucent_normal_map_fade.slf b/libraries/render-utils/src/model_translucent_normal_map_fade.slf index 204b5ac56b..c6c0e16812 100644 --- a/libraries/render-utils/src/model_translucent_normal_map_fade.slf +++ b/libraries/render-utils/src/model_translucent_normal_map_fade.slf @@ -71,7 +71,7 @@ void main(void) { vec3 fragPosition = _position.xyz; // Lighting is done in world space vec3 fragNormal; - <$tangentToViewSpaceLOD(_position, normalTex, _normal, _tangent, fragNormal)$> + <$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$> TransformCamera cam = getTransformCamera(); vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0)); diff --git a/libraries/shared/src/shared/Shapes.cpp b/libraries/shared/src/shared/Shapes.cpp index dabdf21202..277154d6b6 100644 --- a/libraries/shared/src/shared/Shapes.cpp +++ b/libraries/shared/src/shared/Shapes.cpp @@ -8,8 +8,11 @@ #include "Shapes.h" +#include "qmath.h" + namespace geometry { +using glm::vec2; using glm::vec3; // The golden ratio @@ -20,7 +23,7 @@ Solid<3> tesselate(const Solid<3>& solid_, int count) { float length = glm::length(solid.vertices[0]); for (int i = 0; i < count; ++i) { Solid<3> result { solid.vertices, {} }; - result.vertices.reserve(solid.vertices.size() + solid.faces.size() * 3); + result.vertices.reserve(solid.vertices.size() + solid.faces.size() * 6); for (size_t f = 0; f < solid.faces.size(); ++f) { Index baseVertex = (Index)result.vertices.size(); const Face<3>& oldFace = solid.faces[f]; @@ -30,13 +33,26 @@ Solid<3> tesselate(const Solid<3>& solid_, int count) { vec3 ab = glm::normalize(a + b) * length; vec3 bc = glm::normalize(b + c) * length; vec3 ca = glm::normalize(c + a) * length; + + result.vertices.push_back(a); + result.vertices.push_back(ab); + result.vertices.push_back(ca); + result.faces.push_back(Face<3>{ { baseVertex, baseVertex + 1, baseVertex + 2 } }); + + result.vertices.push_back(ab); + result.vertices.push_back(b); + result.vertices.push_back(bc); + result.faces.push_back(Face<3>{ { baseVertex + 3, baseVertex + 4, baseVertex + 5 } }); + + result.vertices.push_back(bc); + result.vertices.push_back(c); + result.vertices.push_back(ca); + result.faces.push_back(Face<3>{ { baseVertex + 6, baseVertex + 7, baseVertex + 8 } }); + result.vertices.push_back(ab); result.vertices.push_back(bc); result.vertices.push_back(ca); - result.faces.push_back(Face<3>{ { oldFace[0], baseVertex, baseVertex + 2 } }); - result.faces.push_back(Face<3>{ { baseVertex, oldFace[1], baseVertex + 1 } }); - result.faces.push_back(Face<3>{ { baseVertex + 1, oldFace[2], baseVertex + 2 } }); - result.faces.push_back(Face<3>{ { baseVertex, baseVertex + 1, baseVertex + 2 } }); + result.faces.push_back(Face<3>{ { baseVertex + 9, baseVertex + 10, baseVertex + 11 } }); } solid = result; } @@ -50,6 +66,10 @@ const Solid<3>& tetrahedron() { static const auto D = vec3(-1, -1, 1); static const Solid<3> TETRAHEDRON = Solid<3>{ { A, B, C, D }, + { vec2(0.75f, 0.5f), vec2(0.5f, 0.0f), vec2(0.25f, 0.5f), + vec2(0.5f, 1.0f), vec2(1.0f, 1.0f), vec2(0.75f, 0.5f), + vec2(0.25f, 0.5f), vec2(0.5f, 1.0f), vec2(0.75f, 0.5f), + vec2(0.25f, 0.5f), vec2(0.0f, 1.0f), vec2(0.5f, 1.0f) }, FaceVector<3>{ Face<3> { { 0, 1, 2 } }, Face<3> { { 3, 1, 0 } }, @@ -65,8 +85,15 @@ const Solid<4>& cube() { static const auto B = vec3(-1, 1, 1); static const auto C = vec3(-1, 1, -1); static const auto D = vec3(1, 1, -1); + static const float THIRD = 1.0f / 3.0f; static const Solid<4> CUBE = Solid<4>{ { A, B, C, D, -A, -B, -C, -D }, + { vec2(0.5f, 0.0f), vec2(0.25f, 0.0f), vec2(0.25f, THIRD), vec2(0.5f, THIRD), + vec2(0.5f, THIRD), vec2(0.25f, THIRD), vec2(0.25f, 2.0f * THIRD), vec2(0.5f, 2.0f * THIRD), + vec2(0.25f, THIRD), vec2(0.0f, THIRD), vec2(0.0f, 2.0f * THIRD), vec2(0.25f, 2.0f * THIRD), + vec2(1.0f, THIRD), vec2(0.75f, THIRD), vec2(0.75f, 2.0f * THIRD), vec2(1.0f, 2.0f * THIRD), + vec2(0.75f, THIRD), vec2(0.5f, THIRD), vec2(0.5f, 2.0f * THIRD), vec2(0.75f, 2.0f * THIRD), + vec2(0.25f, 1.0f), vec2(0.5f, 1.0f), vec2(0.5f, 2.0f * THIRD), vec2(0.25f, 2.0f * THIRD) }, FaceVector<4>{ Face<4> { { 3, 2, 1, 0 } }, Face<4> { { 0, 1, 7, 6 } }, @@ -86,8 +113,18 @@ const Solid<3>& octahedron() { static const auto D = vec3(0, 0, -1); static const auto E = vec3(1, 0, 0); static const auto F = vec3(-1, 0, 0); + static const float THIRD = 1.0f / 3.0f; + static const float SEVENTH = 1.0f / 7.0f; static const Solid<3> OCTAHEDRON = Solid<3>{ { A, B, C, D, E, F}, + { vec2(2.0f * SEVENTH, THIRD), vec2(SEVENTH, 2.0f * THIRD), vec2(3.0f * SEVENTH, 2.0f * THIRD), + vec2(2.0f * SEVENTH, THIRD), vec2(3.0f * SEVENTH, 2.0f * THIRD), vec2(4.0f * SEVENTH, THIRD), + vec2(5.0f * SEVENTH, 0.0f), vec2(4.0f * SEVENTH, THIRD), vec2(6.0f * SEVENTH, THIRD), + vec2(2.0f * SEVENTH, THIRD), vec2(0.0f, THIRD), vec2(1.0f * SEVENTH, 2.0f * THIRD), + vec2(2.0f * SEVENTH, 1.0f), vec2(3.0f * SEVENTH, 2.0f * THIRD), vec2(1.0f * SEVENTH, 2.0f * THIRD), + vec2(5.0f * SEVENTH, 2.0f * THIRD), vec2(4.0f * SEVENTH, THIRD), vec2(3.0f * SEVENTH, 2.0f * THIRD), + vec2(5.0f * SEVENTH, 2.0f * THIRD), vec2(6.0f * SEVENTH, THIRD), vec2(4.0f * SEVENTH, THIRD), + vec2(5.0f * SEVENTH, 2.0f * THIRD), vec2(1.0f, 2.0f * THIRD), vec2(6.0f * SEVENTH, THIRD) }, FaceVector<3> { Face<3> { { 0, 2, 4, } }, Face<3> { { 0, 4, 3, } }, @@ -116,11 +153,52 @@ const Solid<5>& dodecahedron() { static const vec3 I = vec3(0, -IP, P); static const vec3 J = vec3(P, 0, IP); + + /* _ + / \ | + / \ y2 + / \ | + / \ _ + \ / | + \ / y1 + \ / | + ___________ _ + |x3|- - x1 - -||x3| + |- - - - x2- - - -| + */ + + // x1, x2, and x3 are the solutions to the following system of equations: + // 1 = 3 * x1 + 3 * x2 + x3 + // x1 + 2 * x3 = (golden ratio) * x1 + // x2 = x1 + 2 * x3 + static const float x1 = 4.0f / (17.0f + 7.0f * sqrt(5.0f)); + static const float x2 = (1.0f / 11.0f) * (5.0f * sqrt(5.0f) - 9.0f); + static const float x2_2 = x2 / 2.0f; + static const float x3 = (1.0f / 11.0f) * (6.0f * sqrt(5.0f) - 13.0f); + // y1 and y2 are the solutions to the following system of equations (x is the sidelength, but is different than x1 because the scale in the y direction is different): + // 1 = 3 * y1 + 2 * y2 + // y1 = sin(108 deg) * x + // y1 + y2 = x * sqrt(5 + 2 * sqrt(5)) / 2 + static const float y1 = sqrt(2.0f * (5.0f + sqrt(5.0f))) / (sqrt(2.0f * (5.0f + sqrt(5.0f))) + 4.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))); + static const float y2 = -(sqrt(2.0f * (5.0f + sqrt(5.0f))) - 2.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))) / (sqrt(2.0f * (5.0f + sqrt(5.0f))) + 4.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))); + static const Solid<5> DODECAHEDRON = Solid<5>{ { A, B, C, D, E, F, G, H, I, J, -A, -B, -C, -D, -E, -F, -G, -H, -I, -J, }, + { vec2(x1 + x2_2, 0.0f), vec2(x2_2, 0.0f), vec2(x2_2 - x3, y1), vec2(x3 + x1, y1 + y2), vec2(x3 + x1 + x2_2, y1), + vec2(1.0f - (x2 - x3 + x2_2), 0.0f), vec2(1.0f - (x2 + x1 + x3), y2), vec2(1.0f - (x2 + x1), y1 + y2), vec2(1.0f - x2, y1 + y2), vec2(1.0f - (x2 - x3), y2), + vec2(1.0f - x2_2, y1), vec2(1.0f - x2, y1 + y2), vec2(1.0f - (x3 + x1), y1 + y2 + y1), vec2(1.0f - x3, y1 + y2 + y1), vec2(1.0f, y1 + y2), + vec2(x3, y1 + y2), vec2(0.0f, y1 + y2 + y1), vec2(x2_2, y1 + y2 + y1 + y2), vec2(x2, y1 + y2 + y1), vec2(x1 + x3, y1 + y2), + vec2(x3 + x1, y1 + y2), vec2(x2, y1 + y2 + y1), vec2(x2 + x1, y1 + y2 + y1), vec2(x3 + x1 + x2, y1 + y2), vec2(x3 + x1 + x2_2, y1), + vec2(x3 + x1 + x2_2, y1), vec2(x3 + x1 + x2, y1 + y2), vec2(x3 + x1 + x2 + x2_2, y1), vec2(x1 + x2 + x2_2, 0.0f), vec2(x3 + x1 + x2_2 + x3, 0.0f), + vec2(1.0f - (x3 + x1 + x2_2), 1.0f - y1), vec2(1.0f - (x3 + x1 + x2), 1.0f - (y1 + y2)), vec2(1.0f - (x3 + x1 + x2 + x2_2), 1.0f - y1), vec2(1.0f - (x1 + x2 + x2_2), 1.0f), vec2(1.0f - (x3 + x1 + x2_2 + x3), 1.0f), + vec2(x2 + x1 + x3, 1.0f - y2), vec2(x2 + x1, 1.0f - (y1 + y2)), vec2(x2, 1.0f - (y1 + y2)), vec2(x2 - x3, 1.0f - y2), vec2(x2 - x3 + x2_2, 1.0f), + vec2(x2 + x1 + x2, y1 + y2 + y1), vec2(x3 + x1 + x2 + x1, y1 + y2), vec2(x3 + x1 + x2, y1 + y2), vec2(x2 + x1, y1 + y2 + y1), vec2(x2 + x1 + x2_2, y1 + y2 + y1 + y2), + vec2(1.0f - (x3 + x1 + x2), y1 + y2 + y1), vec2(1.0f - (x2 + x1), y1 + y2), vec2(1.0f - (x2 + x1 + x2_2), y1), vec2(1.0f - (x2 + x1 + x2), y1 + y2), vec2(1.0f - (x3 + x1 + x2 + x1), y1 + y2 + y1), + vec2(1.0f - (x3 + x1 + x2_2), y1 + y2 + y1 + y2), vec2(1.0f - (x3 + x1), y1 + y2 + y1), vec2(1.0f - x2, y1 + y2), vec2(1.0f - (x2 + x1), y2 + y1), vec2(1.0f - (x3 + x1 + x2), y1 + y2 + y1), + vec2(1.0f - (x1 + x2_2), 1.0f), vec2(1.0f - x2_2, 1.0f), vec2(1.0f - (x2_2 - x3), 1.0f - y1), vec2(1.0f - (x1 + x3), 1.0f - (y1 + y2)), vec2(1.0f - (x3 + x1 + x2_2), 1.0f - y1) }, FaceVector<5> { Face<5> { { 0, 1, 2, 3, 4 } }, Face<5> { { 0, 5, 18, 6, 1 } }, @@ -148,12 +226,33 @@ const Solid<3>& icosahedron() { static const auto D = vec3(P, 0, N); static const auto E = vec3(P, 0, -N); static const auto F = vec3(0, N, -P); - + static const float THIRD = 1.0f / 3.0f; + static const float ELEVENTH = 1.0f / 11.0f; static const Solid<3> ICOSAHEDRON = Solid<3> { { A, B, C, D, E, F, -A, -B, -C, -D, -E, -F, }, + { vec2(3.0f * ELEVENTH, 0.0f), vec2(2.0f * ELEVENTH, THIRD), vec2(4.0f * ELEVENTH, THIRD), + vec2(2.0f * ELEVENTH, THIRD), vec2(3.0f * ELEVENTH, 2.0f * THIRD), vec2(4.0f * ELEVENTH, THIRD), + vec2(3.0f * ELEVENTH, 2.0f * THIRD), vec2(5.0f * ELEVENTH, 2.0f * THIRD), vec2(4.0f * ELEVENTH, THIRD), + vec2(5.0f * ELEVENTH, 2.0f * THIRD), vec2(6.0f * ELEVENTH, THIRD), vec2(4.0f * ELEVENTH, THIRD), + vec2(6.0f * ELEVENTH, THIRD), vec2(5.0f * ELEVENTH, 0.0f), vec2(4.0f * ELEVENTH, THIRD), + vec2(1.0f * ELEVENTH, 0.0f), vec2(0.0f, THIRD), vec2(2.0f * ELEVENTH, THIRD), + vec2(1.0f * ELEVENTH, 2.0f * THIRD), vec2(2.0f * ELEVENTH, THIRD), vec2(0.0f, THIRD), + vec2(2.0f * ELEVENTH, THIRD), vec2(1.0f * ELEVENTH, 2.0f * THIRD), vec2(3.0f * ELEVENTH, 2.0f * THIRD), + vec2(2.0f * ELEVENTH, 1.0f), vec2(3.0f * ELEVENTH, 2.0f * THIRD), vec2(1.0f * ELEVENTH, 2.0f * THIRD), + vec2(3.0f * ELEVENTH, 2.0f * THIRD), vec2(4.0f * ELEVENTH, 1.0f), vec2(5.0f * ELEVENTH, 2.0f * THIRD), + vec2(7.0f * ELEVENTH, 2.0f * THIRD), vec2(5.0f * ELEVENTH, 2.0f * THIRD), vec2(6.0f * ELEVENTH, 1.0f), + vec2(5.0f * ELEVENTH, 2.0f * THIRD), vec2(7.0f * ELEVENTH, 2.0f * THIRD), vec2(6.0f * ELEVENTH, THIRD), + vec2(8.0f * ELEVENTH, THIRD), vec2(6.0f * ELEVENTH, THIRD), vec2(7.0f * ELEVENTH, 2.0f * THIRD), + vec2(6.0f * ELEVENTH, THIRD), vec2(8.0f * ELEVENTH, THIRD), vec2(7.0f * ELEVENTH, 0.0f), + vec2(10.0f * ELEVENTH, THIRD), vec2(9.0f * ELEVENTH, 0.0f), vec2(8.0f * ELEVENTH, THIRD), + vec2(7.0f * ELEVENTH, 2.0f * THIRD), vec2(8.0f * ELEVENTH, 1.0f), vec2(9.0f * ELEVENTH, 2.0f * THIRD), + vec2(8.0f * ELEVENTH, THIRD), vec2(7.0f * ELEVENTH, 2.0f * THIRD), vec2(9.0f * ELEVENTH, 2.0f * THIRD), + vec2(10.0f * ELEVENTH, THIRD), vec2(8.0f * ELEVENTH, THIRD), vec2(9.0f * ELEVENTH, 2.0f * THIRD), + vec2(1.0f, 2.0f * THIRD), vec2(10.0f * ELEVENTH, THIRD), vec2(9.0f * ELEVENTH, 2.0f * THIRD), + vec2(10.0f * ELEVENTH, 1.0f), vec2(1.0f, 2.0f * THIRD), vec2(9.0f * ELEVENTH, 2.0f * THIRD) }, FaceVector<3> { Face<3> { { 1, 2, 0 } }, Face<3> { { 2, 3, 0 } }, diff --git a/libraries/shared/src/shared/Shapes.h b/libraries/shared/src/shared/Shapes.h index 3486a0a663..6bd2eab199 100644 --- a/libraries/shared/src/shared/Shapes.h +++ b/libraries/shared/src/shared/Shapes.h @@ -22,6 +22,7 @@ namespace geometry { using Index = uint32_t; using Vec = glm::vec3; using VertexVector = std::vector; + using TexCoordVector = std::vector; using IndexVector = std::vector; template @@ -33,6 +34,7 @@ namespace geometry { template struct Solid { VertexVector vertices; + TexCoordVector texCoords; FaceVector faces; Solid& fitDimension(float newMaxDimension) { From 96e48a01621d45093b05da7aa597429878e2d928 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 7 Mar 2018 13:16:13 -0800 Subject: [PATCH 05/44] warnings --- .../src/RenderableMaterialEntityItem.cpp | 2 +- .../src/RenderableShapeEntityItem.cpp | 9 +++++---- libraries/render-utils/src/GeometryCache.cpp | 3 +-- libraries/shared/src/shared/Shapes.cpp | 14 +++++++------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 8566b9bae8..ea8edb8a08 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -123,5 +123,5 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { // Draw! DependencyManager::get()->renderSphere(batch); - args->_details._trianglesRendered += DependencyManager::get()->getSphereTriangleCount(); + args->_details._trianglesRendered += (int)DependencyManager::get()->getSphereTriangleCount(); } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index b14e201366..0e04ae3418 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -138,11 +138,12 @@ ItemKey ShapeEntityRenderer::getKey() { } bool ShapeEntityRenderer::useMaterialPipeline() const { - withReadLock([&] { - if (_procedural.isReady()) { - return false; - } + bool proceduralReady = resultWithReadLock([&] { + return _procedural.isReady(); }); + if (proceduralReady) { + return false; + } graphics::MaterialKey drawMaterialKey; auto mat = _materials.find("0"); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 61fcdafd39..edd68603cb 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -401,7 +401,7 @@ vec2 calculateSphereTexCoord(const vec3& vertex) { } vec3 calculateSphereTangent(float u) { - float phi = u * M_PI * 2.0f; + float phi = u * (float)M_PI * 2.0f; return -glm::normalize(glm::vec3(glm::sin(phi), 0.0f, glm::cos(phi))); } @@ -414,7 +414,6 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid for (const auto& vertex : shape.vertices) { addVec3ToVector(vertices, vertex); addVec3ToVector(vertices, vertex); - vec2 uv = calculateSphereTexCoord(vertex); addVec2ToVector(vertices, calculateSphereTexCoord(vertex)); // We'll fill in the correct tangents later, once we correct the UVs addVec3ToVector(vertices, vec3(0.0f)); diff --git a/libraries/shared/src/shared/Shapes.cpp b/libraries/shared/src/shared/Shapes.cpp index 277154d6b6..afcf956165 100644 --- a/libraries/shared/src/shared/Shapes.cpp +++ b/libraries/shared/src/shared/Shapes.cpp @@ -22,7 +22,7 @@ Solid<3> tesselate(const Solid<3>& solid_, int count) { Solid<3> solid = solid_; float length = glm::length(solid.vertices[0]); for (int i = 0; i < count; ++i) { - Solid<3> result { solid.vertices, {} }; + Solid<3> result { solid.vertices, {}, {} }; result.vertices.reserve(solid.vertices.size() + solid.faces.size() * 6); for (size_t f = 0; f < solid.faces.size(); ++f) { Index baseVertex = (Index)result.vertices.size(); @@ -171,16 +171,16 @@ const Solid<5>& dodecahedron() { // 1 = 3 * x1 + 3 * x2 + x3 // x1 + 2 * x3 = (golden ratio) * x1 // x2 = x1 + 2 * x3 - static const float x1 = 4.0f / (17.0f + 7.0f * sqrt(5.0f)); - static const float x2 = (1.0f / 11.0f) * (5.0f * sqrt(5.0f) - 9.0f); + static const float x1 = 4.0f / (17.0f + 7.0f * sqrtf(5.0f)); + static const float x2 = (1.0f / 11.0f) * (5.0f * sqrtf(5.0f) - 9.0f); static const float x2_2 = x2 / 2.0f; - static const float x3 = (1.0f / 11.0f) * (6.0f * sqrt(5.0f) - 13.0f); + static const float x3 = (1.0f / 11.0f) * (6.0f * sqrtf(5.0f) - 13.0f); // y1 and y2 are the solutions to the following system of equations (x is the sidelength, but is different than x1 because the scale in the y direction is different): // 1 = 3 * y1 + 2 * y2 // y1 = sin(108 deg) * x - // y1 + y2 = x * sqrt(5 + 2 * sqrt(5)) / 2 - static const float y1 = sqrt(2.0f * (5.0f + sqrt(5.0f))) / (sqrt(2.0f * (5.0f + sqrt(5.0f))) + 4.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))); - static const float y2 = -(sqrt(2.0f * (5.0f + sqrt(5.0f))) - 2.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))) / (sqrt(2.0f * (5.0f + sqrt(5.0f))) + 4.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))); + // y1 + y2 = x * sqrtf(5 + 2 * sqrtf(5)) / 2 + static const float y1 = sqrtf(2.0f * (5.0f + sqrtf(5.0f))) / (sqrtf(2.0f * (5.0f + sqrtf(5.0f))) + 4.0f * sqrtf(5.0f + 2.0f * sqrtf(5.0f))); + static const float y2 = -(sqrtf(2.0f * (5.0f + sqrtf(5.0f))) - 2.0f * sqrtf(5.0f + 2.0f * sqrtf(5.0f))) / (sqrtf(2.0f * (5.0f + sqrtf(5.0f))) + 4.0f * sqrtf(5.0f + 2.0f * sqrtf(5.0f))); static const Solid<5> DODECAHEDRON = Solid<5>{ { From 2158acecf4941be566cd599f35a4d69d75989545 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 8 Mar 2018 12:39:40 -0800 Subject: [PATCH 06/44] tell cmake we are fine ignoring generated for CMP0071 --- interface/CMakeLists.txt | 11 +++++++---- libraries/render-utils/CMakeLists.txt | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 3ed5445493..3d33b9929b 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -318,13 +318,13 @@ if (APPLE) else() # copy the resources files beside the executable add_custom_command(TARGET ${TARGET_NAME} POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E copy_if_different - "${RESOURCES_RCC}" + COMMAND "${CMAKE_COMMAND}" -E copy_if_different + "${RESOURCES_RCC}" "$" # 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 - # the ttf files, but doing so generates a CORS policy violation, + # we should be able to modify the CSS to reference the QRC path to + # the ttf files, but doing so generates a CORS policy violation, # 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" @@ -379,3 +379,6 @@ endif() add_dependency_external_projects(GifCreator) find_package(GifCreator REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GIFCREATOR_INCLUDE_DIRS}) + +# tell CMake to exclude ui_console.h for policy CMP0071 +set_property(SOURCE ui_console.h PROPERTY SKIP_AUTOMOC ON) diff --git a/libraries/render-utils/CMakeLists.txt b/libraries/render-utils/CMakeLists.txt index 7fece45b2f..319b6ad415 100644 --- a/libraries/render-utils/CMakeLists.txt +++ b/libraries/render-utils/CMakeLists.txt @@ -8,6 +8,9 @@ include_hifi_library_headers(audio) include_hifi_library_headers(networking) include_hifi_library_headers(octree) +# tell CMake to exclude qrc_fonts.cpp for policy CMP0071 +set_property(SOURCE qrc_fonts.cpp PROPERTY SKIP_AUTOMOC ON) + if (NOT ANDROID) target_nsight() endif () From 1fb68ec5ca7453ae9f3d6d99d5bdcafe51933645 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Thu, 8 Mar 2018 23:07:12 +0300 Subject: [PATCH 07/44] FB12956 - Audio Meter Toggle Button Broken --- .../qml/{AvatarInputs.qml => AvatarInputsBar.qml} | 6 +++--- interface/src/Application.cpp | 7 +++++-- interface/src/ui/AvatarInputs.cpp | 10 +++++----- interface/src/ui/AvatarInputs.h | 4 ++-- 4 files changed, 15 insertions(+), 12 deletions(-) rename interface/resources/qml/{AvatarInputs.qml => AvatarInputsBar.qml} (88%) diff --git a/interface/resources/qml/AvatarInputs.qml b/interface/resources/qml/AvatarInputsBar.qml similarity index 88% rename from interface/resources/qml/AvatarInputs.qml rename to interface/resources/qml/AvatarInputsBar.qml index be4bf03465..a88a42080e 100644 --- a/interface/resources/qml/AvatarInputs.qml +++ b/interface/resources/qml/AvatarInputsBar.qml @@ -14,9 +14,9 @@ import Qt.labs.settings 1.0 import "./hifi/audio" as HifiAudio -Hifi.AvatarInputs { +Item { id: root; - objectName: "AvatarInputs" + objectName: "AvatarInputsBar" property int modality: Qt.NonModal width: audio.width; height: audio.height; @@ -26,7 +26,7 @@ Hifi.AvatarInputs { HifiAudio.MicBar { id: audio; - visible: root.showAudioTools; + visible: AvatarInputs.showAudioTools; standalone: true; dragTarget: parent; } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 719fbf4ae8..d3b19fba5d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2710,6 +2710,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) { surfaceContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor()); + surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); surfaceContext->setContextProperty("Selection", DependencyManager::get().data()); surfaceContext->setContextProperty("ContextOverlay", DependencyManager::get().data()); surfaceContext->setContextProperty("Wallet", DependencyManager::get().data()); @@ -2723,10 +2724,12 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) { void Application::onDesktopRootItemCreated(QQuickItem* rootItem) { Stats::show(); - AvatarInputs::show(); auto surfaceContext = DependencyManager::get()->getSurfaceContext(); surfaceContext->setContextProperty("Stats", Stats::getInstance()); - surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); + + auto offscreenUi = DependencyManager::get(); + auto qml = PathUtils::qmlUrl("AvatarInputsBar.qml"); + offscreenUi->show(qml, "AvatarInputsBar"); } void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { diff --git a/interface/src/ui/AvatarInputs.cpp b/interface/src/ui/AvatarInputs.cpp index 51d1c9bf6b..3053cb8855 100644 --- a/interface/src/ui/AvatarInputs.cpp +++ b/interface/src/ui/AvatarInputs.cpp @@ -16,19 +16,19 @@ #include "Application.h" #include "Menu.h" -HIFI_QML_DEF(AvatarInputs) - static AvatarInputs* INSTANCE{ nullptr }; Setting::Handle showAudioToolsSetting { QStringList { "AvatarInputs", "showAudioTools" }, false }; AvatarInputs* AvatarInputs::getInstance() { - Q_ASSERT(INSTANCE); + if (!INSTANCE) { + INSTANCE = new AvatarInputs(); + Q_ASSERT(INSTANCE); + } return INSTANCE; } -AvatarInputs::AvatarInputs(QQuickItem* parent) : QQuickItem(parent) { - INSTANCE = this; +AvatarInputs::AvatarInputs(QObject* parent) : QObject(parent) { _showAudioTools = showAudioToolsSetting.get(); } diff --git a/interface/src/ui/AvatarInputs.h b/interface/src/ui/AvatarInputs.h index fb48df9d73..47f520a639 100644 --- a/interface/src/ui/AvatarInputs.h +++ b/interface/src/ui/AvatarInputs.h @@ -19,7 +19,7 @@ public: \ private: \ type _##name{ initialValue }; -class AvatarInputs : public QQuickItem { +class AvatarInputs : public QObject { Q_OBJECT HIFI_QML_DECL @@ -32,7 +32,7 @@ class AvatarInputs : public QQuickItem { public: static AvatarInputs* getInstance(); Q_INVOKABLE float loudnessToAudioLevel(float loudness); - AvatarInputs(QQuickItem* parent = nullptr); + AvatarInputs(QObject* parent = nullptr); void update(); bool showAudioTools() const { return _showAudioTools; } From c8b4217a962b12a16d9df9efad22d9c601d7a62a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Mar 2018 12:57:23 +1300 Subject: [PATCH 08/44] Fix Window.hasFocus() --- interface/src/Application.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2b77cb8950..cffb390644 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7347,10 +7347,14 @@ bool Application::isThrottleRendering() const { } bool Application::hasFocus() const { - if (_displayPlugin) { - return getActiveDisplayPlugin()->hasFocus(); - } - return (QApplication::activeWindow() != nullptr); + bool result = (QApplication::activeWindow() != nullptr); +#if defined(Q_OS_WIN) + // On Windows, QWidget::activateWindow() - as called in setFocus() - makes the application's taskbar icon flash but doesn't + // take user focus away from their current window. So also check whether the application is the user's current foreground + // window. + result = result && (HWND)QApplication::activeWindow()->winId() == GetForegroundWindow(); +#endif + return result; } void Application::setFocus() { From 025d2807f47a2b1a5d2006513a11e67330bc46fb Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Mar 2018 12:59:27 +1300 Subject: [PATCH 09/44] Fix Window.setFocus() JSDoc --- interface/src/scripting/WindowScriptingInterface.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 5a30f44856..dfe117b239 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -62,7 +62,8 @@ public slots: QScriptValue hasFocus(); /**jsdoc - * Make the Interface window have focus. + * Make the Interface window have focus. On Windows, if Interface doesn't already have focus, the task bar icon flashes to + * indicate that Interface wants attention but focus isn't taken away from the application that the user is using. * @function Window.setFocus */ void setFocus(); From 966d711e56f7f7585290fef3a11ef4dca67eb9b1 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Mar 2018 13:38:48 +1300 Subject: [PATCH 10/44] Fix Window.raiseMainWindow() --- interface/src/Application.cpp | 17 ++++++++++++++--- interface/src/Application.h | 1 + .../src/scripting/WindowScriptingInterface.cpp | 2 +- .../src/scripting/WindowScriptingInterface.h | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cffb390644..e3168f228a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7362,9 +7362,20 @@ void Application::setFocus() { // flashes the taskbar icon. auto window = qApp->getWindow(); window->activateWindow(); - - // Do NOT do the following because it takes focus away from the _displayPlugin. - //window->setFocus(); +} + +void Application::raise() { + auto windowState = qApp->getWindow()->windowState(); + if (windowState & Qt::WindowMinimized) { + if (windowState & Qt::WindowMaximized) { + qApp->getWindow()->showMaximized(); + } else if (windowState & Qt::WindowFullScreen) { + qApp->getWindow()->showFullScreen(); + } else { + qApp->getWindow()->showNormal(); + } + } + qApp->getWindow()->raise(); } void Application::setMaxOctreePacketsPerSecond(int maxOctreePPS) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 7339257bba..1420d5b056 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -162,6 +162,7 @@ public: glm::vec2 getDeviceSize() const; bool hasFocus() const; void setFocus(); + void raise(); void showCursor(const Cursor::Icon& cursor); diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index ffd2a76318..4cedfb5a34 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -81,7 +81,7 @@ void WindowScriptingInterface::setFocus() { void WindowScriptingInterface::raiseMainWindow() { // It's forbidden to call raise() from another thread. qApp->postLambdaEvent([] { - qApp->getWindow()->raise(); + qApp->raise(); }); } diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index dfe117b239..2a9806a302 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -69,7 +69,7 @@ public slots: void setFocus(); /**jsdoc - * Raise the Interface window if it is minimized, and give it focus. + * Raise the Interface window if it is minimized. If raised, the window gains focus. * @function Window.raiseMainWindow */ void raiseMainWindow(); From c1e256a4f39725446f1478355ac5b28f057e2cb1 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Mar 2018 13:58:00 +1300 Subject: [PATCH 11/44] Remove unused methods --- .../src/display-plugins/NullDisplayPlugin.cpp | 4 ---- .../display-plugins/src/display-plugins/NullDisplayPlugin.h | 1 - .../src/display-plugins/OpenGLDisplayPlugin.cpp | 5 ----- .../src/display-plugins/OpenGLDisplayPlugin.h | 2 -- libraries/plugins/src/plugins/DisplayPlugin.h | 3 --- 5 files changed, 15 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp index 6a19a34727..47a213cf71 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp @@ -21,10 +21,6 @@ glm::uvec2 NullDisplayPlugin::getRecommendedRenderSize() const { return glm::uvec2(100, 100); } -bool NullDisplayPlugin::hasFocus() const { - return false; -} - void NullDisplayPlugin::submitFrame(const gpu::FramePointer& frame) { if (frame) { _gpuContext->consumeFrameUpdates(frame); diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h index 97b71b5780..11563b3798 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h @@ -16,7 +16,6 @@ public: grouping getGrouping() const override { return DEVELOPER; } glm::uvec2 getRecommendedRenderSize() const override; - bool hasFocus() const override; void submitFrame(const gpu::FramePointer& newFrame) override; QImage getScreenshot(float aspectRatio = 0.0f) const override; QImage getSecondaryCameraScreenshot() const override; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 9bd7d89634..c4b26e80de 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -828,11 +828,6 @@ glm::uvec2 OpenGLDisplayPlugin::getSurfaceSize() const { return result; } -bool OpenGLDisplayPlugin::hasFocus() const { - auto window = _container->getPrimaryWidget(); - return window ? window->hasFocus() : false; -} - void OpenGLDisplayPlugin::assertNotPresentThread() const { Q_ASSERT(QThread::currentThread() != _presentThread); } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index bf06486095..ec8d6df2d1 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -98,8 +98,6 @@ protected: virtual void compositePointer(); virtual void compositeExtra() {}; - virtual bool hasFocus() const override; - // These functions must only be called on the presentation thread virtual void customizeContext(); virtual void uncustomizeContext(); diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 2c717f629c..25f4b247da 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -142,9 +142,6 @@ public: virtual void setContext(const gpu::ContextPointer& context) final { _gpuContext = context; } virtual void submitFrame(const gpu::FramePointer& newFrame) = 0; - // Does the rendering surface have current focus? - virtual bool hasFocus() const = 0; - // The size of the rendering target (may be larger than the device size due to distortion) virtual glm::uvec2 getRecommendedRenderSize() const = 0; From 21381a7295bb5efdc08b125f54b7180f1485da2f Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 14 Mar 2018 11:44:00 -0700 Subject: [PATCH 12/44] fix building with gles on desktop (still crashes) --- plugins/oculus/CMakeLists.txt | 2 +- tests/render-perf/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/oculus/CMakeLists.txt b/plugins/oculus/CMakeLists.txt index 638cadf574..893b7f48b1 100644 --- a/plugins/oculus/CMakeLists.txt +++ b/plugins/oculus/CMakeLists.txt @@ -19,7 +19,7 @@ if (WIN32 AND (NOT USE_GLES)) set(TARGET_NAME oculus) setup_hifi_plugin(Multimedia) link_hifi_libraries( - shared task gl gpu gpu-gl controllers ui qml + shared task gl gpu ${PLATFORM_GL_BACKEND} controllers ui qml plugins ui-plugins display-plugins input-plugins audio-client networking render-utils ${PLATFORM_GL_BACKEND} diff --git a/tests/render-perf/CMakeLists.txt b/tests/render-perf/CMakeLists.txt index 66ca28f7db..fd4d8d88dd 100644 --- a/tests/render-perf/CMakeLists.txt +++ b/tests/render-perf/CMakeLists.txt @@ -14,7 +14,7 @@ set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries link_hifi_libraries( shared task networking animation - ktx image octree gl gpu gpu-gl + ktx image octree gl gpu ${PLATFORM_GL_BACKEND} render render-utils graphics fbx model-networking graphics-scripting entities entities-renderer audio avatars script-engine From d67044f220d47791a5ff18d6caa04356b942ea53 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 14 Mar 2018 13:32:48 -0700 Subject: [PATCH 13/44] EntityScriptServer should wait for script engine to finish when stopping Script engine will still running and using EntityEditPacketSender, which is owned by EntityScriptServer, which was destroyed. https://highfidelity.manuscript.com/f/cases/11071/ --- assignment-client/src/scripts/EntityScriptServer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 60cb1e349b..8276807be7 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -476,6 +476,7 @@ void EntityScriptServer::clear() { // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread _entitiesScriptEngine->unloadAllEntityScripts(); _entitiesScriptEngine->stop(); + _entitiesScriptEngine->waitTillDoneRunning(); } _entityViewer.clear(); From 2fe9f6df6f9bbfc6f5abb04818167c40fdd9aca5 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 14 Mar 2018 12:15:02 -0700 Subject: [PATCH 14/44] Add google analytics to installer --- INSTALL.md | 2 + cmake/macros/SetPackagingParameters.cmake | 1 + cmake/templates/CPackProperties.cmake.in | 2 + cmake/templates/NSIS.template.in | 154 +++++++++++++++++++--- 4 files changed, 141 insertions(+), 18 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 79d7e96977..e07d28a43d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -17,6 +17,8 @@ To produce an executable installer on Windows, the following are required: - [Nullsoft Scriptable Install System](http://nsis.sourceforge.net/Download) - 3.0b3 - [UAC Plug-in for Nullsoft](http://nsis.sourceforge.net/UAC_plug-in) - 0.2.4c - [nsProcess Plug-in for Nullsoft](http://nsis.sourceforge.net/NsProcess_plugin) - 1.6 +- [Inetc Plug-in for Nullsoft](http://nsis.sourceforge.net/Inetc_plug-in) - 1.0 +- [NSISpcre Plug-in for Nullsoft](http://nsis.sourceforge.net/NSISpcre_plug-in) - 1.0 Run the `package` target to create an executable installer using the Nullsoft Scriptable Install System. diff --git a/cmake/macros/SetPackagingParameters.cmake b/cmake/macros/SetPackagingParameters.cmake index e26f81edd9..3ca72b473b 100644 --- a/cmake/macros/SetPackagingParameters.cmake +++ b/cmake/macros/SetPackagingParameters.cmake @@ -149,6 +149,7 @@ macro(SET_PACKAGING_PARAMETERS) set(CLIENT_LAUNCH_NOW_REG_KEY "ClientLaunchAfterInstall") set(SERVER_LAUNCH_NOW_REG_KEY "ServerLaunchAfterInstall") set(CUSTOM_INSTALL_REG_KEY "CustomInstall") + set(CLIENT_ID_REG_KEY "ClientGUID") endif () # setup component categories for installer diff --git a/cmake/templates/CPackProperties.cmake.in b/cmake/templates/CPackProperties.cmake.in index b91d78f628..1a0fa2fac7 100644 --- a/cmake/templates/CPackProperties.cmake.in +++ b/cmake/templates/CPackProperties.cmake.in @@ -41,6 +41,8 @@ set(CONSOLE_STARTUP_REG_KEY "@CONSOLE_STARTUP_REG_KEY@") set(SERVER_LAUNCH_NOW_REG_KEY "@SERVER_LAUNCH_NOW_REG_KEY@") set(CLIENT_LAUNCH_NOW_REG_KEY "@CLIENT_LAUNCH_NOW_REG_KEY@") set(CUSTOM_INSTALL_REG_KEY "@CUSTOM_INSTALL_REG_KEY@") +set(GA_TRACKING_ID "@GA_TRACKING_ID@") +set(CLIENT_ID_REG_KEY "@CLIENT_ID_REG_KEY@") set(INSTALLER_HEADER_IMAGE "@INSTALLER_HEADER_IMAGE@") set(UNINSTALLER_HEADER_IMAGE "@UNINSTALLER_HEADER_IMAGE@") set(ADD_REMOVE_ICON_PATH "@ADD_REMOVE_ICON_PATH@") diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index c1bfebe2c4..4f9cb0d818 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -319,6 +319,87 @@ Function DownloadFile FunctionEnd !endif + +!include NSISpcre.nsh +!insertmacro REMatches + +Var CampaignName + +!macro GetCampaignName RetVar + Call GetCampaignName + Pop ${RetVar} +!macroend + +Function GetCampaignName + Push $0 ; Stash $0 + + ; Parse filename out of the path + ${RECaptureMatches} $0 "([^\\]*\\)*(.*)\.exe" $EXEPATH 0 + ${If} $0 == 2 + Pop $0 ; Discard Path + Pop $0 ; Recover filename + ; Parse campaign out of the filename + ${RECaptureMatches} $0 "HighFidelity-([^-]*-)Beta-.*" $0 0 + ${If} $0 == 1 + Pop $0 ; Recover campaign name + StrCpy $0 $0 -1 0 ; Remove trailing - and copy to _RetVar + ${Else} + StrCpy $0 "" + ${EndIf} + ${Else} + StrCpy $0 "" + ${EndIf} + + Exch $0 ; Restore $0 and push result +FunctionEnd + +!macro CreateGUID RetVar + System::Call 'ole32::CoCreateGuid(g .s)' + Pop ${RetVar} + ; Strip opening and closing braces + StrCpy ${RetVar} ${RetVar} -1 1 +!macroend + +Var GAClientID + +!macro InitGAClientID + ; Generate a new GUID on every run for now + !insertmacro CreateGUID $GAClientID + + ; Push $0 + ; ReadRegStr $GAClientID HKLM "@REGISTRY_HKLM_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "@CLIENT_ID_REG_KEY@" + ; ${REMatches} $0 "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" $GAClientID 0 + ; ${If} $0 == false + ; !insertmacro CreateGUID $GAClientID + ; WriteRegStr HKLM "@REGISTRY_HKLM_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "@CLIENT_ID_REG_KEY@" $GAClientID + ; ${EndIf} + ; Pop $0 +!macroend + +!macro GoogleAnalytics Category Action Label Value + ${If} "@GA_TRACKING_ID@" != "" + Push $0 + Push $1 + + StrCpy $0 "https://google-analytics.com/collect?v=1&tid=@GA_TRACKING_ID@" + StrCpy $0 "$0&cid=$GAClientID&t=event&ec=${Category}&ea=${Action}" + + ${If} "${Label}" != "" + StrCpy $0 "$0&el=${Label}" + ${EndIf} + ${If} "${Value}" != "" + StrCpy $0 "$0&ev=${Value}" + ${EndIf} + + GetTempFileName $1 + inetc::get /SILENT $0 $1 /END + Delete $1 + + Pop $1 + Pop $0 + ${EndIf} +!macroend + ;-------------------------------- ; Installation types @@ -342,28 +423,32 @@ SectionEnd ;-------------------------------- ;Pages + !define MUI_CUSTOMFUNCTION_ABORT OnUserAbort + + !define MUI_PAGE_CUSTOMFUNCTION_PRE PageWelcomePre !insertmacro MUI_PAGE_WELCOME + !define MUI_PAGE_CUSTOMFUNCTION_PRE PageLicensePre !insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@" Page custom InstallTypesPage ReadInstallTypes - !define MUI_PAGE_CUSTOMFUNCTION_PRE AbortFunction + !define MUI_PAGE_CUSTOMFUNCTION_PRE PageDirectoryPre !insertmacro MUI_PAGE_DIRECTORY ;Start Menu Folder Page Configuration !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM" !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" - - !define MUI_PAGE_CUSTOMFUNCTION_PRE AbortFunction + !define MUI_PAGE_CUSTOMFUNCTION_PRE PageStartMenuPre !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER - !define MUI_PAGE_CUSTOMFUNCTION_PRE AbortFunction + !define MUI_PAGE_CUSTOMFUNCTION_PRE PageComponentsPre @CPACK_NSIS_PAGE_COMPONENTS@ Page custom PostInstallOptionsPage ReadPostInstallOptions + !define MUI_PAGE_CUSTOMFUNCTION_PRE PageInstallFilesPre !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_UNPAGE_CONFIRM @@ -452,8 +537,40 @@ Var CopyFromProductionCheckbox Var ExpressInstallRadioButton Var CustomInstallRadioButton Var InstallTypeDialog -Var Express Var CustomInstallTemporaryState +Var Express + +!macro MaybeSkipPage + ; Check if Express is set, if so, abort the post install options page + ${If} $Express == "1" + Abort + ${EndIf} +!macroend + +Function OnUserAbort + !insertmacro GoogleAnalytics "Installer" "Abort" "User Abort" "" +FunctionEnd +Function PageWelcomePre + !insertmacro GoogleAnalytics "Installer" "Welcome" "" "" +FunctionEnd +Function PageLicensePre + !insertmacro GoogleAnalytics "Installer" "License" "" "" +FunctionEnd +Function PageDirectoryPre + !insertmacro MaybeSkipPage + !insertmacro GoogleAnalytics "Installer" "Directory" "" "" +FunctionEnd +Function PageStartMenuPre + !insertmacro MaybeSkipPage + !insertmacro GoogleAnalytics "Installer" "StartMenu" "" "" +FunctionEnd +Function PageComponentsPre + !insertmacro MaybeSkipPage + !insertmacro GoogleAnalytics "Installer" "Components" "" "" +FunctionEnd +Function PageInstallFilesPre + !insertmacro GoogleAnalytics "Installer" "Install" "" "" +FunctionEnd !macro SetInstallOption Checkbox OptionName Default ; reads the value for the given install option to the registry @@ -472,6 +589,8 @@ Var CustomInstallTemporaryState !macroend Function InstallTypesPage + !insertmacro GoogleAnalytics "Installer" "Install Types" "" "" + !insertmacro MUI_HEADER_TEXT "Choose Installation Type" "Express or Custom Install" nsDialogs::Create 1018 @@ -523,14 +642,10 @@ Function ChangeCustomLabel Pop $R1 FunctionEnd -Function AbortFunction - ; Check if Express is set, if so, abort the post install options page - StrCmp $Express "1" 0 end - Abort - end: -FunctionEnd - Function PostInstallOptionsPage + !insertmacro MaybeSkipPage + !insertmacro GoogleAnalytics "Installer" "Post Install Options" "" "" + !insertmacro MUI_HEADER_TEXT "Setup Options" "" nsDialogs::Create 1018 @@ -540,11 +655,6 @@ Function PostInstallOptionsPage Abort ${EndIf} - ; Check if Express is set, if so, abort the post install options page - StrCmp $Express "1" 0 end - Abort - end: - StrCpy $CurrentOffset 0 StrCpy $OffsetUnits u @@ -965,6 +1075,7 @@ Section "-Core installation" ; Handle whichever post install options were set Call HandlePostInstallOptions + !insertmacro GoogleAnalytics "Installer" "Done" "" "" SectionEnd !include nsProcess.nsh @@ -979,7 +1090,7 @@ SectionEnd ${If} $R0 == 0 ; the process is running, ask the user to close it - + ${If} "${displayName}" == "@CONSOLE_DISPLAY_NAME@" MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION \ "${displayName} cannot be ${action} while ${displayName} is running.$\r$\nPlease close it in the system tray and click Retry to continue." \ @@ -992,6 +1103,8 @@ SectionEnd /SD IDCANCEL IDRETRY Prompt_${UniqueID} IDCANCEL 0 ${EndIf} + !insertmacro GoogleAnalytics "Installer" "Abort" "AppRunning" "${displayName}" + ; If the user decided to cancel, stop the current installer/uninstaller Abort @@ -1219,6 +1332,11 @@ Function .onInit Quit !endif + !insertmacro InitGAClientID + !insertmacro GetCampaignName $CampaignName + + !insertmacro GoogleAnalytics "Installer" "Start" "$CampaignName" "" + ; make sure none of the installed applications are still running !insertmacro CheckForRunningApplications "installed" "Installer" ${nsProcess::Unload} From 4fd6eb559bda55ecc7869174fa50bf4dabc8e8ca Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 14 Mar 2018 17:06:38 -0700 Subject: [PATCH 15/44] Remove dangling packet sender pointer before it's invalid. --- assignment-client/src/scripts/EntityScriptServer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 8276807be7..1255c18e71 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -566,8 +566,15 @@ void EntityScriptServer::handleOctreePacket(QSharedPointer mess void EntityScriptServer::aboutToFinish() { shutdownScriptEngine(); + auto entityScriptingInterface = DependencyManager::get(); // our entity tree is going to go away so tell that to the EntityScriptingInterface - DependencyManager::get()->setEntityTree(nullptr); + entityScriptingInterface->setEntityTree(nullptr); + + // Should always be true as they are singletons. + if (entityScriptingInterface->getPacketSender() == &_entityEditSender) { + // The packet sender is about to go away. + entityScriptingInterface->setPacketSender(nullptr); + } DependencyManager::get()->cleanup(); From 10dd16ae8d53ff0216cb50a4f4a9314ac6d78ff5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 14 Mar 2018 17:09:20 -0700 Subject: [PATCH 16/44] remove VS redist handling from NSIS template --- cmake/templates/NSIS.template.in | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index c1bfebe2c4..d175fb29c5 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -837,9 +837,6 @@ Section "-Core installation" Delete "$INSTDIR\ui_resources_200_percent.pak" Delete "$INSTDIR\vccorlib120.dll" Delete "$INSTDIR\version" - Delete "$INSTDIR\msvcr140.dll" - Delete "$INSTDIR\msvcp140.dll" - Delete "$INSTDIR\vcruntime140.dll" Delete "$INSTDIR\xinput1_3.dll" ; Delete old desktop shortcuts before they were renamed during Sandbox rename @@ -858,12 +855,6 @@ Section "-Core installation" ; Rename the incorrectly cased Raleway font Rename "$INSTDIR\resources\qml\styles-uit\RalewaySemibold.qml" "$INSTDIR\resources\qml\styles-uit\RalewaySemiBold.qml" - ExecWait "$INSTDIR\vcredist_x64.exe /install /q /norestart" - - ; Remove the Old Interface directory and vcredist_x64.exe (from installs prior to Server Console) - RMDir /r "$INSTDIR\Interface" - Delete "$INSTDIR\vcredist_x64.exe" - ;Use the entire tree produced by the INSTALL target. Keep the ;list of directories here in sync with the RMDir commands below. SetOutPath "$INSTDIR" From bee8899c461ef2cca5e1985746bfe22d1d38f9a7 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 15 Mar 2018 12:17:21 -0700 Subject: [PATCH 17/44] Add support for uploading .content.zip files --- domain-server/src/DomainServer.cpp | 22 ++++++-------- domain-server/src/DomainServer.h | 2 +- interface/src/Application.cpp | 32 +++++++++----------- interface/src/Application.h | 2 +- libraries/networking/src/udt/PacketHeaders.h | 4 +-- 5 files changed, 28 insertions(+), 34 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index ce672be604..4fadedb773 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -727,7 +727,7 @@ void DomainServer::setupNodeListAndAssignments() { packetReceiver.registerListener(PacketType::OctreeDataPersist, this, "processOctreeDataPersistMessage"); packetReceiver.registerListener(PacketType::OctreeFileReplacement, this, "handleOctreeFileReplacementRequest"); - packetReceiver.registerListener(PacketType::OctreeFileReplacementFromUrl, this, "handleOctreeFileReplacementFromURLRequest"); + packetReceiver.registerListener(PacketType::DomainContentReplacementFromUrl, this, "handleDomainContentReplacementFromURLRequest"); // set a custom packetVersionMatch as the verify packet operator for the udt::Socket nodeList->setPacketFilterOperator(&DomainServer::isPacketVerified); @@ -736,7 +736,6 @@ void DomainServer::setupNodeListAndAssignments() { auto assetClient = DependencyManager::set(); assetClient->moveToThread(&_assetClientThread); _assetClientThread.start(); - // add whatever static assignments that have been parsed to the queue addStaticAssignmentsToQueue(); } @@ -3429,13 +3428,10 @@ void DomainServer::handleOctreeFileReplacement(QByteArray octreeFile) { } } -void DomainServer::handleOctreeFileReplacementFromURLRequest(QSharedPointer message) { +void DomainServer::handleDomainContentReplacementFromURLRequest(QSharedPointer message) { qInfo() << "Received request to replace content from a url"; auto node = DependencyManager::get()->findNodeWithAddr(message->getSenderSockAddr()); - if (node) { - qDebug() << "Found node: " << node->getCanReplaceContent(); - } - if (node->getCanReplaceContent()) { + if (node && node->getCanReplaceContent()) { // Convert message data into our URL QString url(message->getMessage()); QUrl modelsURL = QUrl(url, QUrl::StrictMode); @@ -3448,7 +3444,12 @@ void DomainServer::handleOctreeFileReplacementFromURLRequest(QSharedPointererror(); if (networkError == QNetworkReply::NoError) { - handleOctreeFileReplacement(reply->readAll()); + if (modelsURL.fileName().endsWith(".json.gz")) { + handleOctreeFileReplacement(reply->readAll()); + } else if (modelsURL.fileName().endsWith(".zip")) { + auto deferred = makePromise("recoverFromUploadedBackup"); + _contentManager->recoverFromUploadedBackup(deferred, reply->readAll()); + } } else { qDebug() << "Error downloading JSON from specified file: " << modelsURL; } @@ -3456,12 +3457,9 @@ void DomainServer::handleOctreeFileReplacementFromURLRequest(QSharedPointer message) { auto node = DependencyManager::get()->nodeWithUUID(message->getSourceID()); if (node->getCanReplaceContent()) { handleOctreeFileReplacement(message->readAll()); } -} +} \ No newline at end of file diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 6e9fe28c0a..b118008d3d 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -91,7 +91,7 @@ private slots: void processICEServerHeartbeatDenialPacket(QSharedPointer message); void processICEServerHeartbeatACK(QSharedPointer message); - void handleOctreeFileReplacementFromURLRequest(QSharedPointer message); + void handleDomainContentReplacementFromURLRequest(QSharedPointer message); void handleOctreeFileReplacementRequest(QSharedPointer message); void handleOctreeFileReplacement(QByteArray octreeFile); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 75f57729c8..404f61b55e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -351,6 +351,7 @@ static const QString OBJ_EXTENSION = ".obj"; static const QString AVA_JSON_EXTENSION = ".ava.json"; static const QString WEB_VIEW_TAG = "noDownload=true"; static const QString ZIP_EXTENSION = ".zip"; +static const QString CONTENT_ZIP_EXTENSION = ".content.zip"; static const float MIRROR_FULLSCREEN_DISTANCE = 0.389f; @@ -378,7 +379,7 @@ static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; static const QString DOMAIN_SPAWNING_POINT = "/0, -10, 0"; -const QHash Application::_acceptedExtensions { +const std::vector> Application::_acceptedExtensions { { SVO_EXTENSION, &Application::importSVOFromURL }, { SVO_JSON_EXTENSION, &Application::importSVOFromURL }, { AVA_JSON_EXTENSION, &Application::askToWearAvatarAttachmentUrl }, @@ -386,6 +387,7 @@ const QHash Application::_acceptedExtensi { JS_EXTENSION, &Application::askToLoadScript }, { FST_EXTENSION, &Application::askToSetAvatarUrl }, { JSON_GZ_EXTENSION, &Application::askToReplaceDomainContent }, + { CONTENT_ZIP_EXTENSION, &Application::askToReplaceDomainContent }, { ZIP_EXTENSION, &Application::importFromZIP }, { JPG_EXTENSION, &Application::importImage }, { PNG_EXTENSION, &Application::importImage } @@ -6171,11 +6173,9 @@ bool Application::canAcceptURL(const QString& urlString) const { } else if (urlString.startsWith(HIFI_URL_SCHEME)) { return true; } - QHashIterator i(_acceptedExtensions); QString lowerPath = url.path().toLower(); - while (i.hasNext()) { - i.next(); - if (lowerPath.endsWith(i.key(), Qt::CaseInsensitive)) { + for (auto& pair : _acceptedExtensions) { + if (lowerPath.endsWith(pair.first, Qt::CaseInsensitive)) { return true; } } @@ -6192,12 +6192,10 @@ bool Application::acceptURL(const QString& urlString, bool defaultUpload) { } QUrl url(urlString); - QHashIterator i(_acceptedExtensions); QString lowerPath = url.path().toLower(); - while (i.hasNext()) { - i.next(); - if (lowerPath.endsWith(i.key(), Qt::CaseInsensitive)) { - AcceptURLMethod method = i.value(); + for (auto& pair : _acceptedExtensions) { + if (lowerPath.endsWith(pair.first, Qt::CaseInsensitive)) { + AcceptURLMethod method = pair.second; return (this->*method)(urlString); } } @@ -6384,13 +6382,11 @@ void Application::replaceDomainContent(const QString& url) { QByteArray urlData(url.toUtf8()); auto limitedNodeList = DependencyManager::get(); const auto& domainHandler = limitedNodeList->getDomainHandler(); - limitedNodeList->eachMatchingNode([](const SharedNodePointer& node) { - return node->getType() == NodeType::EntityServer && node->getActiveSocket(); - }, [&urlData, limitedNodeList, &domainHandler](const SharedNodePointer& octreeNode) { - auto octreeFilePacket = NLPacket::create(PacketType::OctreeFileReplacementFromUrl, urlData.size(), true); - octreeFilePacket->write(urlData); - limitedNodeList->sendPacket(std::move(octreeFilePacket), domainHandler.getSockAddr()); - }); + + auto octreeFilePacket = NLPacket::create(PacketType::DomainContentReplacementFromUrl, urlData.size(), true); + octreeFilePacket->write(urlData); + limitedNodeList->sendPacket(std::move(octreeFilePacket), domainHandler.getSockAddr()); + auto addressManager = DependencyManager::get(); addressManager->handleLookupString(DOMAIN_SPAWNING_POINT); QString newHomeAddress = addressManager->getHost() + DOMAIN_SPAWNING_POINT; @@ -6403,7 +6399,7 @@ bool Application::askToReplaceDomainContent(const QString& url) { const int MAX_CHARACTERS_PER_LINE = 90; if (DependencyManager::get()->getThisNodeCanReplaceContent()) { QUrl originURL { url }; - if (originURL.host().endsWith(MARKETPLACE_CDN_HOSTNAME)) { + if (true || originURL.host().endsWith(MARKETPLACE_CDN_HOSTNAME)) { // Create a confirmation dialog when this call is made static const QString infoText = simpleWordWrap("Your domain's content will be replaced with a new content set. " "If you want to save what you have now, create a backup before proceeding. For more information about backing up " diff --git a/interface/src/Application.h b/interface/src/Application.h index 3eed506ead..95aaa9b6cd 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -603,7 +603,7 @@ private: GLCanvas* _glWidget{ nullptr }; typedef bool (Application::* AcceptURLMethod)(const QString &); - static const QHash _acceptedExtensions; + static const std::vector> _acceptedExtensions; glm::uvec2 _renderResolution; diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 98a9087d37..09fd31a41e 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -121,7 +121,7 @@ public: ReplicatedAvatarIdentity, ReplicatedKillAvatar, ReplicatedBulkAvatarData, - OctreeFileReplacementFromUrl, + DomainContentReplacementFromUrl, ChallengeOwnership, EntityScriptCallMethod, ChallengeOwnershipRequest, @@ -171,7 +171,7 @@ public: << PacketTypeEnum::Value::DomainServerPathResponse << PacketTypeEnum::Value::DomainServerAddedNode << PacketTypeEnum::Value::DomainServerConnectionToken << PacketTypeEnum::Value::DomainSettingsRequest << PacketTypeEnum::Value::OctreeDataFileRequest << PacketTypeEnum::Value::OctreeDataFileReply - << PacketTypeEnum::Value::OctreeDataPersist << PacketTypeEnum::Value::OctreeFileReplacementFromUrl + << PacketTypeEnum::Value::OctreeDataPersist << PacketTypeEnum::Value::DomainContentReplacementFromUrl << PacketTypeEnum::Value::DomainSettings << PacketTypeEnum::Value::ICEServerPeerInformation << PacketTypeEnum::Value::ICEServerQuery << PacketTypeEnum::Value::ICEServerHeartbeat << PacketTypeEnum::Value::ICEServerHeartbeatACK << PacketTypeEnum::Value::ICEPing From 6552aeac4d1ab645eb0ed4988b0eaee10f104fd5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 15 Mar 2018 12:17:35 -0700 Subject: [PATCH 18/44] Fix quazip not building with correct build type --- cmake/externals/quazip/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/externals/quazip/CMakeLists.txt b/cmake/externals/quazip/CMakeLists.txt index 0d66b365a2..f2690e0a7d 100644 --- a/cmake/externals/quazip/CMakeLists.txt +++ b/cmake/externals/quazip/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(SET CMP0046 OLD) include(ExternalProject) -set(QUAZIP_CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_NAME_DIR:PATH=/lib -DZLIB_ROOT=${ZLIB_ROOT} -DCMAKE_POSITION_INDEPENDENT_CODE=ON) +set(QUAZIP_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_NAME_DIR:PATH=/lib -DZLIB_ROOT=${ZLIB_ROOT} -DCMAKE_POSITION_INDEPENDENT_CODE=ON) if (APPLE) else () From 499defe77ea061b4148c94abeca0e8d26088506d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 15 Mar 2018 11:56:18 -0700 Subject: [PATCH 19/44] grab VS2013 redistributables that are needed by externals --- cmake/macros/GenerateInstallers.cmake | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index 2f3493c52e..032f83e8be 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -46,6 +46,14 @@ macro(GENERATE_INSTALLERS) set(UNINSTALLER_HEADER_IMAGE "") fix_path_for_nsis(${_UNINSTALLER_HEADER_BAD_PATH} UNINSTALLER_HEADER_IMAGE) + # we use external libraries that still need the 120 (VS2013) redistributables + # so we include them as well until those external libraries are updated + # to use the redistributables that match what we build our applications for + set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS + "C:/Windows/System32/msvcp120.dll" + "C:/Windows/System32/msvcr120.dll" + ) + set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ${INTERFACE_INSTALL_DIR}) set(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT ${CLIENT_COMPONENT}) From bbe98f61a6d35b09c629045c8a27947f74e6ed9d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 14 Mar 2018 16:38:18 -0700 Subject: [PATCH 20/44] Pull GUID storage in Registry for now. --- cmake/templates/NSIS.template.in | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index 4f9cb0d818..1e828e9186 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -365,15 +365,6 @@ Var GAClientID !macro InitGAClientID ; Generate a new GUID on every run for now !insertmacro CreateGUID $GAClientID - - ; Push $0 - ; ReadRegStr $GAClientID HKLM "@REGISTRY_HKLM_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "@CLIENT_ID_REG_KEY@" - ; ${REMatches} $0 "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" $GAClientID 0 - ; ${If} $0 == false - ; !insertmacro CreateGUID $GAClientID - ; WriteRegStr HKLM "@REGISTRY_HKLM_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "@CLIENT_ID_REG_KEY@" $GAClientID - ; ${EndIf} - ; Pop $0 !macroend !macro GoogleAnalytics Category Action Label Value @@ -1103,7 +1094,7 @@ SectionEnd /SD IDCANCEL IDRETRY Prompt_${UniqueID} IDCANCEL 0 ${EndIf} - !insertmacro GoogleAnalytics "Installer" "Abort" "AppRunning" "${displayName}" + !insertmacro GoogleAnalytics "Installer" "Abort" "${displayName} Running" "" ; If the user decided to cancel, stop the current installer/uninstaller Abort From 9275fe1f7d9bd7b0ab107b2890d67de9c6e332ad Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 15 Mar 2018 12:47:51 -0700 Subject: [PATCH 21/44] Update backup downloads to use .content.zip extension --- domain-server/src/DomainServer.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 4fadedb773..1d1e8d4dc3 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -2133,9 +2134,10 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url _contentManager->getAllBackupsAndStatus(deferred); return true; } else if (url.path().startsWith(URI_API_BACKUPS_ID)) { + constexpr const char* CONTENT_TYPE_ZIP = "application/zip"; auto id = url.path().mid(QString(URI_API_BACKUPS_ID).length()); auto deferred = makePromise("consolidateBackup"); - deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) { + deferred->then([connectionPtr, JSON_MIME_TYPE, id](QString error, QVariantMap result) { if (!connectionPtr) { return; } @@ -2146,7 +2148,12 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url auto path = result["backupFilePath"].toString(); auto file { std::unique_ptr(new QFile(path)) }; if (file->open(QIODevice::ReadOnly)) { - connectionPtr->respond(HTTPConnection::StatusCode200, std::move(file)); + auto downloadedFilename = id; + downloadedFilename.replace(QRegularExpression(".zip$"), ".content.zip"); + auto contentDisposition = "attachment; filename=\"" + downloadedFilename + "\""; + connectionPtr->respond(HTTPConnection::StatusCode200, std::move(file), CONTENT_TYPE_ZIP, { + { "Content-Disposition", contentDisposition.toUtf8() } + }); } else { qCritical(domain_server) << "Unable to load consolidated backup at:" << path << result; connectionPtr->respond(HTTPConnection::StatusCode500, "Error opening backup"); From 03c8c14f612847024374e3ea822a11fc36a5fbc7 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 15 Mar 2018 12:49:22 -0700 Subject: [PATCH 22/44] Fix content replacement being allowed from all URLs --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 404f61b55e..f9a98aa680 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6399,7 +6399,7 @@ bool Application::askToReplaceDomainContent(const QString& url) { const int MAX_CHARACTERS_PER_LINE = 90; if (DependencyManager::get()->getThisNodeCanReplaceContent()) { QUrl originURL { url }; - if (true || originURL.host().endsWith(MARKETPLACE_CDN_HOSTNAME)) { + if (originURL.host().endsWith(MARKETPLACE_CDN_HOSTNAME)) { // Create a confirmation dialog when this call is made static const QString infoText = simpleWordWrap("Your domain's content will be replaced with a new content set. " "If you want to save what you have now, create a backup before proceeding. For more information about backing up " From f8df90e36d64a27bdf1d3a90c60bc61b84e372e8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 15 Mar 2018 13:47:23 -0700 Subject: [PATCH 23/44] disable the sixense plugin by default --- CMakeLists.txt | 24 ++++++++++++------------ interface/CMakeLists.txt | 6 +++++- plugins/CMakeLists.txt | 8 ++++++-- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 25fd4731e6..ee5e027473 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# If we're running under the gradle build, HIFI_ANDROID will be set here, but +# If we're running under the gradle build, HIFI_ANDROID will be set here, but # ANDROID will not be set until after the `project` statement. This is the *ONLY* # place you need to use `HIFI_ANDROID` instead of `ANDROID` if (WIN32 AND NOT HIFI_ANDROID) @@ -61,8 +61,6 @@ else() endif() option(DISABLE_KTX_CACHE "Disable KTX Cache" OFF) - - set(PLATFORM_QT_GL OpenGL) if (USE_GLES) @@ -132,8 +130,8 @@ set_packaging_parameters() # FIXME hack to work on the proper Android toolchain if (ANDROID) - add_subdirectory(android/app) - return() + add_subdirectory(android/app) + return() endif() # add subdirectories for all targets @@ -148,16 +146,18 @@ if (BUILD_SERVER) endif() if (BUILD_CLIENT) - add_subdirectory(interface) - set_target_properties(interface PROPERTIES FOLDER "Apps") - if (ANDROID) - add_subdirectory(gvr-interface) - set_target_properties(gvr-interface PROPERTIES FOLDER "Apps") - endif() + add_subdirectory(interface) + set_target_properties(interface PROPERTIES FOLDER "Apps") + if (ANDROID) + add_subdirectory(gvr-interface) + set_target_properties(gvr-interface PROPERTIES FOLDER "Apps") + endif() + + option(USE_SIXENSE "Build Interface with sixense library/plugin" OFF) endif() if (BUILD_CLIENT OR BUILD_SERVER) - add_subdirectory(plugins) + add_subdirectory(plugins) endif() # BUILD_TOOLS option will be handled inside the tools's CMakeLists.txt because 'scribe' tool is required for build anyway diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 3d33b9929b..76e2ccd181 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -181,7 +181,11 @@ add_dependencies(${TARGET_NAME} resources) if (WIN32) # These are external plugins, but we need to do the 'add dependency' here so that their # binary directories get added to the fixup path - add_dependency_external_projects(sixense) + + if (USE_SIXENSE) + add_dependency_external_projects(sixense) + endif () + add_dependency_external_projects(sdl2) add_dependency_external_projects(OpenVR) add_dependency_external_projects(neuron) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 06cf929368..4a0f52e272 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -20,8 +20,12 @@ if (NOT SERVER_ONLY AND NOT ANDROID) add_subdirectory(${DIR}) set(DIR "oculusLegacy") add_subdirectory(${DIR}) - set(DIR "hifiSixense") - add_subdirectory(${DIR}) + + if (USE_SIXENSE) + set(DIR "hifiSixense") + add_subdirectory(${DIR}) + endif() + set(DIR "hifiSpacemouse") add_subdirectory(${DIR}) set(DIR "hifiNeuron") From d140ccb790b3b29a5a86fa665039885acc551075 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 15 Mar 2018 14:52:15 -0700 Subject: [PATCH 24/44] Fix constexpr compile error on Windows --- domain-server/src/DomainServer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 1d1e8d4dc3..a11fe74c58 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -2134,7 +2134,6 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url _contentManager->getAllBackupsAndStatus(deferred); return true; } else if (url.path().startsWith(URI_API_BACKUPS_ID)) { - constexpr const char* CONTENT_TYPE_ZIP = "application/zip"; auto id = url.path().mid(QString(URI_API_BACKUPS_ID).length()); auto deferred = makePromise("consolidateBackup"); deferred->then([connectionPtr, JSON_MIME_TYPE, id](QString error, QVariantMap result) { @@ -2148,6 +2147,8 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url auto path = result["backupFilePath"].toString(); auto file { std::unique_ptr(new QFile(path)) }; if (file->open(QIODevice::ReadOnly)) { + constexpr const char* CONTENT_TYPE_ZIP = "application/zip"; + auto downloadedFilename = id; downloadedFilename.replace(QRegularExpression(".zip$"), ".content.zip"); auto contentDisposition = "attachment; filename=\"" + downloadedFilename + "\""; From 283eccd043bb6b3598adc518771f94c2ad0fce92 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 15 Mar 2018 16:21:49 -0700 Subject: [PATCH 25/44] remove unneeded ANDROID block, revert removed line in NSIS --- CMakeLists.txt | 4 ---- cmake/templates/NSIS.template.in | 5 ++++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ee5e027473..ff9fbe9244 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -148,10 +148,6 @@ endif() if (BUILD_CLIENT) add_subdirectory(interface) set_target_properties(interface PROPERTIES FOLDER "Apps") - if (ANDROID) - add_subdirectory(gvr-interface) - set_target_properties(gvr-interface PROPERTIES FOLDER "Apps") - endif() option(USE_SIXENSE "Build Interface with sixense library/plugin" OFF) endif() diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index d175fb29c5..368282ab7a 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -855,6 +855,9 @@ Section "-Core installation" ; Rename the incorrectly cased Raleway font Rename "$INSTDIR\resources\qml\styles-uit\RalewaySemibold.qml" "$INSTDIR\resources\qml\styles-uit\RalewaySemiBold.qml" + ; Remove the Old Interface directory and vcredist_x64.exe (from installs prior to Server Console) + RMDir /r "$INSTDIR\Interface" + ;Use the entire tree produced by the INSTALL target. Keep the ;list of directories here in sync with the RMDir commands below. SetOutPath "$INSTDIR" @@ -970,7 +973,7 @@ SectionEnd ${If} $R0 == 0 ; the process is running, ask the user to close it - + ${If} "${displayName}" == "@CONSOLE_DISPLAY_NAME@" MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION \ "${displayName} cannot be ${action} while ${displayName} is running.$\r$\nPlease close it in the system tray and click Retry to continue." \ From ee6c65c1ac0e3772423f99d0b9992f60c14bd2fa Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 16 Mar 2018 12:03:26 -0300 Subject: [PATCH 26/44] Android - Prevent crash when setting the url property to _webSurface. --- libraries/entities-renderer/src/RenderableWebEntityItem.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 52b9364e98..31de9c4234 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -174,7 +174,9 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene } if (urlChanged) { - _webSurface->getRootItem()->setProperty("url", _lastSourceUrl); + if (_webSurface->getRootItem()) { + _webSurface->getRootItem()->setProperty("url", _lastSourceUrl); + } } if (_contextPosition != entity->getWorldPosition()) { From ca38b9fe34a10468af92478ab38efc49abef941d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 16 Mar 2018 10:53:59 -0700 Subject: [PATCH 27/44] Fix invalid QML surface cache interaction --- interface/src/ui/overlays/Web3DOverlay.cpp | 36 ++++++-- interface/src/ui/overlays/Web3DOverlay.h | 1 + scripts/developer/tests/webOverlayTool.js | 102 +++++++++++++++++++++ 3 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 scripts/developer/tests/webOverlayTool.js diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index b324bf39c4..97d4a09f91 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -63,6 +63,19 @@ static const float OPAQUE_ALPHA_THRESHOLD = 0.99f; const QString Web3DOverlay::TYPE = "web3d"; const QString Web3DOverlay::QML = "Web3DOverlay.qml"; + +static auto qmlSurfaceDeleter = [](OffscreenQmlSurface* surface) { + AbstractViewStateInterface::instance()->postLambdaEvent([surface] { + if (AbstractViewStateInterface::instance()->isAboutToQuit()) { + // WebEngineView may run other threads (wasapi), so they must be deleted for a clean shutdown + // if the application has already stopped its event loop, delete must be explicit + delete surface; + } else { + surface->deleteLater(); + } + }); +}; + Web3DOverlay::Web3DOverlay() { _touchDevice.setCapabilities(QTouchDevice::Position); _touchDevice.setType(QTouchDevice::TouchScreen); @@ -75,7 +88,8 @@ Web3DOverlay::Web3DOverlay() { connect(this, &Web3DOverlay::resizeWebSurface, this, &Web3DOverlay::onResizeWebSurface); //need to be intialized before Tablet 1st open - _webSurface = DependencyManager::get()->acquire(_url); + _webSurface = DependencyManager::get()->acquire(QML); + _cachedWebSurface = true; _webSurface->getSurfaceContext()->setContextProperty("HMD", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED _webSurface->getSurfaceContext()->setContextProperty("GlobalServices", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED @@ -114,6 +128,7 @@ void Web3DOverlay::destroyWebSurface() { if (!_webSurface) { return; } + QQuickItem* rootItem = _webSurface->getRootItem(); if (rootItem && rootItem->objectName() == "tabletRoot") { @@ -135,10 +150,15 @@ void Web3DOverlay::destroyWebSurface() { QObject::disconnect(this, &Web3DOverlay::scriptEventReceived, _webSurface.data(), &OffscreenQmlSurface::emitScriptEvent); QObject::disconnect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived); - auto offscreenCache = DependencyManager::get(); - // FIXME prevents crash on shutdown, but we shoudln't have to do this check - if (offscreenCache) { - offscreenCache->release(QML, _webSurface); + + // If the web surface was fetched out of the cache, release it back into the cache + if (_cachedWebSurface) { + auto offscreenCache = DependencyManager::get(); + // FIXME prevents crash on shutdown, but we shoudln't have to do this check + if (offscreenCache) { + offscreenCache->release(QML, _webSurface); + } + _cachedWebSurface = false; } _webSurface.reset(); } @@ -147,6 +167,8 @@ void Web3DOverlay::buildWebSurface() { if (_webSurface) { return; } + // FIXME the context save here is most likely unecessary since the QML surfaces now render + // off the main thread, and all GL context work is done off the main thread (I *think*) gl::withSavedContext([&] { // FIXME, the max FPS could be better managed by being dynamic (based on the number of current surfaces // and the current rendering load) @@ -156,10 +178,12 @@ void Web3DOverlay::buildWebSurface() { if (isWebContent()) { _webSurface = DependencyManager::get()->acquire(QML); + _cachedWebSurface = true; _webSurface->getRootItem()->setProperty("url", _url); _webSurface->getRootItem()->setProperty("scriptURL", _scriptURL); } else { - _webSurface = DependencyManager::get()->acquire(_url); + _webSurface = _webSurface = QSharedPointer(new OffscreenQmlSurface(), qmlSurfaceDeleter); + _cachedWebSurface = false; setupQmlSurface(); } _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getWorldPosition())); diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 4098e98488..d888424cbc 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -88,6 +88,7 @@ private: InputMode _inputMode { Touch }; QSharedPointer _webSurface; + bool _cachedWebSurface{ false }; gpu::TexturePointer _texture; QString _url; QString _scriptURL; diff --git a/scripts/developer/tests/webOverlayTool.js b/scripts/developer/tests/webOverlayTool.js new file mode 100644 index 0000000000..1a3aa35205 --- /dev/null +++ b/scripts/developer/tests/webOverlayTool.js @@ -0,0 +1,102 @@ +// webSpawnTool.js +// +// Stress tests the rendering of web surfaces over time +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +SPAWNER = function (properties) { + properties = properties || {}; + var RADIUS = properties.radius || 5.0; // Spawn within this radius (square) + var SPAWN_COUNT = properties.count || 10000; // number of entities to spawn + var SPAWN_LIMIT = properties.spawnLimit || 1; + var SPAWN_INTERVAL = properties.spawnInterval || properties.interval || 2; + var SPAWN_LIFETIME = properties.lifetime || 10; // Entity timeout (when/if we crash, we need the entities to delete themselves) + + function randomPositionXZ(center, radius) { + return { + x: center.x + (Math.random() * radius * 2.0) - radius, + y: center.y, + z: center.z + (Math.random() * radius * 2.0) - radius + }; + } + + function makeObject(properties) { + + var overlay = Overlays.addOverlay("web3d", { + name: "Web", + url: "https://www.reddit.com/r/random", + localPosition: randomPositionXZ( { x: 0, y: 0, z: -1 }, 1), + localRotation: Quat.angleAxis(180, Vec3.Y_AXIS), + dimensions: {x: .8, y: .45, z: 0.1}, + color: { red: 255, green: 255, blue: 255 }, + alpha: 1.0, + showKeyboardFocusHighlight: false, + visible: true + }); + + var now = Date.now(); + + return { + destroy: function () { + Overlays.deleteOverlay(overlay) + }, + getAge: function () { + return (Date.now() - now) / 1000.0; + } + }; + } + + + var items = []; + var toCreate = 0; + var spawned = 0; + var spawnTimer = 0.0; + var keepAliveTimer = 0.0; + + function clear () { + } + + function create() { + toCreate = SPAWN_COUNT; + Script.update.connect(spawn); + } + + function spawn(dt) { + if (toCreate <= 0) { + Script.update.disconnect(spawn); + print("Finished spawning"); + } + else if ((spawnTimer -= dt) < 0.0){ + spawnTimer = SPAWN_INTERVAL; + + var n = Math.min(toCreate, SPAWN_LIMIT); + print("Spawning " + n + " items (" + (spawned += n) + ")"); + + toCreate -= n; + for (; n > 0; --n) { + items.push(makeObject()); + } + } + } + + function despawn() { + print("despawning"); + items.forEach(function (item) { + item.destroy(); + }); + item = []; + } + + function init () { + Script.update.disconnect(init); + Script.scriptEnding.connect(despawn); + clear(); + create(); + } + + Script.update.connect(init); +}; + +SPAWNER(); From 1dfde86680bbcb47fc51575e9fc8b8501baba6f5 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 16 Mar 2018 11:11:08 -0700 Subject: [PATCH 28/44] Fix typo --- interface/src/ui/overlays/Web3DOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 97d4a09f91..d460ff44e8 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -182,7 +182,7 @@ void Web3DOverlay::buildWebSurface() { _webSurface->getRootItem()->setProperty("url", _url); _webSurface->getRootItem()->setProperty("scriptURL", _scriptURL); } else { - _webSurface = _webSurface = QSharedPointer(new OffscreenQmlSurface(), qmlSurfaceDeleter); + _webSurface = QSharedPointer(new OffscreenQmlSurface(), qmlSurfaceDeleter); _cachedWebSurface = false; setupQmlSurface(); } From 984a48316d742b8bbcfd182c69dc1f4ccdb0813b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 16 Mar 2018 10:56:56 -0700 Subject: [PATCH 29/44] CR --- libraries/render-utils/src/GeometryCache.cpp | 145 +++++-------------- libraries/render-utils/src/GeometryCache.h | 11 +- 2 files changed, 45 insertions(+), 111 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index edd68603cb..693e288d5d 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -135,10 +135,10 @@ static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT; static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT; static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT; -static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 3 + sizeof(glm::vec2); // position, normal, texcoords, tangent -static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3); -static const uint SHAPE_TEXCOORD0_OFFSET = sizeof(glm::vec3) * 2; -static const uint SHAPE_TANGENT_OFFSET = sizeof(glm::vec3) * 2 + sizeof(glm::vec2); +static const uint SHAPE_VERTEX_STRIDE = sizeof(GeometryCache::ShapeVertex); // position, normal, texcoords, tangent +static const uint SHAPE_NORMALS_OFFSET = offsetof(GeometryCache::ShapeVertex, normal); +static const uint SHAPE_TEXCOORD0_OFFSET = offsetof(GeometryCache::ShapeVertex, uv); +static const uint SHAPE_TANGENT_OFFSET = offsetof(GeometryCache::ShapeVertex, tangent); void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, const glm::vec3 &entityExtents, QVector &outPointList) { @@ -197,22 +197,11 @@ std::vector polygon() { return result; } -void addVec3ToVector(std::vector& vertices, glm::vec3 vec) { - vertices.push_back(vec.x); - vertices.push_back(vec.y); - vertices.push_back(vec.z); -} - -void addVec2ToVector(std::vector& vertices, glm::vec2 vec) { - vertices.push_back(vec.x); - vertices.push_back(vec.y); -} - -void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices) { +void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices) { gpu::Buffer::Size offset = vertexBuffer->getSize(); vertexBuffer->append(vertices); - gpu::Buffer::Size viewSize = vertices.size() * sizeof(glm::vec3); + gpu::Buffer::Size viewSize = vertices.size() * sizeof(ShapeVertex); _positionView = gpu::BufferView(vertexBuffer, offset, viewSize, SHAPE_VERTEX_STRIDE, POSITION_ELEMENT); @@ -315,14 +304,14 @@ static IndexPair indexToken(geometry::Index a, geometry::Index b) { template void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - std::vector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; IndexPairs wireSeenIndices; size_t faceCount = shape.faces.size(); size_t faceIndexCount = triangulatedFaceIndexCount(); - vertices.reserve(N * faceCount * 2); + vertices.reserve(N * faceCount); solidIndices.reserve(faceIndexCount * faceCount); Index baseVertex = 0; @@ -359,10 +348,7 @@ void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - std::vector vertices; - vertices.reserve(shape.vertices.size() * SHAPE_VERTEX_STRIDE / sizeof(float)); + std::vector vertices; + vertices.reserve(shape.vertices.size()); for (const auto& vertex : shape.vertices) { - addVec3ToVector(vertices, vertex); - addVec3ToVector(vertices, vertex); - addVec2ToVector(vertices, calculateSphereTexCoord(vertex)); // We'll fill in the correct tangents later, once we correct the UVs - addVec3ToVector(vertices, vec3(0.0f)); + vertices.emplace_back(vertex, vertex, calculateSphereTexCoord(vertex), vec3(0.0f)); } // We need to fix up the sphere's UVs because it's actually a tesselated icosahedron. See http://mft-dev.dk/uv-mapping-sphere/ @@ -424,9 +409,9 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid for (size_t f = 0; f < faceCount; f++) { // Fix zipper { - float& u1 = vertices[shape.faces[f][0] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; - float& u2 = vertices[shape.faces[f][1] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; - float& u3 = vertices[shape.faces[f][2] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + float& u1 = vertices[shape.faces[f][0]].uv.x; + float& u2 = vertices[shape.faces[f][1]].uv.x; + float& u3 = vertices[shape.faces[f][2]].uv.x; if (glm::isnan(u1)) { u1 = (u2 + u3) / 2.0f; @@ -461,21 +446,19 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid if (shape.vertices[originalIndex].y == 1.0f || shape.vertices[originalIndex].y == -1.0f) { float uSum = 0.0f; for (Index i2 = 1; i2 <= N - 1; i2++) { - float u = vertices[shape.faces[f][(i + i2) % N] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + float u = vertices[shape.faces[f][(i + i2) % N]].uv.x; uSum += u; } uSum /= (float)(N - 1); - vertices[originalIndex * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)] = uSum; + vertices[originalIndex].uv.x = uSum; break; } } // Fill in tangents for (Index i = 0; i < N; i++) { - vec3 tangent = calculateSphereTangent(vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]); - vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float)] = tangent.x; - vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float) + 1] = tangent.y; - vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float) + 2] = tangent.z; + vec3 tangent = calculateSphereTangent(vertices[shape.faces[f][i]].uv.x); + vertices[shape.faces[f][i]].tangent = tangent; } } @@ -516,31 +499,22 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid template void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer, bool isConical = false) { using namespace geometry; - std::vector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; // Top (if not conical) and bottom faces std::vector shape = polygon(); if (isConical) { for (uint32_t i = 0; i < N; i++) { - addVec3ToVector(vertices, vec3(0.0f, 0.5f, 0.0f)); - addVec3ToVector(vertices, vec3(0.0f, 1.0f, 0.0f)); - addVec2ToVector(vertices, vec2(i / (float)N, 1.0f)); - addVec3ToVector(vertices, vec3(0.0f)); + vertices.emplace_back(vec3(0.0f, 0.5f, 0.0f), vec3(0.0f, 1.0f, 0.0f), vec2((float)i / (float)N, 1.0f), vec3(0.0f)); } } else { for (const vec3& v : shape) { - addVec3ToVector(vertices, vec3(v.x, 0.5f, v.z)); - addVec3ToVector(vertices, vec3(0.0f, 1.0f, 0.0f)); - addVec2ToVector(vertices, vec2(v.x, v.z) + vec2(0.5f)); - addVec3ToVector(vertices, vec3(1.0f, 0.0f, 0.0f)); + vertices.emplace_back(vec3(v.x, 0.5f, v.z), vec3(0.0f, 1.0f, 0.0f), vec2(v.x, v.z) + vec2(0.5f), vec3(1.0f, 0.0f, 0.0f)); } } for (const vec3& v : shape) { - addVec3ToVector(vertices, vec3(v.x, -0.5f, v.z)); - addVec3ToVector(vertices, vec3(0.0f, -1.0f, 0.0f)); - addVec2ToVector(vertices, vec2(-v.x, v.z) + vec2(0.5f)); - addVec3ToVector(vertices, vec3(-1.0f, 0.0f, 0.0f)); + vertices.emplace_back(vec3(v.x, -0.5f, v.z), vec3(0.0f, -1.0f, 0.0f), vec2(-v.x, v.z) + vec2(0.5f), vec3(-1.0f, 0.0f, 0.0f)); } Index baseVertex = 0; for (uint32_t i = 2; i < N; i++) { @@ -572,25 +546,13 @@ void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& ver vec3 tangent = glm::normalize(bottomLeft - bottomRight); // Our tex coords go in the opposite direction as our vertices - float u = 1.0f - i / (float)N; - float u2 = 1.0f - (i + 1) / (float)N; + float u = 1.0f - (float)i / (float)N; + float u2 = 1.0f - (float)(i + 1) / (float)N; - addVec3ToVector(vertices, topLeft); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u, 0.0f)); - addVec3ToVector(vertices, tangent); - addVec3ToVector(vertices, bottomLeft); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u, 1.0f)); - addVec3ToVector(vertices, tangent); - addVec3ToVector(vertices, topRight); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u2, 0.0f)); - addVec3ToVector(vertices, tangent); - addVec3ToVector(vertices, bottomRight); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u2, 1.0f)); - addVec3ToVector(vertices, tangent); + vertices.emplace_back(topLeft, normal, vec2(u, 0.0f), tangent); + vertices.emplace_back(bottomLeft, normal, vec2(u, 1.0f), tangent); + vertices.emplace_back(topRight, normal, vec2(u2, 0.0f), tangent); + vertices.emplace_back(bottomRight, normal, vec2(u2, 1.0f), tangent); solidIndices.push_back(baseVertex + 0); solidIndices.push_back(baseVertex + 2); @@ -609,43 +571,6 @@ void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& ver shapeData.setupIndices(indexBuffer, solidIndices, wireIndices); } -void drawCircle(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { - // Draw a circle with radius 1/4th the size of the bounding box - using namespace geometry; - - std::vector vertices; - IndexVector solidIndices, wireIndices; - const int NUM_CIRCLE_VERTICES = 64; - - std::vector shape = polygon(); - for (const vec3& v : shape) { - addVec3ToVector(vertices, vec3(v.x, 0.0f, v.z)); - addVec3ToVector(vertices, vec3(0.0f, 0.0f, 0.0f)); - addVec2ToVector(vertices, vec2(v.x, v.z) + vec2(0.5f)); - addVec3ToVector(vertices, vec3(1.0f, 0.0f, 0.0f)); - } - - Index baseVertex = 0; - for (uint32_t i = 2; i < NUM_CIRCLE_VERTICES; i++) { - solidIndices.push_back(baseVertex + 0); - solidIndices.push_back(baseVertex + i); - solidIndices.push_back(baseVertex + i - 1); - solidIndices.push_back(baseVertex + NUM_CIRCLE_VERTICES); - solidIndices.push_back(baseVertex + i + NUM_CIRCLE_VERTICES - 1); - solidIndices.push_back(baseVertex + i + NUM_CIRCLE_VERTICES); - } - - for (uint32_t i = 1; i <= NUM_CIRCLE_VERTICES; i++) { - wireIndices.push_back(baseVertex + (i % NUM_CIRCLE_VERTICES)); - wireIndices.push_back(baseVertex + i - 1); - wireIndices.push_back(baseVertex + (i % NUM_CIRCLE_VERTICES) + NUM_CIRCLE_VERTICES); - wireIndices.push_back(baseVertex + (i - 1) + NUM_CIRCLE_VERTICES); - } - - shapeData.setupVertices(vertexBuffer, vertices); - shapeData.setupIndices(indexBuffer, solidIndices, wireIndices); -} - // FIXME solids need per-face vertices, but smooth shaded // components do not. Find a way to support using draw elements // or draw arrays as appropriate @@ -678,9 +603,9 @@ void GeometryCache::buildShapes() { // Line { ShapeData& shapeData = _shapes[Line]; - shapeData.setupVertices(_shapeVertices, std::vector { - -0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f + shapeData.setupVertices(_shapeVertices, std::vector { + ShapeVertex(vec3(-0.5f, 0.0f, 0.0f), vec3(-0.5f, 0.0f, 0.0f), vec2(0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f)), + ShapeVertex(vec3(0.5f, 0.0f, 0.0f), vec3(0.5f, 0.0f, 0.0f), vec2(0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f)) }); IndexVector wireIndices; // Only two indices diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index b0caaf113c..63154398a4 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -354,6 +354,15 @@ public: /// Set a batch to the simple pipeline, returning the previous pipeline void useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend = false); + struct ShapeVertex { + ShapeVertex(const vec3& pos, const vec3& normal, const vec2& uv, const vec3& tangent) : pos(pos), normal(normal), uv(uv), tangent(tangent) {} + + vec3 pos; + vec3 normal; + vec2 uv; + vec3 tangent; + }; + struct ShapeData { gpu::BufferView _positionView; gpu::BufferView _normalView; @@ -362,7 +371,7 @@ public: gpu::BufferView _indicesView; gpu::BufferView _wireIndicesView; - void setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices); + void setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices); void setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices); void setupBatch(gpu::Batch& batch) const; void draw(gpu::Batch& batch) const; From 2f5928305393a6ddf16c75cb31877b959e4c18e2 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 16 Mar 2018 14:48:08 -0700 Subject: [PATCH 30/44] Fix initialization of QML overlay surfaces --- interface/src/ui/overlays/Web3DOverlay.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index d460ff44e8..6bf5370ca5 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -183,6 +183,7 @@ void Web3DOverlay::buildWebSurface() { _webSurface->getRootItem()->setProperty("scriptURL", _scriptURL); } else { _webSurface = QSharedPointer(new OffscreenQmlSurface(), qmlSurfaceDeleter); + _webSurface->load(_url); _cachedWebSurface = false; setupQmlSurface(); } From 444534f4ffe705c1f0121aae998520ed2733dcdf Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 16 Mar 2018 13:38:45 -0700 Subject: [PATCH 31/44] model behaves correctly if missing material (cherry picked from commit 1e89debc4e85ceccce3f72582bc422b904098e95) --- libraries/render-utils/src/MeshPartPayload.cpp | 14 ++++++++------ libraries/render-utils/src/MeshPartPayload.h | 9 ++++++--- libraries/render-utils/src/Model.cpp | 3 ++- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index ecfb4847e4..5c64d4b584 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -47,6 +47,8 @@ template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderAr } } +const graphics::MaterialPointer MeshPartPayload::DEFAULT_MATERIAL = std::make_shared(); + MeshPartPayload::MeshPartPayload(const std::shared_ptr& mesh, int partIndex, graphics::MaterialPointer material) { updateMeshPart(mesh, partIndex); addMaterial(graphics::MaterialLayer(material, 0)); @@ -99,7 +101,7 @@ void MeshPartPayload::updateKey(bool isVisible, bool isLayered, bool canCastShad builder.withSubMetaCulled(); } - if (_drawMaterials.top().material) { + if (topMaterialExists()) { auto matKey = _drawMaterials.top().material->getKey(); if (matKey.isTranslucent()) { builder.withTransparent(); @@ -119,7 +121,7 @@ Item::Bound MeshPartPayload::getBound() const { ShapeKey MeshPartPayload::getShapeKey() const { graphics::MaterialKey drawMaterialKey; - if (_drawMaterials.top().material) { + if (topMaterialExists()) { drawMaterialKey = _drawMaterials.top().material->getKey(); } @@ -171,7 +173,7 @@ void MeshPartPayload::render(RenderArgs* args) { bindMesh(batch); // apply material properties - RenderPipelines::bindMaterial(_drawMaterials.top().material, batch, args->_enableTexturing); + RenderPipelines::bindMaterial(!_drawMaterials.empty() ? _drawMaterials.top().material : DEFAULT_MATERIAL, batch, args->_enableTexturing); args->_details._materialSwitches++; // Draw! @@ -356,7 +358,7 @@ void ModelMeshPartPayload::updateKey(bool isVisible, bool isLayered, bool canCas builder.withDeformed(); } - if (_drawMaterials.top().material) { + if (topMaterialExists()) { auto matKey = _drawMaterials.top().material->getKey(); if (matKey.isTranslucent()) { builder.withTransparent(); @@ -387,7 +389,7 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, bool isWireframe } graphics::MaterialKey drawMaterialKey; - if (_drawMaterials.top().material) { + if (topMaterialExists()) { drawMaterialKey = _drawMaterials.top().material->getKey(); } @@ -469,7 +471,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) { bindMesh(batch); // apply material properties - RenderPipelines::bindMaterial(_drawMaterials.top().material, batch, args->_enableTexturing); + RenderPipelines::bindMaterial(!_drawMaterials.empty() ? _drawMaterials.top().material : DEFAULT_MATERIAL, batch, args->_enableTexturing); args->_details._materialSwitches++; // Draw! diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 087550345d..08ad7a8311 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -65,15 +65,18 @@ public: graphics::Mesh::Part _drawPart; size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; } - size_t getMaterialTextureSize() { return _drawMaterials.top().material ? _drawMaterials.top().material->getTextureSize() : 0; } - int getMaterialTextureCount() { return _drawMaterials.top().material ? _drawMaterials.top().material->getTextureCount() : 0; } - bool hasTextureInfo() const { return _drawMaterials.top().material ? _drawMaterials.top().material->hasTextureInfo() : false; } + size_t getMaterialTextureSize() { return topMaterialExists() ? _drawMaterials.top().material->getTextureSize() : 0; } + int getMaterialTextureCount() { return topMaterialExists() ? _drawMaterials.top().material->getTextureCount() : 0; } + bool hasTextureInfo() const { return topMaterialExists() ? _drawMaterials.top().material->hasTextureInfo() : false; } void addMaterial(graphics::MaterialLayer material); void removeMaterial(graphics::MaterialPointer material); protected: + static const graphics::MaterialPointer DEFAULT_MATERIAL; render::ItemKey _itemKey{ render::ItemKey::Builder::opaqueShape().build() }; + + bool topMaterialExists() const { return !_drawMaterials.empty() && _drawMaterials.top().material; } }; namespace render { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 2617ef12ad..70f873734a 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1604,7 +1604,8 @@ void Model::createVisibleRenderItemSet() { int numParts = (int)mesh->getNumParts(); for (int partIndex = 0; partIndex < numParts; partIndex++) { _modelMeshRenderItems << std::make_shared(shared_from_this(), i, partIndex, shapeID, transform, offset); - _modelMeshMaterialNames.push_back(getGeometry()->getShapeMaterial(shapeID)->getName()); + auto material = getGeometry()->getShapeMaterial(shapeID); + _modelMeshMaterialNames.push_back(material ? material->getName() : ""); _modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)i }); shapeID++; } From 8ddf360c796ff22d8d6f85fdbca7f692931860b1 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 19 Mar 2018 09:59:11 -0700 Subject: [PATCH 32/44] support relative paths for material images --- libraries/entities/src/MaterialEntityItem.cpp | 2 +- .../src/model-networking/MaterialCache.cpp | 33 ++++++++++--------- .../src/model-networking/MaterialCache.h | 4 +-- .../src/model-networking/ModelCache.cpp | 32 +++++++++--------- .../src/model-networking/ModelCache.h | 16 ++++----- 5 files changed, 44 insertions(+), 43 deletions(-) diff --git a/libraries/entities/src/MaterialEntityItem.cpp b/libraries/entities/src/MaterialEntityItem.cpp index 44ef34a3a4..137d6ef396 100644 --- a/libraries/entities/src/MaterialEntityItem.cpp +++ b/libraries/entities/src/MaterialEntityItem.cpp @@ -157,7 +157,7 @@ void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool u } if (usingUserData) { - _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(getUserData().toUtf8())); + _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(getUserData().toUtf8()), materialURLString); // Since our material changed, the current name might not be valid anymore, so we need to update setCurrentMaterialName(_currentMaterialName); diff --git a/libraries/model-networking/src/model-networking/MaterialCache.cpp b/libraries/model-networking/src/model-networking/MaterialCache.cpp index cf3e255e0c..f0cbfc914a 100644 --- a/libraries/model-networking/src/model-networking/MaterialCache.cpp +++ b/libraries/model-networking/src/model-networking/MaterialCache.cpp @@ -20,7 +20,7 @@ void NetworkMaterialResource::downloadFinished(const QByteArray& data) { parsedMaterials.reset(); if (_url.toString().contains(".json")) { - parsedMaterials = parseJSONMaterials(QJsonDocument::fromJson(data)); + parsedMaterials = parseJSONMaterials(QJsonDocument::fromJson(data), _url); } // TODO: parse other material types @@ -75,7 +75,7 @@ bool NetworkMaterialResource::parseJSONColor(const QJsonValue& array, glm::vec3& * @property {number} materialVersion=1 - The version of the material. Currently not used. * @property {Material|Material[]} materials - The details of the material or materials. */ -NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMaterials(const QJsonDocument& materialJSON) { +NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMaterials(const QJsonDocument& materialJSON, const QUrl& baseUrl) { ParsedMaterials toReturn; if (!materialJSON.isNull() && materialJSON.isObject()) { QJsonObject materialJSONObject = materialJSON.object(); @@ -91,13 +91,13 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater QJsonArray materials = materialsValue.toArray(); for (auto material : materials) { if (!material.isNull() && material.isObject()) { - auto parsedMaterial = parseJSONMaterial(material.toObject()); + auto parsedMaterial = parseJSONMaterial(material.toObject(), baseUrl); toReturn.networkMaterials[parsedMaterial.first] = parsedMaterial.second; toReturn.names.push_back(parsedMaterial.first); } } } else if (materialsValue.isObject()) { - auto parsedMaterial = parseJSONMaterial(materialsValue.toObject()); + auto parsedMaterial = parseJSONMaterial(materialsValue.toObject(), baseUrl); toReturn.networkMaterials[parsedMaterial.first] = parsedMaterial.second; toReturn.names.push_back(parsedMaterial.first); } @@ -138,7 +138,7 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater * @property {string} lightMap - URL of light map texture image. Currently not used. */ // Note: See MaterialEntityItem.h for default values used in practice. -std::pair> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON) { +std::pair> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl) { std::string name = ""; std::shared_ptr material = std::make_shared(); for (auto& key : materialJSON.keys()) { @@ -199,57 +199,58 @@ std::pair> NetworkMaterialResource } else if (key == "albedoMap") { auto value = materialJSON.value(key); if (value.isString()) { + QString urlString = value.toString(); bool useAlphaChannel = false; auto opacityMap = materialJSON.find("opacityMap"); - if (opacityMap != materialJSON.end() && opacityMap->isString() && opacityMap->toString() == value.toString()) { + if (opacityMap != materialJSON.end() && opacityMap->isString() && opacityMap->toString() == urlString) { useAlphaChannel = true; } - material->setAlbedoMap(value.toString(), useAlphaChannel); + material->setAlbedoMap(baseUrl.resolved(urlString), useAlphaChannel); } } else if (key == "roughnessMap") { auto value = materialJSON.value(key); if (value.isString()) { - material->setRoughnessMap(value.toString(), false); + material->setRoughnessMap(baseUrl.resolved(value.toString()), false); } } else if (key == "glossMap") { auto value = materialJSON.value(key); if (value.isString()) { - material->setRoughnessMap(value.toString(), true); + material->setRoughnessMap(baseUrl.resolved(value.toString()), true); } } else if (key == "metallicMap") { auto value = materialJSON.value(key); if (value.isString()) { - material->setMetallicMap(value.toString(), false); + material->setMetallicMap(baseUrl.resolved(value.toString()), false); } } else if (key == "specularMap") { auto value = materialJSON.value(key); if (value.isString()) { - material->setMetallicMap(value.toString(), true); + material->setMetallicMap(baseUrl.resolved(value.toString()), true); } } else if (key == "normalMap") { auto value = materialJSON.value(key); if (value.isString()) { - material->setNormalMap(value.toString(), false); + material->setNormalMap(baseUrl.resolved(value.toString()), false); } } else if (key == "bumpMap") { auto value = materialJSON.value(key); if (value.isString()) { - material->setNormalMap(value.toString(), true); + material->setNormalMap(baseUrl.resolved(value.toString()), true); } } else if (key == "occlusionMap") { auto value = materialJSON.value(key); if (value.isString()) { - material->setOcclusionMap(value.toString()); + material->setOcclusionMap(baseUrl.resolved(value.toString())); } } else if (key == "scatteringMap") { auto value = materialJSON.value(key); if (value.isString()) { - material->setScatteringMap(value.toString()); + material->setScatteringMap(baseUrl.resolved(value.toString())); } } else if (key == "lightMap") { auto value = materialJSON.value(key); if (value.isString()) { - material->setLightmapMap(value.toString()); + material->setLightmapMap(baseUrl.resolved(value.toString())); } } } diff --git a/libraries/model-networking/src/model-networking/MaterialCache.h b/libraries/model-networking/src/model-networking/MaterialCache.h index 468a12c677..074cd6c98d 100644 --- a/libraries/model-networking/src/model-networking/MaterialCache.h +++ b/libraries/model-networking/src/model-networking/MaterialCache.h @@ -37,8 +37,8 @@ public: ParsedMaterials parsedMaterials; - static ParsedMaterials parseJSONMaterials(const QJsonDocument& materialJSON); - static std::pair> parseJSONMaterial(const QJsonObject& materialJSON); + static ParsedMaterials parseJSONMaterials(const QJsonDocument& materialJSON, const QUrl& baseUrl); + static std::pair> parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl); private: static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB); diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index b253ac4af3..f17cdbb7e8 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -556,58 +556,58 @@ graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& url, im return nullptr; } -void NetworkMaterial::setAlbedoMap(const QString& url, bool useAlphaChannel) { - auto map = fetchTextureMap(QUrl(url), image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP); +void NetworkMaterial::setAlbedoMap(const QUrl& url, bool useAlphaChannel) { + auto map = fetchTextureMap(url, image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP); if (map) { map->setUseAlphaChannel(useAlphaChannel); setTextureMap(MapChannel::ALBEDO_MAP, map); } } -void NetworkMaterial::setNormalMap(const QString& url, bool isBumpmap) { - auto map = fetchTextureMap(QUrl(url), isBumpmap ? image::TextureUsage::BUMP_TEXTURE : image::TextureUsage::NORMAL_TEXTURE, MapChannel::NORMAL_MAP); +void NetworkMaterial::setNormalMap(const QUrl& url, bool isBumpmap) { + auto map = fetchTextureMap(url, isBumpmap ? image::TextureUsage::BUMP_TEXTURE : image::TextureUsage::NORMAL_TEXTURE, MapChannel::NORMAL_MAP); if (map) { setTextureMap(MapChannel::NORMAL_MAP, map); } } -void NetworkMaterial::setRoughnessMap(const QString& url, bool isGloss) { - auto map = fetchTextureMap(QUrl(url), isGloss ? image::TextureUsage::GLOSS_TEXTURE : image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP); +void NetworkMaterial::setRoughnessMap(const QUrl& url, bool isGloss) { + auto map = fetchTextureMap(url, isGloss ? image::TextureUsage::GLOSS_TEXTURE : image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP); if (map) { setTextureMap(MapChannel::ROUGHNESS_MAP, map); } } -void NetworkMaterial::setMetallicMap(const QString& url, bool isSpecular) { - auto map = fetchTextureMap(QUrl(url), isSpecular ? image::TextureUsage::SPECULAR_TEXTURE : image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP); +void NetworkMaterial::setMetallicMap(const QUrl& url, bool isSpecular) { + auto map = fetchTextureMap(url, isSpecular ? image::TextureUsage::SPECULAR_TEXTURE : image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP); if (map) { setTextureMap(MapChannel::METALLIC_MAP, map); } } -void NetworkMaterial::setOcclusionMap(const QString& url) { - auto map = fetchTextureMap(QUrl(url), image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP); +void NetworkMaterial::setOcclusionMap(const QUrl& url) { + auto map = fetchTextureMap(url, image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP); if (map) { setTextureMap(MapChannel::OCCLUSION_MAP, map); } } -void NetworkMaterial::setEmissiveMap(const QString& url) { - auto map = fetchTextureMap(QUrl(url), image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP); +void NetworkMaterial::setEmissiveMap(const QUrl& url) { + auto map = fetchTextureMap(url, image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP); if (map) { setTextureMap(MapChannel::EMISSIVE_MAP, map); } } -void NetworkMaterial::setScatteringMap(const QString& url) { - auto map = fetchTextureMap(QUrl(url), image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP); +void NetworkMaterial::setScatteringMap(const QUrl& url) { + auto map = fetchTextureMap(url, image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP); if (map) { setTextureMap(MapChannel::SCATTERING_MAP, map); } } -void NetworkMaterial::setLightmapMap(const QString& url) { - auto map = fetchTextureMap(QUrl(url), image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP); +void NetworkMaterial::setLightmapMap(const QUrl& url) { + auto map = fetchTextureMap(url, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP); if (map) { //map->setTextureTransform(_lightmapTransform); //map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y); diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index bbb00d72eb..4dfa8b17ea 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -164,14 +164,14 @@ public: NetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl); NetworkMaterial(const NetworkMaterial& material); - void setAlbedoMap(const QString& url, bool useAlphaChannel); - void setNormalMap(const QString& url, bool isBumpmap); - void setRoughnessMap(const QString& url, bool isGloss); - void setMetallicMap(const QString& url, bool isSpecular); - void setOcclusionMap(const QString& url); - void setEmissiveMap(const QString& url); - void setScatteringMap(const QString& url); - void setLightmapMap(const QString& url); + void setAlbedoMap(const QUrl& url, bool useAlphaChannel); + void setNormalMap(const QUrl& url, bool isBumpmap); + void setRoughnessMap(const QUrl& url, bool isGloss); + void setMetallicMap(const QUrl& url, bool isSpecular); + void setOcclusionMap(const QUrl& url); + void setEmissiveMap(const QUrl& url); + void setScatteringMap(const QUrl& url); + void setLightmapMap(const QUrl& url); protected: friend class Geometry; From 17fddd9e0effc0b4e0c4e5b406317956d5edeb56 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Mon, 19 Mar 2018 15:33:14 -0300 Subject: [PATCH 33/44] RenderableWebEntityItem root item check moved to hasWebSurface and buildWebSurface --- .../entities-renderer/src/RenderableWebEntityItem.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 31de9c4234..bd00ded12d 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -174,9 +174,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene } if (urlChanged) { - if (_webSurface->getRootItem()) { - _webSurface->getRootItem()->setProperty("url", _lastSourceUrl); - } + _webSurface->getRootItem()->setProperty("url", _lastSourceUrl); } if (_contextPosition != entity->getWorldPosition()) { @@ -241,7 +239,7 @@ void WebEntityRenderer::doRender(RenderArgs* args) { } bool WebEntityRenderer::hasWebSurface() { - return (bool)_webSurface; + return (bool)_webSurface && _webSurface->getRootItem(); } bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) { @@ -305,7 +303,7 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) { _fadeStartTime = usecTimestampNow(); _webSurface->resume(); - return true; + return _webSurface->getRootItem(); } void WebEntityRenderer::destroyWebSurface() { From 0117179fe4fffe3689456173e95babbbf9ec3844 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 19 Mar 2018 14:47:30 -0700 Subject: [PATCH 34/44] Pull GA ID from env variables --- cmake/macros/SetPackagingParameters.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/macros/SetPackagingParameters.cmake b/cmake/macros/SetPackagingParameters.cmake index 3ca72b473b..a962504e72 100644 --- a/cmake/macros/SetPackagingParameters.cmake +++ b/cmake/macros/SetPackagingParameters.cmake @@ -150,6 +150,7 @@ macro(SET_PACKAGING_PARAMETERS) set(SERVER_LAUNCH_NOW_REG_KEY "ServerLaunchAfterInstall") set(CUSTOM_INSTALL_REG_KEY "CustomInstall") set(CLIENT_ID_REG_KEY "ClientGUID") + set(GA_TRACKING_ID $ENV{GA_TRACKING_ID}) endif () # setup component categories for installer From 1405c8fcb3d93781179ce6081a7aa139f1a5cd13 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 8 Mar 2018 15:21:55 -0800 Subject: [PATCH 35/44] add a client only option to cmake --- CMakeLists.txt | 90 +++++++++++++++------------ cmake/macros/GenerateInstallers.cmake | 9 ++- interface/CMakeLists.txt | 25 ++++---- plugins/hifiCodec/CMakeLists.txt | 4 +- plugins/pcmCodec/CMakeLists.txt | 4 +- tools/oven/CMakeLists.txt | 4 +- 6 files changed, 78 insertions(+), 58 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff9fbe9244..7052276956 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,8 +14,12 @@ include("cmake/init.cmake") include("cmake/compiler.cmake") if (BUILD_SCRIBE_ONLY) - add_subdirectory(tools/scribe) - return() + add_subdirectory(tools/scribe) + return() +endif() + +if (NOT DEFINED CLIENT_ONLY) + set(CLIENT_ONLY 0) endif() if (NOT DEFINED SERVER_ONLY) @@ -23,42 +27,52 @@ if (NOT DEFINED SERVER_ONLY) endif() if (ANDROID OR UWP) - set(MOBILE 1) + set(MOBILE 1) else() - set(MOBILE 0) + set(MOBILE 0) endif() +set(BUILD_CLIENT_OPTION ON) +set(BUILD_SERVER_OPTION ON) +set(BUILD_TESTS_OPTION ON) +set(BUILD_TOOLS_OPTION ON) +set(BUILD_INSTALLER_OPTION ON) +set(GLES_OPTION OFF) +set(DISABLE_QML_OPTION OFF) + if (ANDROID OR UWP) - option(BUILD_SERVER "Build server components" OFF) - option(BUILD_TOOLS "Build tools" OFF) - option(BUILD_INSTALLER "Build installer" OFF) -else() - option(BUILD_SERVER "Build server components" ON) - option(BUILD_TOOLS "Build tools" ON) - option(BUILD_INSTALLER "Build installer" ON) + set(BUILD_SERVER_OPTION OFF) + set(BUILD_TOOLS_OPTION OFF) + set(BUILD_INSTALLER OFF) +endif() + +if (CLIENT_ONLY) + set(BUILD_SERVER_OPTION OFF) endif() if (SERVER_ONLY) - option(BUILD_CLIENT "Build client components" OFF) - option(BUILD_TESTS "Build tests" OFF) -else() - option(BUILD_CLIENT "Build client components" ON) - option(BUILD_TESTS "Build tests" ON) + set(BUILD_CLIENT_OPTION OFF) + set(BUILD_TESTS_OPTION OFF) endif() if (ANDROID) - option(USE_GLES "Use OpenGL ES" ON) - set(PLATFORM_QT_COMPONENTS AndroidExtras WebView) + set(GLES_OPTION ON) + set(PLATFORM_QT_COMPONENTS AndroidExtras WebView) else () - option(USE_GLES "Use OpenGL ES" OFF) - set(PLATFORM_QT_COMPONENTS WebEngine WebEngineWidgets) + set(PLATFORM_QT_COMPONENTS WebEngine WebEngineWidgets) endif () if (USE_GLES AND (NOT ANDROID)) - option(DISABLE_QML "Disable QML" ON) -else() - option(DISABLE_QML "Disable QML" OFF) + set(DISABLE_QML_OPTION ON) endif() + +option(BUILD_CLIENT "Build client components" ${BUILD_CLIENT_OPTION}) +option(BUILD_SERVER "Build server components" ${BUILD_SERVER_OPTION}) +option(BUILD_TESTS "Build tests" ${BUILD_TESTS_OPTION}) +option(BUILD_TOOLS "Build tools" ${BUILD_TOOLS_OPTION}) +option(BUILD_INSTALLER "Build installer" ${BUILD_INSTALLER_OPTION}) +option(USE_GLES "Use OpenGL ES" ${GLES_OPTION}) +option(DISABLE_QML "Disable QML" ${DISABLE_QML_OPTION}) option(DISABLE_KTX_CACHE "Disable KTX Cache" OFF) set(PLATFORM_QT_GL OpenGL) @@ -70,12 +84,10 @@ else() set(PLATFORM_GL_BACKEND gpu-gl) endif() - foreach(PLATFORM_QT_COMPONENT ${PLATFORM_QT_COMPONENTS}) list(APPEND PLATFORM_QT_LIBRARIES "Qt5::${PLATFORM_QT_COMPONENT}") endforeach() - MESSAGE(STATUS "Build server: " ${BUILD_SERVER}) MESSAGE(STATUS "Build client: " ${BUILD_CLIENT}) MESSAGE(STATUS "Build tests: " ${BUILD_TESTS}) @@ -84,17 +96,17 @@ MESSAGE(STATUS "Build installer: " ${BUILD_INSTALLER}) MESSAGE(STATUS "GL ES: " ${USE_GLES}) if (DISABLE_QML) -MESSAGE(STATUS "QML disabled!") -add_definitions(-DDISABLE_QML) + MESSAGE(STATUS "QML disabled!") + add_definitions(-DDISABLE_QML) endif() if (DISABLE_KTX_CACHE) -MESSAGE(STATUS "KTX cache disabled!") -add_definitions(-DDISABLE_KTX_CACHE) + MESSAGE(STATUS "KTX cache disabled!") + add_definitions(-DDISABLE_KTX_CACHE) endif() if (UNIX AND DEFINED ENV{HIFI_MEMORY_DEBUGGING}) - MESSAGE(STATUS "Memory debugging is enabled") + MESSAGE(STATUS "Memory debugging is enabled") endif() # @@ -160,16 +172,16 @@ endif() add_subdirectory(tools) if (BUILD_TESTS) - add_subdirectory(tests) + add_subdirectory(tests) endif() if (BUILD_INSTALLER) - if (UNIX) - install( - DIRECTORY "${CMAKE_SOURCE_DIR}/scripts" - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/interface - COMPONENT ${CLIENT_COMPONENT} - ) - endif() - generate_installers() + if (UNIX) + install( + DIRECTORY "${CMAKE_SOURCE_DIR}/scripts" + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/interface + COMPONENT ${CLIENT_COMPONENT} + ) + endif() + generate_installers() endif() diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index 032f83e8be..a263da677c 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -88,8 +88,13 @@ macro(GENERATE_INSTALLERS) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") - cpack_add_component(${CLIENT_COMPONENT} DISPLAY_NAME "High Fidelity Interface") - cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "High Fidelity Sandbox") + if (BUILD_CLIENT) + cpack_add_component(${CLIENT_COMPONENT} DISPLAY_NAME "High Fidelity Interface") + endif () + + if (BUILD_SERVER) + cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "High Fidelity Sandbox") + endif () include(CPack) endmacro() diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 4ce35027f2..d98ac67dfd 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -26,17 +26,17 @@ generate_qrc(OUTPUT ${RESOURCES_QRC} PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources if (ANDROID) # on Android, don't compress the rcc binary add_custom_command( - OUTPUT ${RESOURCES_RCC} - DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS} - COMMAND "${QT_DIR}/bin/rcc" - ARGS ${RESOURCES_QRC} -no-compress -binary -o ${RESOURCES_RCC} + OUTPUT ${RESOURCES_RCC} + DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS} + COMMAND "${QT_DIR}/bin/rcc" + ARGS ${RESOURCES_QRC} -no-compress -binary -o ${RESOURCES_RCC} ) else () add_custom_command( - OUTPUT ${RESOURCES_RCC} - DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS} - COMMAND "${QT_DIR}/bin/rcc" - ARGS ${RESOURCES_QRC} -binary -o ${RESOURCES_RCC} + OUTPUT ${RESOURCES_RCC} + DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS} + COMMAND "${QT_DIR}/bin/rcc" + ARGS ${RESOURCES_QRC} -binary -o ${RESOURCES_RCC} ) endif() @@ -203,12 +203,6 @@ if (WIN32) add_dependency_external_projects(steamworks) endif() -# include OPENSSL -include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") - -# append OpenSSL to our list of libraries to link -target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES}) - # disable /OPT:REF and /OPT:ICF for the Debug builds # This will prevent the following linker warnings # LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification @@ -232,6 +226,9 @@ link_hifi_libraries( # include the binary directory of render-utils for shader includes target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/libraries/render-utils") +# include OpenSSL +target_openssl() + target_bullet() target_opengl() add_crashpad() diff --git a/plugins/hifiCodec/CMakeLists.txt b/plugins/hifiCodec/CMakeLists.txt index 28c1dc3807..9ecaf7b511 100644 --- a/plugins/hifiCodec/CMakeLists.txt +++ b/plugins/hifiCodec/CMakeLists.txt @@ -12,5 +12,7 @@ link_hifi_libraries(audio plugins) add_dependency_external_projects(hifiAudioCodec) target_include_directories(${TARGET_NAME} PRIVATE ${HIFIAUDIOCODEC_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${HIFIAUDIOCODEC_LIBRARIES}) -install_beside_console() +if (BUILD_SERVER) + install_beside_console() +endif () diff --git a/plugins/pcmCodec/CMakeLists.txt b/plugins/pcmCodec/CMakeLists.txt index 900a642a88..cce33ecd1a 100644 --- a/plugins/pcmCodec/CMakeLists.txt +++ b/plugins/pcmCodec/CMakeLists.txt @@ -9,5 +9,7 @@ set(TARGET_NAME pcmCodec) setup_hifi_client_server_plugin() link_hifi_libraries(shared plugins) -install_beside_console() +if (BUILD_SERVER) + install_beside_console() +endif () diff --git a/tools/oven/CMakeLists.txt b/tools/oven/CMakeLists.txt index 549414cbab..71bb997303 100644 --- a/tools/oven/CMakeLists.txt +++ b/tools/oven/CMakeLists.txt @@ -18,4 +18,6 @@ elseif (APPLE) set_target_properties(${TARGET_NAME} PROPERTIES INSTALL_RPATH "@executable_path/../Frameworks") endif() -install_beside_console() +if (BUILD_SERVER) + install_beside_console() +endif () From c743bfcf278cb83733609c7059c36e5e40e2246b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 8 Mar 2018 17:02:13 -0800 Subject: [PATCH 36/44] templatize conditional for selection of server component --- cmake/macros/SetPackagingParameters.cmake | 18 +++++++++++++----- cmake/templates/CPackProperties.cmake.in | 1 + cmake/templates/NSIS.template.in | 20 ++++++++++---------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/cmake/macros/SetPackagingParameters.cmake b/cmake/macros/SetPackagingParameters.cmake index a962504e72..a47452c7cf 100644 --- a/cmake/macros/SetPackagingParameters.cmake +++ b/cmake/macros/SetPackagingParameters.cmake @@ -27,6 +27,11 @@ macro(SET_PACKAGING_PARAMETERS) message(STATUS "The BRANCH environment variable is: $ENV{BRANCH}") message(STATUS "The RELEASE_TYPE variable is: ${RELEASE_TYPE}") + # setup component categories for installer + set(DDE_COMPONENT dde) + set(CLIENT_COMPONENT client) + set(SERVER_COMPONENT server) + if (RELEASE_TYPE STREQUAL "PRODUCTION") set(DEPLOY_PACKAGE TRUE) set(PRODUCTION_BUILD 1) @@ -151,12 +156,15 @@ macro(SET_PACKAGING_PARAMETERS) set(CUSTOM_INSTALL_REG_KEY "CustomInstall") set(CLIENT_ID_REG_KEY "ClientGUID") set(GA_TRACKING_ID $ENV{GA_TRACKING_ID}) - endif () - # setup component categories for installer - set(DDE_COMPONENT dde) - set(CLIENT_COMPONENT client) - set(SERVER_COMPONENT server) + # setup conditional checks for server component selection depending on + # the inclusion of the server component at all + if (CLIENT_ONLY) + set(SERVER_COMPONENT_CONDITIONAL "0 == 1") + else () + set(SERVER_COMPONENT_CONDITIONAL "\${SectionIsSelected} \${${SERVER_COMPONENT_NAME}}") + endif () + endif () # print out some results for testing this new build feature message(STATUS "The BUILD_GLOBAL_SERVICES variable is: ${BUILD_GLOBAL_SERVICES}") diff --git a/cmake/templates/CPackProperties.cmake.in b/cmake/templates/CPackProperties.cmake.in index 1a0fa2fac7..ad38e067b6 100644 --- a/cmake/templates/CPackProperties.cmake.in +++ b/cmake/templates/CPackProperties.cmake.in @@ -46,3 +46,4 @@ set(CLIENT_ID_REG_KEY "@CLIENT_ID_REG_KEY@") set(INSTALLER_HEADER_IMAGE "@INSTALLER_HEADER_IMAGE@") set(UNINSTALLER_HEADER_IMAGE "@UNINSTALLER_HEADER_IMAGE@") set(ADD_REMOVE_ICON_PATH "@ADD_REMOVE_ICON_PATH@") +set(SERVER_COMPONENT_CONDITIONAL "@SERVER_COMPONENT_CONDITIONAL@") diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index f174727f95..5f652f58b6 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -658,7 +658,7 @@ Function PostInstallOptionsPage !insertmacro SetInstallOption $DesktopClientCheckbox @CLIENT_DESKTOP_SHORTCUT_REG_KEY@ ${BST_CHECKED} ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @CONSOLE_HF_SHORTCUT_NAME@" Pop $DesktopServerCheckbox IntOp $CurrentOffset $CurrentOffset + 15 @@ -667,7 +667,7 @@ Function PostInstallOptionsPage !insertmacro SetInstallOption $DesktopServerCheckbox @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ ${BST_UNCHECKED} ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ after install" Pop $LaunchServerNowCheckbox @@ -694,7 +694,7 @@ Function PostInstallOptionsPage ${EndIf} ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ on startup" Pop $ServerStartupCheckbox IntOp $CurrentOffset $CurrentOffset + 15 @@ -703,7 +703,7 @@ Function PostInstallOptionsPage !insertmacro SetInstallOption $ServerStartupCheckbox @CONSOLE_STARTUP_REG_KEY@ ${BST_CHECKED} ${EndIf} - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Perform a clean install (Delete older settings and content)" Pop $CleanInstallCheckbox IntOp $CurrentOffset $CurrentOffset + 15 @@ -715,7 +715,7 @@ Function PostInstallOptionsPage ${NSD_SetState} $DesktopClientCheckbox ${BST_UNCHECKED} ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_SetState} $DesktopServerCheckbox ${BST_UNCHECKED} ${NSD_SetState} $ServerStartupCheckbox ${BST_UNCHECKED} ${EndIf} @@ -779,7 +779,7 @@ Function ReadPostInstallOptions ${NSD_GetState} $DesktopClientCheckbox $DesktopClientState ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ; check if the user asked for a desktop shortcut to Sandbox ${NSD_GetState} $DesktopServerCheckbox $DesktopServerState @@ -792,7 +792,7 @@ Function ReadPostInstallOptions ${NSD_GetState} $CopyFromProductionCheckbox $CopyFromProductionState ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ; check if we need to launch the server post-install ${NSD_GetState} $LaunchServerNowCheckbox $LaunchServerNowState ${EndIf} @@ -820,7 +820,7 @@ Function HandlePostInstallOptions ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ; check if the user asked for a desktop shortcut to Sandbox ${If} $DesktopServerState == ${BST_CHECKED} CreateShortCut "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@" @@ -1041,7 +1041,7 @@ Section "-Core installation" ${EndIf} ; Conditional handling for server console shortcut - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" \ "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@" ${EndIf} @@ -1186,7 +1186,7 @@ Function .onSelChange ; if neither component is selected, disable the install button ${IfNot} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} - ${AndIfNot} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${AndIfNot} @SERVER_COMPONENT_CONDITIONAL@ GetDlgItem $0 $HWNDPARENT 1 EnableWindow $0 0 ${Else} From f93935f5f6d3bb08562a989e2f9d9b5bc2081b57 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 13 Mar 2018 13:58:51 -0700 Subject: [PATCH 37/44] change PR build compression to bzip2 --- cmake/macros/GenerateInstallers.cmake | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index a263da677c..b770bc9e7f 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -22,11 +22,12 @@ macro(GENERATE_INSTALLERS) set(CPACK_PACKAGE_FILE_NAME "HighFidelity-Beta-${BUILD_VERSION}") set(CPACK_NSIS_DISPLAY_NAME ${_DISPLAY_NAME}) set(CPACK_NSIS_PACKAGE_NAME ${_DISPLAY_NAME}) - if (PR_BUILD) - set(CPACK_NSIS_COMPRESSOR "/SOLID bzip2") - endif () - set(CPACK_PACKAGE_INSTALL_DIRECTORY ${_DISPLAY_NAME}) + if (PR_BUILD) + set(CPACK_NSIS_COMPRESSOR "bzip2") + endif () + + set(CPACK_PACKAGE_INSTALL_DIRECTORY ${_DISPLAY_NAME}) if (WIN32) set(CPACK_NSIS_MUI_ICON "${HF_CMAKE_DIR}/installer/installer.ico") From 6ee6f8808770dba48c45615073681f82365129e5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 13 Mar 2018 15:07:52 -0700 Subject: [PATCH 38/44] only add components to cmake for multi-component installer --- cmake/macros/GenerateInstallers.cmake | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index b770bc9e7f..215e2bf3ca 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -22,13 +22,12 @@ macro(GENERATE_INSTALLERS) set(CPACK_PACKAGE_FILE_NAME "HighFidelity-Beta-${BUILD_VERSION}") set(CPACK_NSIS_DISPLAY_NAME ${_DISPLAY_NAME}) set(CPACK_NSIS_PACKAGE_NAME ${_DISPLAY_NAME}) - if (PR_BUILD) set(CPACK_NSIS_COMPRESSOR "bzip2") endif () - set(CPACK_PACKAGE_INSTALL_DIRECTORY ${_DISPLAY_NAME}) + if (WIN32) set(CPACK_NSIS_MUI_ICON "${HF_CMAKE_DIR}/installer/installer.ico") @@ -59,6 +58,10 @@ macro(GENERATE_INSTALLERS) set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ${INTERFACE_INSTALL_DIR}) set(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT ${CLIENT_COMPONENT}) include(InstallRequiredSystemLibraries) + + if (CLIENT_ONLY OR SERVER_ONLY) + set(CPACK_MONOLITHIC_INSTALL 1) + endif () elseif (APPLE) # produce a drag and drop DMG on OS X set(CPACK_GENERATOR "DragNDrop") From 932c55ca089d2f3b1c7d7d2c13c43da20d33c059 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 13 Mar 2018 15:30:10 -0700 Subject: [PATCH 39/44] handle client section in component-less install --- cmake/macros/GenerateInstallers.cmake | 10 ++++++++++ cmake/macros/SetPackagingParameters.cmake | 8 -------- cmake/templates/CPackProperties.cmake.in | 1 + cmake/templates/NSIS.template.in | 20 ++++++++++---------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index 215e2bf3ca..5c68997b8e 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -62,6 +62,16 @@ macro(GENERATE_INSTALLERS) if (CLIENT_ONLY OR SERVER_ONLY) set(CPACK_MONOLITHIC_INSTALL 1) endif () + + # setup conditional checks for server component selection depending on + # the inclusion of the server component at all + if (CLIENT_ONLY) + set(SERVER_COMPONENT_CONDITIONAL "0 == 1") + set(CLIENT_COMPONENT_CONDITIONAL "1 == 1") + else () + set(SERVER_COMPONENT_CONDITIONAL "\\\${SectionIsSelected} \\\${${SERVER_COMPONENT}}") + set(CLIENT_COMPONENT_CONDITIONAL "\\\${SectionIsSelected} \\\${${CLIENT_COMPONENT}}") + endif () elseif (APPLE) # produce a drag and drop DMG on OS X set(CPACK_GENERATOR "DragNDrop") diff --git a/cmake/macros/SetPackagingParameters.cmake b/cmake/macros/SetPackagingParameters.cmake index a47452c7cf..601fbdaa20 100644 --- a/cmake/macros/SetPackagingParameters.cmake +++ b/cmake/macros/SetPackagingParameters.cmake @@ -156,14 +156,6 @@ macro(SET_PACKAGING_PARAMETERS) set(CUSTOM_INSTALL_REG_KEY "CustomInstall") set(CLIENT_ID_REG_KEY "ClientGUID") set(GA_TRACKING_ID $ENV{GA_TRACKING_ID}) - - # setup conditional checks for server component selection depending on - # the inclusion of the server component at all - if (CLIENT_ONLY) - set(SERVER_COMPONENT_CONDITIONAL "0 == 1") - else () - set(SERVER_COMPONENT_CONDITIONAL "\${SectionIsSelected} \${${SERVER_COMPONENT_NAME}}") - endif () endif () # print out some results for testing this new build feature diff --git a/cmake/templates/CPackProperties.cmake.in b/cmake/templates/CPackProperties.cmake.in index ad38e067b6..9c303f7532 100644 --- a/cmake/templates/CPackProperties.cmake.in +++ b/cmake/templates/CPackProperties.cmake.in @@ -47,3 +47,4 @@ set(INSTALLER_HEADER_IMAGE "@INSTALLER_HEADER_IMAGE@") set(UNINSTALLER_HEADER_IMAGE "@UNINSTALLER_HEADER_IMAGE@") set(ADD_REMOVE_ICON_PATH "@ADD_REMOVE_ICON_PATH@") set(SERVER_COMPONENT_CONDITIONAL "@SERVER_COMPONENT_CONDITIONAL@") +set(CLIENT_COMPONENT_CONDITIONAL "@CLIENT_COMPONENT_CONDITIONAL@") diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index 5f652f58b6..f9a70ee10e 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -649,7 +649,7 @@ Function PostInstallOptionsPage StrCpy $CurrentOffset 0 StrCpy $OffsetUnits u - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @INTERFACE_HF_SHORTCUT_NAME@" Pop $DesktopClientCheckbox IntOp $CurrentOffset $CurrentOffset + 15 @@ -681,7 +681,7 @@ Function PostInstallOptionsPage IntOp $CurrentOffset $CurrentOffset + 15 ${EndIf} - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @INTERFACE_HF_SHORTCUT_NAME@ after install" Pop $LaunchClientNowCheckbox IntOp $CurrentOffset $CurrentOffset + 30 @@ -711,7 +711,7 @@ Function PostInstallOptionsPage ${If} @PR_BUILD@ == 1 ; a PR build defaults all install options expect LaunchServerNowCheckbox, LaunchClientNowCheckbox and the settings copy to unchecked - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ${NSD_SetState} $DesktopClientCheckbox ${BST_UNCHECKED} ${EndIf} @@ -774,7 +774,7 @@ Function ReadInstallTypes FunctionEnd Function ReadPostInstallOptions - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ; check if the user asked for a desktop shortcut to High Fidelity ${NSD_GetState} $DesktopClientCheckbox $DesktopClientState ${EndIf} @@ -797,19 +797,19 @@ Function ReadPostInstallOptions ${NSD_GetState} $LaunchServerNowCheckbox $LaunchServerNowState ${EndIf} - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ; check if we need to launch the client post-install ${NSD_GetState} $LaunchClientNowCheckbox $LaunchClientNowState ${EndIf} - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ; check if the user asked for a clean install ${NSD_GetState} $CleanInstallCheckbox $CleanInstallState ${EndIf} FunctionEnd Function HandlePostInstallOptions - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ; check if the user asked for a desktop shortcut to High Fidelity ${If} $DesktopClientState == ${BST_CHECKED} CreateShortCut "$DESKTOP\@INTERFACE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@" @@ -849,7 +849,7 @@ Function HandlePostInstallOptions ${EndIf} ${EndIf} - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ; check if the user asked for a clean install ${If} $CleanInstallState == ${BST_CHECKED} SetShellVarContext current @@ -1026,7 +1026,7 @@ Section "-Core installation" @CPACK_NSIS_CREATE_ICONS_EXTRA@ ; Conditional handling for Interface specific options - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@INTERFACE_SHORTCUT_NAME@.lnk" \ "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@" @@ -1185,7 +1185,7 @@ Function .onSelChange !insertmacro SectionList MaybeSelectionChanged ; if neither component is selected, disable the install button - ${IfNot} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${IfNot} @CLIENT_COMPONENT_CONDITIONAL@ ${AndIfNot} @SERVER_COMPONENT_CONDITIONAL@ GetDlgItem $0 $HWNDPARENT 1 EnableWindow $0 0 From 38606f83c8379522d08b39da402399ac52f69fd6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 14 Mar 2018 16:29:47 -0700 Subject: [PATCH 40/44] add SERVER_ONLY handling for installer generation --- cmake/macros/GenerateInstallers.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index 5c68997b8e..742c5b5b94 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -68,6 +68,9 @@ macro(GENERATE_INSTALLERS) if (CLIENT_ONLY) set(SERVER_COMPONENT_CONDITIONAL "0 == 1") set(CLIENT_COMPONENT_CONDITIONAL "1 == 1") + elseif (SERVER_ONLY) + set(SERVER_COMPONENT_CONDITIONAL "1 == 1") + set(CLIENT_COMPONENT_CONDITIONAL "0 == 1") else () set(SERVER_COMPONENT_CONDITIONAL "\\\${SectionIsSelected} \\\${${SERVER_COMPONENT}}") set(CLIENT_COMPONENT_CONDITIONAL "\\\${SectionIsSelected} \\\${${CLIENT_COMPONENT}}") From 9a664f25dcc194e810d99ebd47b2c5b1440d5fd6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 16 Mar 2018 10:28:00 -0700 Subject: [PATCH 41/44] setup custom or express label correctly in installer --- cmake/templates/NSIS.template.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index f9a70ee10e..c2a223146d 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -612,10 +612,11 @@ Function InstallTypesPage ${If} $CustomInstallTemporaryState == ${BST_UNCHECKED} ${NSD_Check} $ExpressInstallRadioButton + Call ChangeExpressLabel + ${Else} + Call ChangeCustomLabel ${EndIf} - Call ChangeExpressLabel - nsDialogs::Show FunctionEnd From 45d16731c3a0a14673dea66160c7a9e6b7b42f06 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 16 Mar 2018 13:48:02 -0700 Subject: [PATCH 42/44] fix abort of setup options page for express client --- cmake/templates/NSIS.template.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index c2a223146d..5a7dd3ced3 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -437,6 +437,12 @@ SectionEnd !define MUI_PAGE_CUSTOMFUNCTION_PRE PageComponentsPre @CPACK_NSIS_PAGE_COMPONENTS@ + ; the MUI_PAGE_CUSTOMFUNCTION_PRE shouldn't be defined here + ; which can happen for a component-less (like client only) install + !ifdef MUI_PAGE_CUSTOMFUNCTION_PRE + !undef MUI_PAGE_CUSTOMFUNCTION_PRE + !endif + Page custom PostInstallOptionsPage ReadPostInstallOptions !define MUI_PAGE_CUSTOMFUNCTION_PRE PageInstallFilesPre From cfdf8c25882fa5b62e5a7e8bd679f3fa9ec6a361 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 19 Mar 2018 13:58:07 -0700 Subject: [PATCH 43/44] handle launch client option for client only --- cmake/templates/NSIS.template.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index 5a7dd3ced3..7faa67d1b0 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -893,7 +893,8 @@ Function HandlePostInstallOptions ${EndIf} ${EndIf} - ${If} $LaunchServerNowState == ${BST_CHECKED} + ${If} @SERVER_COMPONENT_CONDITIONAL@ + ${AndIf} $LaunchServerNowState == ${BST_CHECKED} !insertmacro WriteInstallOption @SERVER_LAUNCH_NOW_REG_KEY@ YES ; both launches use the explorer trick in case the user has elevated permissions for the installer @@ -907,7 +908,7 @@ Function HandlePostInstallOptions Exec '"$WINDIR\explorer.exe" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"' ${EndIf} - ${Else} + ${ElseIf} @CLIENT_COMPONENT_CONDITIONAL@ !insertmacro WriteInstallOption @SERVER_LAUNCH_NOW_REG_KEY@ NO ; launch uses the explorer trick in case the user has elevated permissions for the installer From 00aa564d84f57e0add0b02bfde28183af663dbf4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 21 Mar 2018 10:19:44 -0700 Subject: [PATCH 44/44] Fix crashes on exit because of ResourceManager thread destruction --- tools/oven/src/Oven.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/oven/src/Oven.cpp b/tools/oven/src/Oven.cpp index a9aa6907f1..c3fec2d15e 100644 --- a/tools/oven/src/Oven.cpp +++ b/tools/oven/src/Oven.cpp @@ -40,6 +40,8 @@ Oven::Oven() { } Oven::~Oven() { + DependencyManager::get()->cleanup(); + // quit all worker threads and wait on them for (auto& thread : _workerThreads) { thread->quit();