From a5f5f9fc5d7b3d4a6c2fddf54961b3c5070e441c Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 4 Oct 2017 12:05:13 -0700 Subject: [PATCH 01/21] try to improve performance --- .../src/EntityTreeRenderer.cpp | 10 ------- .../src/RenderableEntityItem.cpp | 17 ------------ .../src/RenderableEntityItem.h | 26 ------------------- .../src/RenderableModelEntityItem.cpp | 9 ++++--- .../src/RenderableModelEntityItem.h | 6 ++--- 5 files changed, 8 insertions(+), 60 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 0cb25a2e2f..f8c40a5229 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -222,16 +222,6 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene _renderablesToUpdate.insert({ entityId, renderable }); } - // NOTE: Looping over all the entity renderers is likely to be a bottleneck in the future - // Currently, this is necessary because the model entity loading logic requires constant polling - // This was working fine because the entity server used to send repeated updates as your view changed, - // but with the improved entity server logic (PR 11141), updateInScene (below) would not be triggered enough - for (const auto& entry : _entitiesInScene) { - const auto& renderable = entry.second; - if (renderable) { - renderable->update(scene, transaction); - } - } if (!_renderablesToUpdate.empty()) { for (const auto& entry : _renderablesToUpdate) { const auto& renderable = entry.second; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index ea514d3181..3f1e89b86c 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -291,18 +291,6 @@ void EntityRenderer::updateInScene(const ScenePointer& scene, Transaction& trans }); } -void EntityRenderer::update(const ScenePointer& scene, Transaction& transaction) { - if (!isValidRenderItem()) { - return; - } - - if (!needsUpdate()) { - return; - } - - doUpdate(scene, transaction, _entity); -} - // // Internal methods // @@ -316,11 +304,6 @@ bool EntityRenderer::needsRenderUpdate() const { return needsRenderUpdateFromEntity(_entity); } -// Returns true if the item needs to have update called -bool EntityRenderer::needsUpdate() const { - return needsUpdateFromEntity(_entity); -} - // Returns true if the item in question needs to have updateInScene called because of changes in the entity bool EntityRenderer::needsRenderUpdateFromEntity(const EntityItemPointer& entity) const { bool success = false; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 56cb39252f..6b47ff8b1d 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -49,8 +49,6 @@ public: virtual bool addToScene(const ScenePointer& scene, Transaction& transaction) final; virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction); - virtual void update(const ScenePointer& scene, Transaction& transaction); - protected: virtual bool needsRenderUpdateFromEntity() const final { return needsRenderUpdateFromEntity(_entity); } virtual void onAddToScene(const EntityItemPointer& entity); @@ -73,12 +71,6 @@ protected: // Returns true if the item in question needs to have updateInScene called because of changes in the entity virtual bool needsRenderUpdateFromEntity(const EntityItemPointer& entity) const; - // Returns true if the item in question needs to have update called - virtual bool needsUpdate() const; - - // Returns true if the item in question needs to have update called because of changes in the entity - virtual bool needsUpdateFromEntity(const EntityItemPointer& entity) const { return false; } - // Will be called on the main thread from updateInScene. This can be used to fetch things like // network textures or model geometry from resource caches virtual void doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) { } @@ -88,8 +80,6 @@ protected: // data in this method if using multi-threaded rendering virtual void doRenderUpdateAsynchronous(const EntityItemPointer& entity); - virtual void doUpdate(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) { } - // Called by the `render` method after `needsRenderUpdate` virtual void doRender(RenderArgs* args) = 0; @@ -158,15 +148,6 @@ protected: onRemoveFromSceneTyped(_typedEntity); } - using Parent::needsUpdateFromEntity; - // Returns true if the item in question needs to have update called because of changes in the entity - virtual bool needsUpdateFromEntity(const EntityItemPointer& entity) const override final { - if (Parent::needsUpdateFromEntity(entity)) { - return true; - } - return needsUpdateFromTypedEntity(_typedEntity); - } - using Parent::needsRenderUpdateFromEntity; // Returns true if the item in question needs to have updateInScene called because of changes in the entity virtual bool needsRenderUpdateFromEntity(const EntityItemPointer& entity) const override final { @@ -181,11 +162,6 @@ protected: doRenderUpdateSynchronousTyped(scene, transaction, _typedEntity); } - virtual void doUpdate(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) override final { - Parent::doUpdate(scene, transaction, entity); - doUpdateTyped(scene, transaction, _typedEntity); - } - virtual void doRenderUpdateAsynchronous(const EntityItemPointer& entity) override final { Parent::doRenderUpdateAsynchronous(entity); doRenderUpdateAsynchronousTyped(_typedEntity); @@ -194,8 +170,6 @@ protected: virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { return false; } virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { } virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { } - virtual bool needsUpdateFromTypedEntity(const TypedEntityPointer& entity) const { return false; } - virtual void doUpdateTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { } virtual void onAddToSceneTyped(const TypedEntityPointer& entity) { } virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) { } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index d1e47fd906..19da8a77f4 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1026,7 +1026,7 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { entity->copyAnimationJointDataToModel(); } -bool ModelEntityRenderer::needsUpdate() const { +bool ModelEntityRenderer::needsRenderUpdate() const { ModelPointer model; withReadLock([&] { model = _model; @@ -1061,10 +1061,10 @@ bool ModelEntityRenderer::needsUpdate() const { return true; } } - return Parent::needsUpdate(); + return Parent::needsRenderUpdate(); } -bool ModelEntityRenderer::needsUpdateFromTypedEntity(const TypedEntityPointer& entity) const { +bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { if (resultWithReadLock([&] { if (entity->hasModel() != _hasModel) { return true; @@ -1126,7 +1126,7 @@ bool ModelEntityRenderer::needsUpdateFromTypedEntity(const TypedEntityPointer& e return false; } -void ModelEntityRenderer::doUpdateTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { +void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { if (_hasModel != entity->hasModel()) { _hasModel = entity->hasModel(); } @@ -1250,6 +1250,7 @@ void ModelEntityRenderer::doUpdateTyped(const ScenePointer& scene, Transaction& void ModelEntityRenderer::handleModelLoaded(bool success) { if (success) { _modelJustLoaded = true; + emit requestRenderUpdate(); } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index ad0afeee0a..77121c30d9 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -138,10 +138,10 @@ protected: virtual ItemKey getKey() override; virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) override; - virtual bool needsUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; - virtual bool needsUpdate() const override; + virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; + virtual bool needsRenderUpdate() const override; virtual void doRender(RenderArgs* args) override; - virtual void doUpdateTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; private: void animate(const TypedEntityPointer& entity); From 9de1ca4e1af3f22431a30af5e68bde0774692a9c Mon Sep 17 00:00:00 2001 From: druiz17 Date: Wed, 4 Oct 2017 13:44:36 -0700 Subject: [PATCH 02/21] allow farGrab module to run when stylus is visible --- .../controllerModules/tabletStylusInput.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/system/controllers/controllerModules/tabletStylusInput.js b/scripts/system/controllers/controllerModules/tabletStylusInput.js index 36ed7920dd..29fa878cb1 100644 --- a/scripts/system/controllers/controllerModules/tabletStylusInput.js +++ b/scripts/system/controllers/controllerModules/tabletStylusInput.js @@ -248,17 +248,20 @@ Script.include("/~/system/libraries/controllers.js"); } }; - this.nearGrabWantsToRun = function(controllerData) { - var moduleName = this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay"; - var module = getEnabledModuleByName(moduleName); - var ready = module ? module.isReady(controllerData) : makeRunningValues(false, [], []); - return ready.active; + this.otherModuleNeedsToRun = function(controllerData) { + var grabOverlayModuleName = this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay"; + var grabOverlayModule = getEnabledModuleByName(grabOverlayModuleName); + var grabOverlayModuleReady = grabOverlayModule ? grabOverlayModule.isReady(controllerData) : makeRunningValues(false, [], []); + var farGrabModuleName = this.hand === RIGHT_HAND ? "RightFarActionGrabEntity" : "LeftFarActionGrabEntity"; + var farGrabModule = getEnabledModuleByName(farGrabModuleName); + var farGrabModuleReady = farGrabModule ? farGrabModule.isReady(controllerData) : makeRunningValues(false, [], []); + return grabOverlayModuleReady.active || farGrabModuleReady.active; }; this.processStylus = function(controllerData) { this.updateStylusTip(); - if (!this.stylusTip.valid || this.overlayLaserActive(controllerData) || this.nearGrabWantsToRun(controllerData)) { + if (!this.stylusTip.valid || this.overlayLaserActive(controllerData) || this.otherModuleNeedsToRun(controllerData)) { this.pointFinger(false); this.hideStylus(); return false; From 347645329eaa14071792d032672ec04e82168e17 Mon Sep 17 00:00:00 2001 From: druiz17 Date: Thu, 5 Oct 2017 09:11:02 -0700 Subject: [PATCH 03/21] fixing laser staying on in edit mode --- .../system/controllers/controllerModules/farActionGrabEntity.js | 1 - scripts/system/libraries/entitySelectionTool.js | 1 - 2 files changed, 2 deletions(-) diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index c5b82f75f0..81ffaa4189 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -408,7 +408,6 @@ Script.include("/~/system/libraries/controllers.js"); this.distanceRotating = false; if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) { - this.updateLaserPointer(controllerData); this.prepareDistanceRotatingData(controllerData); return makeRunningValues(true, [], []); } else { diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 4df25c41b7..010c86f4d4 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -4076,7 +4076,6 @@ SelectionDisplay = (function() { if (controllerPose.valid && lastControllerPoses[hand].valid) { if (!Vec3.equal(controllerPose.position, lastControllerPoses[hand].position) || !Vec3.equal(controllerPose.rotation, lastControllerPoses[hand].rotation)) { - print("setting controller pose"); that.mouseMoveEvent({}); } } From c45fe1af6c966cb541ae7b3bdd4073e02039b004 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sat, 7 Oct 2017 19:41:43 -0700 Subject: [PATCH 04/21] Fix rendering transform for text3d overlays --- interface/src/ui/overlays/Text3DOverlay.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 57e3c32060..2e55a9a471 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -88,6 +88,7 @@ void Text3DOverlay::update(float deltatime) { applyTransformTo(transform); setTransform(transform); } + Parent::update(deltatime); } void Text3DOverlay::render(RenderArgs* args) { From 4d2f16efc3f1d37521f761c30d4c513a4b9f06b1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 8 Oct 2017 18:01:41 -0700 Subject: [PATCH 05/21] allow project to be built with clang on Linux --- .../src/audio/AudioMixerSlavePool.cpp | 4 ++++ .../src/avatars/AvatarMixerSlavePool.cpp | 4 ++++ cmake/externals/glew/CMakeLists.txt | 2 +- cmake/externals/nvtt/CMakeLists.txt | 2 +- cmake/macros/MemoryDebugger.cmake | 14 +++++++++++--- interface/CMakeLists.txt | 2 +- libraries/networking/src/LimitedNodeList.cpp | 2 +- 7 files changed, 23 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/audio/AudioMixerSlavePool.cpp b/assignment-client/src/audio/AudioMixerSlavePool.cpp index d2c19d97ba..e28c96e259 100644 --- a/assignment-client/src/audio/AudioMixerSlavePool.cpp +++ b/assignment-client/src/audio/AudioMixerSlavePool.cpp @@ -97,7 +97,11 @@ void AudioMixerSlavePool::run(ConstIter begin, ConstIter end) { #else // fill the queue std::for_each(_begin, _end, [&](const SharedNodePointer& node) { +#if defined(__clang__) && defined(Q_OS_LINUX) + _queue.push(node); +#else _queue.emplace(node); +#endif }); { diff --git a/assignment-client/src/avatars/AvatarMixerSlavePool.cpp b/assignment-client/src/avatars/AvatarMixerSlavePool.cpp index 8afbc1cfe4..25b88686b7 100644 --- a/assignment-client/src/avatars/AvatarMixerSlavePool.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlavePool.cpp @@ -97,7 +97,11 @@ void AvatarMixerSlavePool::run(ConstIter begin, ConstIter end) { #else // fill the queue std::for_each(_begin, _end, [&](const SharedNodePointer& node) { +#if defined(__clang__) && defined(Q_OS_LINUX) + _queue.push(node); +#else _queue.emplace(node); +#endif }); { diff --git a/cmake/externals/glew/CMakeLists.txt b/cmake/externals/glew/CMakeLists.txt index 28a599bfa6..6c3208981d 100644 --- a/cmake/externals/glew/CMakeLists.txt +++ b/cmake/externals/glew/CMakeLists.txt @@ -9,7 +9,7 @@ ExternalProject_Add( ${EXTERNAL_NAME} URL http://hifi-public.s3.amazonaws.com/dependencies/glew_simple_1.13.0.zip URL_MD5 73f833649e904257b35bf4e84f8bdfb5 - CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= + CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_POSITION_INDEPENDENT_CODE=ON LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 diff --git a/cmake/externals/nvtt/CMakeLists.txt b/cmake/externals/nvtt/CMakeLists.txt index fa9d7b5ea1..00722bd1e0 100644 --- a/cmake/externals/nvtt/CMakeLists.txt +++ b/cmake/externals/nvtt/CMakeLists.txt @@ -31,7 +31,7 @@ else () ${EXTERNAL_NAME} URL http://hifi-public.s3.amazonaws.com/dependencies/nvidia-texture-tools-2.1.0.hifi.zip URL_MD5 5794b950f8b265a9a41b2839b3bf7ebb - CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DNVTT_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= + CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DNVTT_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_POSITION_INDEPENDENT_CODE=ON LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 diff --git a/cmake/macros/MemoryDebugger.cmake b/cmake/macros/MemoryDebugger.cmake index 6df41257f2..29634b90b7 100644 --- a/cmake/macros/MemoryDebugger.cmake +++ b/cmake/macros/MemoryDebugger.cmake @@ -14,9 +14,17 @@ endif () if (HIFI_MEMORY_DEBUGGING) if (UNIX) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -U_FORTIFY_SOURCE -fno-stack-protector -fno-omit-frame-pointer") - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=address") - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=address") + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # for clang on Linux + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address") + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address") + else () + # for gcc on Linux + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fsanitize=address -U_FORTIFY_SOURCE -fno-stack-protector -fno-omit-frame-pointer") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=undefined -fsanitize=address") + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=undefined -fsanitize=address") + endif() endif (UNIX) endif () endmacro(SETUP_MEMORY_DEBUGGER) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 305a6475f6..5f34ecf199 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -262,7 +262,7 @@ target_link_libraries( ) if (UNIX) - target_link_libraries(${TARGET_NAME} pthread) + target_link_libraries(${TARGET_NAME} pthread atomic) endif(UNIX) # assume we are using a Qt build without bearer management diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 574ec7f054..300a445ebd 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -676,7 +676,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t } // insert the new node and release our read lock -#ifdef Q_OS_ANDROID +#if defined(Q_OS_ANDROID) || (defined(__clang__) && defined(Q_OS_LINUX)) _nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodePointer)); #else _nodeHash.emplace(newNode->getUUID(), newNodePointer); From 873ae9b9d650244fd1bb303492759c92912b3ca0 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 9 Oct 2017 13:36:38 -0700 Subject: [PATCH 06/21] model asks for renderUpdate if animating --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 19da8a77f4..df78bd9439 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1244,6 +1244,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce mapJoints(entity, model->getJointNames()); } animate(entity); + emit requestRenderUpdate(); } } From aa08053a283a5d88d0610bbcfef331d140845e95 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 9 Oct 2017 17:34:43 -0700 Subject: [PATCH 07/21] fix osx build --- cmake/macros/MemoryDebugger.cmake | 6 +++--- interface/CMakeLists.txt | 8 +++++++- interface/src/scripting/WalletScriptingInterface.cpp | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/cmake/macros/MemoryDebugger.cmake b/cmake/macros/MemoryDebugger.cmake index 29634b90b7..ed80e03c6b 100644 --- a/cmake/macros/MemoryDebugger.cmake +++ b/cmake/macros/MemoryDebugger.cmake @@ -16,9 +16,9 @@ if (HIFI_MEMORY_DEBUGGING) if (UNIX) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") # for clang on Linux - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address") - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address") - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address -fsanitize-recover=address") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address -fsanitize-recover=address") + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address -fsanitize-recover=address") else () # for gcc on Linux SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fsanitize=address -U_FORTIFY_SOURCE -fno-stack-protector -fno-omit-frame-pointer") diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 5f34ecf199..b16ad58431 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -262,7 +262,13 @@ target_link_libraries( ) if (UNIX) - target_link_libraries(${TARGET_NAME} pthread atomic) + if (CMAKE_SYSTEM_NAME MATCHES "Linux") + # Linux + target_link_libraries(${TARGET_NAME} pthread atomic) + else () + # OSX + target_link_libraries(${TARGET_NAME} pthread) + endif () endif(UNIX) # assume we are using a Qt build without bearer management diff --git a/interface/src/scripting/WalletScriptingInterface.cpp b/interface/src/scripting/WalletScriptingInterface.cpp index 555e9477b0..0529cc2d4e 100644 --- a/interface/src/scripting/WalletScriptingInterface.cpp +++ b/interface/src/scripting/WalletScriptingInterface.cpp @@ -18,7 +18,6 @@ CheckoutProxy::CheckoutProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(q WalletScriptingInterface::WalletScriptingInterface() { } -static const QString CHECKOUT_QML_PATH = qApp->applicationDirPath() + "../../../qml/hifi/commerce/checkout/Checkout.qml"; void WalletScriptingInterface::buy(const QString& name, const QString& id, const int& price, const QString& href) { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "buy", Q_ARG(const QString&, name), Q_ARG(const QString&, id), Q_ARG(const int&, price), Q_ARG(const QString&, href)); @@ -28,6 +27,7 @@ void WalletScriptingInterface::buy(const QString& name, const QString& id, const auto tabletScriptingInterface = DependencyManager::get(); auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + const QString CHECKOUT_QML_PATH = qApp->applicationDirPath() + "../../../qml/hifi/commerce/checkout/Checkout.qml"; tablet->loadQMLSource(CHECKOUT_QML_PATH); DependencyManager::get()->openTablet(); @@ -44,4 +44,4 @@ void WalletScriptingInterface::buy(const QString& name, const QString& id, const checkout->writeProperty("itemId", id); checkout->writeProperty("itemPrice", price); checkout->writeProperty("itemHref", href); -} \ No newline at end of file +} From be2b2416293dabbe702414766eec607a2a250d95 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 10 Oct 2017 12:20:48 -0700 Subject: [PATCH 08/21] Lots of progress; don't yet have some things --- .../InspectionCertificate.qml | 77 ++++++++++++++----- .../hifi/commerce/purchases/PurchasedItem.qml | 5 +- .../qml/hifi/commerce/purchases/Purchases.qml | 3 +- interface/src/commerce/Ledger.cpp | 20 +++-- interface/src/commerce/Ledger.h | 7 +- interface/src/commerce/QmlCommerce.cpp | 6 ++ interface/src/commerce/QmlCommerce.h | 3 + scripts/system/marketplaces/marketplaces.js | 20 ++--- 8 files changed, 93 insertions(+), 48 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml index 19728daa82..2a20f7fa9b 100644 --- a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml +++ b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml @@ -25,7 +25,8 @@ Rectangle { HifiConstants { id: hifi; } id: root; - property string marketplaceId: ""; + property string marketplaceUrl; + property string certificateId; property string itemName: "--"; property string itemOwner: "--"; property string itemEdition: "--"; @@ -35,6 +36,26 @@ Rectangle { color: hifi.colors.faintGray; Hifi.QmlCommerce { id: commerce; + + onCertificateInfoResult: { + if (result.status !== 'success') { + console.log("Failed to get certificate info", result.message); + } else { + root.marketplaceUrl = result.data.marketplace_item_url; + root.itemOwner = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"; + root.itemEdition = result.data.edition_number + "/" + (result.data.limited_run === -1 ? "\u221e" : result.data.limited_run); + root.dateOfPurchase = getFormattedDate(result.data.transfer_created_at * 1000); + + if (result.data.invalid_reason) { + errorText.text = "Here we will display some text if there's an error with the certificate " + + "(DMCA takedown, invalid cert, location of item updated)"; + } + } + } + } + + onCertificateIdChanged: { + commerce.certificateInfo(certificateId); } // This object is always used in a popup. @@ -126,7 +147,7 @@ Rectangle { anchors.fill: parent; hoverEnabled: enabled; onClicked: { - sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', itemId: root.marketplaceId}); + sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', marketplaceUrl: root.marketplaceUrl}); } onEntered: itemName.color = hifi.colors.blueHighlight; onExited: itemName.color = hifi.colors.blueAccent; @@ -199,11 +220,10 @@ Rectangle { RalewayRegular { id: dateOfPurchaseHeader; text: "DATE OF PURCHASE"; - visible: root.dateOfPurchase !== ""; // Text size size: 16; // Anchors - anchors.top: ownedBy.bottom; + anchors.top: edition.bottom; anchors.topMargin: 20; anchors.left: parent.left; anchors.leftMargin: 45; @@ -216,14 +236,13 @@ Rectangle { AnonymousProRegular { id: dateOfPurchase; text: root.dateOfPurchase; - visible: root.dateOfPurchase !== ""; // Text size size: 22; // Anchors - anchors.top: editionHeader.bottom; + anchors.top: dateOfPurchaseHeader.bottom; anchors.topMargin: 4; - anchors.left: editionHeader.left; - anchors.right: editionHeader.right; + anchors.left: dateOfPurchaseHeader.left; + anchors.right: dateOfPurchaseHeader.right; height: paintedHeight; // Style color: hifi.colors.darkGray; @@ -231,15 +250,13 @@ Rectangle { RalewayRegular { id: errorText; - text: "Here we will display some text if there's an error with the certificate " + - "(DMCA takedown, invalid cert, location of item updated)"; // Text size size: 20; // Anchors - anchors.top: root.dateOfPurchase !== "" ? dateOfPurchase.bottom : edition.bottom; + anchors.top: dateOfPurchase.bottom; anchors.topMargin: 40; - anchors.left: root.dateOfPurchase !== "" ? dateOfPurchase.left : edition.left; - anchors.right: root.dateOfPurchase !== "" ? dateOfPurchase.right : edition.right; + anchors.left: dateOfPurchase.left; + anchors.right: dateOfPurchase.right; anchors.bottom: parent.bottom; // Style wrapMode: Text.WordWrap; @@ -290,7 +307,7 @@ Rectangle { height: 50; text: "View In Market" onClicked: { - sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', itemId: root.marketplaceId}); + sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', marketplaceUrl: root.marketplaceUrl}); } } } @@ -313,19 +330,37 @@ Rectangle { // function fromScript(message) { switch (message.method) { - case 'inspectionCertificate_setMarketplaceId': - root.marketplaceId = message.marketplaceId; - break; - case 'inspectionCertificate_setItemInfo': - root.itemName = message.itemName; - root.itemOwner = message.itemOwner; - root.itemEdition = message.itemEdition; + case 'inspectionCertificate_setCertificateId': + root.certificateId = message.certificateId; break; default: console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message)); } } signal sendToScript(var message); + + function getFormattedDate(timestamp) { + var a = new Date(timestamp); + var year = a.getFullYear(); + var month = a.getMonth(); + var day = a.getDate(); + var hour = a.getHours(); + var drawnHour = hour; + if (hour === 0) { + drawnHour = 12; + } else if (hour > 12) { + drawnHour -= 12; + } + + var amOrPm = "AM"; + if (hour >= 12) { + amOrPm = "PM"; + } + + var min = a.getMinutes(); + var sec = a.getSeconds(); + return year + '-' + month + '-' + day + ' ' + drawnHour + ':' + min + amOrPm; + } // // FUNCTION DEFINITIONS END // diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index 5eb5516519..e7e16668fe 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -34,6 +34,7 @@ Item { property string itemId; property string itemPreviewImageUrl; property string itemHref; + property string certificateId; property int displayedItemCount; property int itemEdition; property int numberSold; @@ -168,7 +169,7 @@ Item { anchors.fill: parent; hoverEnabled: enabled; onClicked: { - sendToPurchases({method: 'purchases_itemCertificateClicked', itemMarketplaceId: root.itemId}); + sendToPurchases({method: 'purchases_itemCertificateClicked', itemCertificateId: root.certificateId}); } onEntered: { certificateIcon.color = hifi.colors.black; @@ -225,7 +226,7 @@ Item { } else if (root.purchaseStatus === "invalidated") { "INVALIDATED" } else if (root.numberSold !== -1) { - ("Sales: " + root.numberSold + "/" + (root.limitedRun === -1 ? "INFTY" : root.limitedRun)) + ("Sales: " + root.numberSold + "/" + (root.limitedRun === -1 ? "\u221e" : root.limitedRun)) } else { "" } diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index ea32c139d4..54abe2d5fc 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -684,8 +684,7 @@ Rectangle { titleBarContainer.referrerURL = message.referrerURL; filterBar.text = message.filterText ? message.filterText : ""; break; - case 'inspectionCertificate_setMarketplaceId': - case 'inspectionCertificate_setItemInfo': + case 'inspectionCertificate_setCertificateId': inspectionCertificate.fromScript(message); break; case 'purchases_showMyItems': diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index a68a6fe929..9a6840c76a 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -13,7 +13,6 @@ #include #include #include -#include "AccountManager.h" #include "Wallet.h" #include "Ledger.h" #include "CommerceLogging.h" @@ -47,14 +46,15 @@ Handler(buy) Handler(receiveAt) Handler(balance) Handler(inventory) +Handler(certificateInfo) -void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, QJsonObject request) { +void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request) { auto accountManager = DependencyManager::get(); const QString URL = "/api/v1/commerce/"; JSONCallbackParameters callbackParams(this, success, this, fail); qCInfo(commerce) << "Sending" << endpoint << QJsonDocument(request).toJson(QJsonDocument::Compact); accountManager->sendRequest(URL + endpoint, - AccountManagerAuth::Required, + authType, method, callbackParams, QJsonDocument(request).toJson()); @@ -70,14 +70,14 @@ void Ledger::signedSend(const QString& propertyName, const QByteArray& text, con } else { request["signature"] = QString("controlled failure!"); } - send(endpoint, success, fail, QNetworkAccessManager::PutOperation, request); + send(endpoint, success, fail, QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, request); } void Ledger::keysQuery(const QString& endpoint, const QString& success, const QString& fail) { auto wallet = DependencyManager::get(); QJsonObject request; request["public_keys"] = QJsonArray::fromStringList(wallet->listPublicKeys()); - send(endpoint, success, fail, QNetworkAccessManager::PostOperation, request); + send(endpoint, success, fail, QNetworkAccessManager::PostOperation, AccountManagerAuth::Required, request); } void Ledger::buy(const QString& hfc_key, int cost, const QString& asset_id, const QString& inventory_key, const bool controlled_failure) { @@ -192,7 +192,7 @@ void Ledger::history(const QStringList& keys) { void Ledger::resetSuccess(QNetworkReply& reply) { apiResponse("reset", reply); } void Ledger::resetFailure(QNetworkReply& reply) { failResponse("reset", reply); } void Ledger::reset() { - send("reset_user_hfc_account", "resetSuccess", "resetFailure", QNetworkAccessManager::PutOperation, QJsonObject()); + send("reset_user_hfc_account", "resetSuccess", "resetFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, QJsonObject()); } void Ledger::accountSuccess(QNetworkReply& reply) { @@ -217,7 +217,7 @@ void Ledger::accountFailure(QNetworkReply& reply) { failResponse("account", reply); } void Ledger::account() { - send("hfc_account", "accountSuccess", "accountFailure", QNetworkAccessManager::PutOperation, QJsonObject()); + send("hfc_account", "accountSuccess", "accountFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, QJsonObject()); } // The api/failResponse is called just for the side effect of logging. @@ -234,3 +234,9 @@ void Ledger::updateLocation(const QString& asset_id, const QString location, con auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); signedSend("transaction", transactionString, key, "location", "updateLocationSuccess", "updateLocationFailure", controlledFailure); } + +void Ledger::certificateInfo(const QString& certificateId) { + QString endpoint = "proof_of_purchase_status/transfer/" + certificateId; + QJsonObject request; + send(endpoint, "certificateInfoSuccess", "certificateInfoFailure", QNetworkAccessManager::GetOperation, AccountManagerAuth::None, request); +} diff --git a/interface/src/commerce/Ledger.h b/interface/src/commerce/Ledger.h index da6c67224f..ae001010f0 100644 --- a/interface/src/commerce/Ledger.h +++ b/interface/src/commerce/Ledger.h @@ -17,6 +17,7 @@ #include #include #include +#include "AccountManager.h" class Ledger : public QObject, public Dependency { @@ -32,6 +33,7 @@ public: void account(); void reset(); void updateLocation(const QString& asset_id, const QString location, const bool controlledFailure = false); + void certificateInfo(const QString& certificateId); signals: void buyResult(QJsonObject result); @@ -41,6 +43,7 @@ signals: void historyResult(QJsonObject result); void accountResult(QJsonObject result); void locationUpdateResult(QJsonObject result); + void certificateInfoResult(QJsonObject result); public slots: void buySuccess(QNetworkReply& reply); @@ -59,11 +62,13 @@ public slots: void accountFailure(QNetworkReply& reply); void updateLocationSuccess(QNetworkReply& reply); void updateLocationFailure(QNetworkReply& reply); + void certificateInfoSuccess(QNetworkReply& reply); + void certificateInfoFailure(QNetworkReply& reply); private: QJsonObject apiResponse(const QString& label, QNetworkReply& reply); QJsonObject failResponse(const QString& label, QNetworkReply& reply); - void send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, QJsonObject request); + void send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request); void keysQuery(const QString& endpoint, const QString& success, const QString& fail); void signedSend(const QString& propertyName, const QByteArray& text, const QString& key, const QString& endpoint, const QString& success, const QString& fail, const bool controlled_failure = false); }; diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index ee75bc59e3..803264fa9f 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -29,6 +29,7 @@ QmlCommerce::QmlCommerce(QQuickItem* parent) : OffscreenQmlDialog(parent) { connect(wallet.data(), &Wallet::keyFilePathIfExistsResult, this, &QmlCommerce::keyFilePathIfExistsResult); connect(ledger.data(), &Ledger::accountResult, this, &QmlCommerce::accountResult); connect(wallet.data(), &Wallet::walletStatusResult, this, &QmlCommerce::walletStatusResult); + connect(ledger.data(), &Ledger::certificateInfoResult, this, &QmlCommerce::certificateInfoResult); } void QmlCommerce::getWalletStatus() { @@ -125,3 +126,8 @@ void QmlCommerce::account() { auto ledger = DependencyManager::get(); ledger->account(); } + +void QmlCommerce::certificateInfo(const QString& certificateId) { + auto ledger = DependencyManager::get(); + ledger->certificateInfo(certificateId); +} diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index 45a5360680..ae63133425 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -43,6 +43,7 @@ signals: void inventoryResult(QJsonObject result); void historyResult(QJsonObject result); void accountResult(QJsonObject result); + void certificateInfoResult(QJsonObject result); protected: Q_INVOKABLE void getWalletStatus(); @@ -63,6 +64,8 @@ protected: Q_INVOKABLE void generateKeyPair(); Q_INVOKABLE void reset(); Q_INVOKABLE void account(); + + Q_INVOKABLE void certificateInfo(const QString& certificateId); }; #endif // hifi_QmlCommerce_h diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index bf9822ba19..6880d10c18 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -134,22 +134,12 @@ tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH); } - function setCertificateInfo(currentEntityWithContextOverlay, itemMarketplaceId) { + function setCertificateInfo(currentEntityWithContextOverlay, itemCertificateId) { wireEventBridge(true); tablet.sendToQml({ - method: 'inspectionCertificate_setMarketplaceId', - marketplaceId: itemMarketplaceId || Entities.getEntityProperties(currentEntityWithContextOverlay, ['marketplaceID']).marketplaceID + method: 'inspectionCertificate_setCertificateId', + certificateId: itemCertificateId || Entities.getEntityProperties(currentEntityWithContextOverlay, ['certificateID']).certificateID }); - // ZRF FIXME! Make a call to the endpoint to get item info instead of this silliness - Script.setTimeout(function () { - var randomNumber = Math.floor((Math.random() * 150) + 1); - tablet.sendToQml({ - method: 'inspectionCertificate_setItemInfo', - itemName: "The Greatest Item", - itemOwner: "ABCDEFG1234567", - itemEdition: (Math.floor(Math.random() * randomNumber) + " / " + randomNumber) - }); - }, 500); } function onUsernameChanged() { @@ -358,13 +348,13 @@ tablet.loadQMLSource("TabletAddressDialog.qml"); break; case 'purchases_itemCertificateClicked': - setCertificateInfo("", message.itemMarketplaceId); + setCertificateInfo("", message.itemCertificateId); break; case 'inspectionCertificate_closeClicked': tablet.gotoHomeScreen(); break; case 'inspectionCertificate_showInMarketplaceClicked': - tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.itemId, MARKETPLACES_INJECT_SCRIPT_URL); + tablet.gotoWebScreen(message.marketplaceUrl, MARKETPLACES_INJECT_SCRIPT_URL); break; case 'header_myItemsClicked': referrerURL = MARKETPLACE_URL_INITIAL; From 702528a8cc492c5a17e0125eb030fa07a7d2990c Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 10 Oct 2017 13:27:17 -0700 Subject: [PATCH 09/21] Fully integrate cert properties --- .../InspectionCertificate.qml | 37 ++++++++++++++++--- .../qml/hifi/commerce/purchases/Purchases.qml | 1 + 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml index 2a20f7fa9b..7e3c665543 100644 --- a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml +++ b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml @@ -30,7 +30,7 @@ Rectangle { property string itemName: "--"; property string itemOwner: "--"; property string itemEdition: "--"; - property string dateOfPurchase: ""; + property string dateOfPurchase: "--"; property bool isLightbox: false; // Style color: hifi.colors.faintGray; @@ -45,17 +45,43 @@ Rectangle { root.itemOwner = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"; root.itemEdition = result.data.edition_number + "/" + (result.data.limited_run === -1 ? "\u221e" : result.data.limited_run); root.dateOfPurchase = getFormattedDate(result.data.transfer_created_at * 1000); + root.itemName = result.data.marketplace_item_name; - if (result.data.invalid_reason) { - errorText.text = "Here we will display some text if there's an error with the certificate " + - "(DMCA takedown, invalid cert, location of item updated)"; + if (result.data.invalid_reason || result.data.transfer_status[0] === "failed") { + titleBarText.text = "Invalid Certificate"; + titleBarText.color = hifi.colors.redHighlight; + popText.text = ""; + if (result.data.invalid_reason) { + errorText.text = result.data.invalid_reason; + } + } else if (result.data.transfer_status[0] === "pending") { + titleBarText.text = "Certificate Pending"; + errorText.text = "The status of this item is still pending confirmation. If the purchase is not confirmed, " + + "this entity will be cleaned up by the domain."; + errorText.color = hifi.colors.baseGray; } } } } onCertificateIdChanged: { - commerce.certificateInfo(certificateId); + if (certificateId !== "") { + commerce.certificateInfo(certificateId); + } + } + + onVisibleChanged: { + if (!visible) { + titleBarText.text = "Certificate"; + popText.text = "PROOF OF PURCHASE"; + root.certificateId = ""; + root.itemName = "--"; + root.itemOwner = "--"; + root.itemEdition = "--"; + root.dateOfPurchase = "--"; + root.marketplaceUrl = ""; + errorText.text = ""; + } } // This object is always used in a popup. @@ -298,6 +324,7 @@ Rectangle { // "Show In Marketplace" button HifiControlsUit.Button { id: showInMarketplaceButton; + enabled: root.marketplaceUrl; color: hifi.buttons.blue; colorScheme: hifi.colorSchemes.light; anchors.top: parent.top; diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 54abe2d5fc..b5697f687d 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -427,6 +427,7 @@ Rectangle { itemId: id; itemPreviewImageUrl: preview; itemHref: download_url; + certificateId: certificate_id; purchaseStatus: status; purchaseStatusChanged: statusChanged; itemEdition: model.edition_number; From 5e383e2b1c3f96380aeb0777cbe7dc8e72f76d68 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 10 Oct 2017 14:56:17 -0700 Subject: [PATCH 10/21] My Item certificates --- .../InspectionCertificate.qml | 63 +++++++++++++------ interface/src/commerce/Ledger.cpp | 19 +++++- 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml index 7e3c665543..90c8c318a5 100644 --- a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml +++ b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml @@ -32,6 +32,7 @@ Rectangle { property string itemEdition: "--"; property string dateOfPurchase: "--"; property bool isLightbox: false; + property bool isMyCert: false; // Style color: hifi.colors.faintGray; Hifi.QmlCommerce { @@ -42,7 +43,9 @@ Rectangle { console.log("Failed to get certificate info", result.message); } else { root.marketplaceUrl = result.data.marketplace_item_url; - root.itemOwner = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"; + root.isMyCert = result.isMyCert ? result.isMyCert : false; + root.itemOwner = root.isMyCert ? Account.username : + "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"; root.itemEdition = result.data.edition_number + "/" + (result.data.limited_run === -1 ? "\u221e" : result.data.limited_run); root.dateOfPurchase = getFormattedDate(result.data.transfer_created_at * 1000); root.itemName = result.data.marketplace_item_name; @@ -80,6 +83,7 @@ Rectangle { root.itemEdition = "--"; root.dateOfPurchase = "--"; root.marketplaceUrl = ""; + root.isMyCert = false; errorText.text = ""; } } @@ -162,7 +166,7 @@ Rectangle { size: 28; // Anchors anchors.top: itemNameHeader.bottom; - anchors.topMargin: 4; + anchors.topMargin: 8; anchors.left: itemNameHeader.left; anchors.right: itemNameHeader.right; height: paintedHeight; @@ -187,14 +191,20 @@ Rectangle { size: 16; // Anchors anchors.top: itemName.bottom; - anchors.topMargin: 20; + anchors.topMargin: 28; anchors.left: parent.left; anchors.leftMargin: 45; anchors.right: parent.right; anchors.rightMargin: 16; height: paintedHeight; // Style - color: hifi.colors.baseGray; + color: hifi.colors.lightGray; + } + FontLoader { id: ralewayRegular; source: "../../../../fonts/Raleway-Regular.ttf"; } + TextMetrics { + id: textMetrics; + font.family: ralewayRegular.name + text: root.itemOwner; } RalewayRegular { id: ownedBy; @@ -203,14 +213,31 @@ Rectangle { size: 22; // Anchors anchors.top: ownedByHeader.bottom; - anchors.topMargin: 4; + anchors.topMargin: 8; anchors.left: ownedByHeader.left; - anchors.right: ownedByHeader.right; - height: paintedHeight; + height: textMetrics.height; + width: root.isMyCert ? textMetrics.width + 25 : ownedByHeader.width; // Style color: hifi.colors.darkGray; elide: Text.ElideRight; } + AnonymousProRegular { + id: isMyCertText; + visible: root.isMyCert; + text: "(Private)"; + size: 18; + // Anchors + anchors.top: ownedBy.top; + anchors.topMargin: 4; + anchors.bottom: ownedBy.bottom; + anchors.left: ownedBy.right; + anchors.leftMargin: 4; + anchors.right: ownedByHeader.right; + // Style + color: hifi.colors.lightGray; + elide: Text.ElideRight; + verticalAlignment: Text.AlignVCenter; + } RalewayRegular { id: editionHeader; @@ -219,23 +246,23 @@ Rectangle { size: 16; // Anchors anchors.top: ownedBy.bottom; - anchors.topMargin: 20; + anchors.topMargin: 28; anchors.left: parent.left; anchors.leftMargin: 45; anchors.right: parent.right; anchors.rightMargin: 16; height: paintedHeight; // Style - color: hifi.colors.baseGray; + color: hifi.colors.lightGray; } AnonymousProRegular { id: edition; text: root.itemEdition; // Text size - size: 22; + size: 18; // Anchors anchors.top: editionHeader.bottom; - anchors.topMargin: 4; + anchors.topMargin: 8; anchors.left: editionHeader.left; anchors.right: editionHeader.right; height: paintedHeight; @@ -250,23 +277,23 @@ Rectangle { size: 16; // Anchors anchors.top: edition.bottom; - anchors.topMargin: 20; + anchors.topMargin: 28; anchors.left: parent.left; anchors.leftMargin: 45; anchors.right: parent.right; anchors.rightMargin: 16; height: paintedHeight; // Style - color: hifi.colors.baseGray; + color: hifi.colors.lightGray; } AnonymousProRegular { id: dateOfPurchase; text: root.dateOfPurchase; // Text size - size: 22; + size: 18; // Anchors anchors.top: dateOfPurchaseHeader.bottom; - anchors.topMargin: 4; + anchors.topMargin: 8; anchors.left: dateOfPurchaseHeader.left; anchors.right: dateOfPurchaseHeader.right; height: paintedHeight; @@ -280,7 +307,7 @@ Rectangle { size: 20; // Anchors anchors.top: dateOfPurchase.bottom; - anchors.topMargin: 40; + anchors.topMargin: 36; anchors.left: dateOfPurchase.left; anchors.right: dateOfPurchase.right; anchors.bottom: parent.bottom; @@ -297,7 +324,7 @@ Rectangle { Item { id: buttonsContainer; anchors.bottom: parent.bottom; - anchors.bottomMargin: 50; + anchors.bottomMargin: 30; anchors.left: parent.left; anchors.right: parent.right; height: 50; @@ -386,7 +413,7 @@ Rectangle { var min = a.getMinutes(); var sec = a.getSeconds(); - return year + '-' + month + '-' + day + ' ' + drawnHour + ':' + min + amOrPm; + return year + '-' + month + '-' + day + '
' + drawnHour + ':' + min + amOrPm; } // // FUNCTION DEFINITIONS END diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 9a6840c76a..b63eff0eee 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -46,7 +46,6 @@ Handler(buy) Handler(receiveAt) Handler(balance) Handler(inventory) -Handler(certificateInfo) void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request) { auto accountManager = DependencyManager::get(); @@ -235,6 +234,24 @@ void Ledger::updateLocation(const QString& asset_id, const QString location, con signedSend("transaction", transactionString, key, "location", "updateLocationSuccess", "updateLocationFailure", controlledFailure); } +void Ledger::certificateInfoSuccess(QNetworkReply& reply) { + auto wallet = DependencyManager::get(); + auto accountManager = DependencyManager::get(); + + QByteArray response = reply.readAll(); + QJsonObject replyObject = QJsonDocument::fromJson(response).object(); + + QStringList keys = wallet->listPublicKeys(); + if (keys.count() != 0) { + QJsonObject data = replyObject["data"].toObject(); + if (data["transfer_recipient_key"].toString() == keys[0]) { + replyObject.insert("isMyCert", true); + } + } + qInfo(commerce) << "certificateInfo" << "response" << QJsonDocument(replyObject).toJson(QJsonDocument::Compact); + emit certificateInfoResult(replyObject); +} +void Ledger::certificateInfoFailure(QNetworkReply& reply) { failResponse("certificateInfo", reply); } void Ledger::certificateInfo(const QString& certificateId) { QString endpoint = "proof_of_purchase_status/transfer/" + certificateId; QJsonObject request; From 4ebccfa65c8205ea0b35c523b5034237b88e4d48 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 10 Oct 2017 16:23:43 -0700 Subject: [PATCH 11/21] Use put instead of get sob --- interface/src/commerce/Ledger.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index b63eff0eee..80e599fb24 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -253,7 +253,8 @@ void Ledger::certificateInfoSuccess(QNetworkReply& reply) { } void Ledger::certificateInfoFailure(QNetworkReply& reply) { failResponse("certificateInfo", reply); } void Ledger::certificateInfo(const QString& certificateId) { - QString endpoint = "proof_of_purchase_status/transfer/" + certificateId; + QString endpoint = "proof_of_purchase_status/transfer"; QJsonObject request; - send(endpoint, "certificateInfoSuccess", "certificateInfoFailure", QNetworkAccessManager::GetOperation, AccountManagerAuth::None, request); + request["certificate_id"] = certificateId; + send(endpoint, "certificateInfoSuccess", "certificateInfoFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::None, request); } From 026195223a0da05106744fbd1d83e380980c015f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 10 Oct 2017 12:58:37 -0700 Subject: [PATCH 12/21] more correct use of BufferView in GeometryCache --- libraries/render-utils/src/GeometryCache.cpp | 75 ++++++++++++-------- libraries/render-utils/src/GeometryCache.h | 8 +-- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 658eab7210..93f3002fe8 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -84,67 +84,83 @@ std::vector polygon() { } void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const geometry::VertexVector& vertices) { + gpu::Buffer::Size offset = vertexBuffer->getSize(); vertexBuffer->append(vertices); - _positionView = gpu::BufferView(vertexBuffer, 0, - vertexBuffer->getSize(), SHAPE_VERTEX_STRIDE, POSITION_ELEMENT); - _normalView = gpu::BufferView(vertexBuffer, SHAPE_NORMALS_OFFSET, - vertexBuffer->getSize(), SHAPE_VERTEX_STRIDE, NORMAL_ELEMENT); + gpu::Buffer::Size viewSize = vertices.size() * 2 * sizeof(glm::vec3); + + _positionView = gpu::BufferView(vertexBuffer, offset, + viewSize, SHAPE_VERTEX_STRIDE, POSITION_ELEMENT); + _normalView = gpu::BufferView(vertexBuffer, offset + SHAPE_NORMALS_OFFSET, + viewSize, SHAPE_VERTEX_STRIDE, NORMAL_ELEMENT); } void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices) { - _indices = indexBuffer; + gpu::Buffer::Size offset = indexBuffer->getSize(); if (!indices.empty()) { - _indexOffset = indexBuffer->getSize() / SHAPE_INDEX_SIZE; - _indexCount = indices.size(); - indexBuffer->append(indices); + for (uint32_t i = 0; i < indices.size(); ++i) { + indexBuffer->append((uint16_t)indices[i]); + } } + gpu::Size viewSize = indices.size() * sizeof(uint16_t); + _indicesView = gpu::BufferView(indexBuffer, offset, viewSize, gpu::Element::INDEX_UINT16); + offset = indexBuffer->getSize(); if (!wireIndices.empty()) { - _wireIndexOffset = indexBuffer->getSize() / SHAPE_INDEX_SIZE; - _wireIndexCount = wireIndices.size(); - indexBuffer->append(wireIndices); + for (uint32_t i = 0; i < wireIndices.size(); ++i) { + indexBuffer->append((uint16_t)wireIndices[i]); + } } + viewSize = wireIndices.size() * sizeof(uint16_t); + _wireIndicesView = gpu::BufferView(indexBuffer, offset, viewSize, gpu::Element::INDEX_UINT16); } void GeometryCache::ShapeData::setupBatch(gpu::Batch& batch) const { batch.setInputBuffer(gpu::Stream::POSITION, _positionView); batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); - batch.setIndexBuffer(SHAPE_INDEX_TYPE, _indices, 0); + batch.setIndexBuffer(_indicesView); } void GeometryCache::ShapeData::draw(gpu::Batch& batch) const { - if (_indexCount) { + gpu::Buffer::Size numIndices = _indicesView.getNumElements(); + if (numIndices > 0) { setupBatch(batch); - batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)_indexCount, (gpu::uint32)_indexOffset); + batch.drawIndexed(gpu::TRIANGLES, numIndices, 0); } } void GeometryCache::ShapeData::drawWire(gpu::Batch& batch) const { - if (_wireIndexCount) { - setupBatch(batch); - batch.drawIndexed(gpu::LINES, (gpu::uint32)_wireIndexCount, (gpu::uint32)_wireIndexOffset); + gpu::Buffer::Size numIndices = _wireIndicesView.getNumElements(); + if (numIndices > 0) { + batch.setInputBuffer(gpu::Stream::POSITION, _positionView); + batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); + batch.setIndexBuffer(_wireIndicesView); + batch.drawIndexed(gpu::LINES, numIndices, 0); } } void GeometryCache::ShapeData::drawInstances(gpu::Batch& batch, size_t count) const { - if (_indexCount) { + gpu::Buffer::Size numIndices = _indicesView.getNumElements(); + if (numIndices > 0) { setupBatch(batch); - batch.drawIndexedInstanced((gpu::uint32)count, gpu::TRIANGLES, (gpu::uint32)_indexCount, (gpu::uint32)_indexOffset); + batch.drawIndexedInstanced((gpu::uint32)count, gpu::TRIANGLES, numIndices, 0); } } void GeometryCache::ShapeData::drawWireInstances(gpu::Batch& batch, size_t count) const { - if (_wireIndexCount) { - setupBatch(batch); - batch.drawIndexedInstanced((gpu::uint32)count, gpu::LINES, (gpu::uint32)_wireIndexCount, (gpu::uint32)_wireIndexOffset); + gpu::Buffer::Size numIndices = _wireIndicesView.getNumElements(); + if (numIndices > 0) { + batch.setInputBuffer(gpu::Stream::POSITION, _positionView); + batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); + batch.setIndexBuffer(_wireIndicesView); + batch.drawIndexedInstanced((gpu::uint32)count, gpu::LINES, numIndices, 0); } } static const size_t ICOSAHEDRON_TO_SPHERE_TESSELATION_COUNT = 3; size_t GeometryCache::getShapeTriangleCount(Shape shape) { - return _shapes[shape]._indexCount / VERTICES_PER_TRIANGLE; + return _shapes[shape]._indicesView.getNumElements() / VERTICES_PER_TRIANGLE; } size_t GeometryCache::getSphereTriangleCount() { @@ -168,7 +184,6 @@ 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; - Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE); VertexVector vertices; IndexVector solidIndices, wireIndices; IndexPairs wireSeenIndices; @@ -179,6 +194,7 @@ void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& face = shape.faces[f]; // Compute the face normal @@ -219,7 +235,6 @@ 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; - Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE); VertexVector vertices; vertices.reserve(shape.vertices.size() * 2); @@ -236,6 +251,7 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid solidIndices.reserve(faceIndexCount * faceCount); + Index baseVertex = 0; for (size_t f = 0; f < faceCount; f++) { const Face& face = shape.faces[f]; // Create the wire indices for unseen edges @@ -265,7 +281,6 @@ 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; - Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE); VertexVector vertices; IndexVector solidIndices, wireIndices; @@ -286,6 +301,7 @@ void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& ver vertices.push_back(vec3(v.x, -0.5f, v.z)); vertices.push_back(vec3(0.0f, -1.0f, 0.0f)); } + Index baseVertex = 0; for (uint32_t i = 2; i < N; i++) { solidIndices.push_back(baseVertex + 0); solidIndices.push_back(baseVertex + i); @@ -343,7 +359,6 @@ void drawCircle(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexB // Draw a circle with radius 1/4th the size of the bounding box using namespace geometry; - Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE); VertexVector vertices; IndexVector solidIndices, wireIndices; const int NUM_CIRCLE_VERTICES = 64; @@ -354,6 +369,7 @@ void drawCircle(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexB vertices.push_back(vec3(0.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); @@ -403,7 +419,6 @@ void GeometryCache::buildShapes() { // Line { - Index baseVertex = (Index)(_shapeVertices->getSize() / SHAPE_VERTEX_STRIDE); ShapeData& shapeData = _shapes[Line]; shapeData.setupVertices(_shapeVertices, VertexVector { vec3(-0.5f, 0.0f, 0.0f), vec3(-0.5f, 0.0f, 0.0f), @@ -411,8 +426,8 @@ void GeometryCache::buildShapes() { }); IndexVector wireIndices; // Only two indices - wireIndices.push_back(0 + baseVertex); - wireIndices.push_back(1 + baseVertex); + wireIndices.push_back(0); + wireIndices.push_back(1); shapeData.setupIndices(_shapeIndices, IndexVector(), wireIndices); } diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 288ab363f0..5a437cf5e9 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -339,14 +339,10 @@ public: void useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend = false); struct ShapeData { - size_t _indexOffset{ 0 }; - size_t _indexCount{ 0 }; - size_t _wireIndexOffset{ 0 }; - size_t _wireIndexCount{ 0 }; - gpu::BufferView _positionView; gpu::BufferView _normalView; - gpu::BufferPointer _indices; + gpu::BufferView _indicesView; + gpu::BufferView _wireIndicesView; void setupVertices(gpu::BufferPointer& vertexBuffer, const geometry::VertexVector& vertices); void setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices); From 4bf99fe9d2aef8253a627426d3097f66fc8eaeff Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 10 Oct 2017 17:05:54 -0700 Subject: [PATCH 13/21] remove unused variable --- libraries/render-utils/src/GeometryCache.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 93f3002fe8..c8fa73947a 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -69,7 +69,6 @@ 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_NORMALS_OFFSET = sizeof(glm::vec3); static const gpu::Type SHAPE_INDEX_TYPE = gpu::UINT32; -static const uint SHAPE_INDEX_SIZE = sizeof(gpu::uint32); template std::vector polygon() { From 886422cbef2a2573b5349791a8c28baa11c3b710 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 10 Oct 2017 17:07:17 -0700 Subject: [PATCH 14/21] remove unused variable --- libraries/render-utils/src/GeometryCache.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index c8fa73947a..c7bc09a5e3 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -68,7 +68,6 @@ 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_NORMALS_OFFSET = sizeof(glm::vec3); -static const gpu::Type SHAPE_INDEX_TYPE = gpu::UINT32; template std::vector polygon() { From 69b6a8c1639638acf333c9878d177dce33dade0f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 10 Oct 2017 15:22:32 -0700 Subject: [PATCH 15/21] Fix .fst texdir not being followed Although the texdir was being acknowledged and used as the _textureBaseURL inside of the Geometry* classes, it was being overwritten in code meant to handle redirects. Basically, when a geometry resource request is redirected (via ATP, HTTP, etc.), we needed to update the _textureBaseURL to take the new location into account. Previously we were overwriting the _textureBaseURL all the time, even when not being redirected, but this updates it to only be overwritten when the request is redirected. There is at least 1 known case that this does not handle: a .fst with its `texdir` set, that points at an fbx that gets redirected. --- .../src/model-networking/ModelCache.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 2756334a1a..b62ad7b366 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -71,14 +71,14 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) { } else { QUrl url = _url.resolved(filename); - QString texdir = mapping.value("texdir").toString(); + QString texdir = mapping.value(TEXDIR_FIELD).toString(); if (!texdir.isNull()) { if (!texdir.endsWith('/')) { texdir += '/'; } _textureBaseUrl = resolveTextureBaseUrl(url, _url.resolved(texdir)); } else { - _textureBaseUrl = _effectiveBaseURL; + _textureBaseUrl = url.resolved(QUrl(".")); } auto animGraphVariant = mapping.value("animGraphUrl"); @@ -241,8 +241,10 @@ private: }; void GeometryDefinitionResource::downloadFinished(const QByteArray& data) { - _url = _effectiveBaseURL; - _textureBaseUrl = _effectiveBaseURL; + if (_url != _effectiveBaseURL) { + _url = _effectiveBaseURL; + _textureBaseUrl = _effectiveBaseURL; + } QThreadPool::globalInstance()->start(new GeometryReader(_self, _effectiveBaseURL, _mapping, data, _combineParts)); } From d9ba75ca72c0413e98bf6870f45439d24a28facf Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 11 Oct 2017 06:07:07 -0700 Subject: [PATCH 16/21] fix warning about implicit cast from 64 to 32 bits --- libraries/render-utils/src/GeometryCache.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index c7bc09a5e3..cf8e268681 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -120,7 +120,7 @@ void GeometryCache::ShapeData::setupBatch(gpu::Batch& batch) const { } void GeometryCache::ShapeData::draw(gpu::Batch& batch) const { - gpu::Buffer::Size numIndices = _indicesView.getNumElements(); + uint32_t numIndices = (uint32_t)_indicesView.getNumElements(); if (numIndices > 0) { setupBatch(batch); batch.drawIndexed(gpu::TRIANGLES, numIndices, 0); @@ -128,7 +128,7 @@ void GeometryCache::ShapeData::draw(gpu::Batch& batch) const { } void GeometryCache::ShapeData::drawWire(gpu::Batch& batch) const { - gpu::Buffer::Size numIndices = _wireIndicesView.getNumElements(); + uint32_t numIndices = (uint32_t)_wireIndicesView.getNumElements(); if (numIndices > 0) { batch.setInputBuffer(gpu::Stream::POSITION, _positionView); batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); @@ -138,7 +138,7 @@ void GeometryCache::ShapeData::drawWire(gpu::Batch& batch) const { } void GeometryCache::ShapeData::drawInstances(gpu::Batch& batch, size_t count) const { - gpu::Buffer::Size numIndices = _indicesView.getNumElements(); + uint32_t numIndices = (uint32_t)_indicesView.getNumElements(); if (numIndices > 0) { setupBatch(batch); batch.drawIndexedInstanced((gpu::uint32)count, gpu::TRIANGLES, numIndices, 0); @@ -146,7 +146,7 @@ void GeometryCache::ShapeData::drawInstances(gpu::Batch& batch, size_t count) co } void GeometryCache::ShapeData::drawWireInstances(gpu::Batch& batch, size_t count) const { - gpu::Buffer::Size numIndices = _wireIndicesView.getNumElements(); + uint32_t numIndices = (uint32_t)_wireIndicesView.getNumElements(); if (numIndices > 0) { batch.setInputBuffer(gpu::Stream::POSITION, _positionView); batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); From c2733a4186f622aa68fdf94240f2e9fb195e6d33 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 11 Oct 2017 09:47:16 -0700 Subject: [PATCH 17/21] Fix notification bug --- scripts/system/notifications.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/system/notifications.js b/scripts/system/notifications.js index dc0fb1daf9..ef2c674a41 100644 --- a/scripts/system/notifications.js +++ b/scripts/system/notifications.js @@ -576,6 +576,10 @@ createNotification("Processing GIF snapshot...", NotificationType.SNAPSHOT); } + function processingGif() { + createNotification("Your wallet isn't set up. Open the WALLET app.", NotificationType.WALLET); + } + function connectionAdded(connectionName) { createNotification(connectionName, NotificationType.CONNECTION); } From 3f0ec73be687c7292a51c2b99ba2592dc68a92c2 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 11 Oct 2017 10:55:14 -0700 Subject: [PATCH 18/21] Fix date displays --- .../inspectionCertificate/InspectionCertificate.qml | 13 +++++++++---- .../qml/hifi/commerce/wallet/WalletHome.qml | 13 +++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml index 90c8c318a5..fe1f049e5e 100644 --- a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml +++ b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml @@ -394,10 +394,14 @@ Rectangle { signal sendToScript(var message); function getFormattedDate(timestamp) { + function addLeadingZero(n) { + return n < 10 ? '0' + n : '' + n; + } + var a = new Date(timestamp); var year = a.getFullYear(); - var month = a.getMonth(); - var day = a.getDate(); + var month = addLeadingZero(a.getMonth()); + var day = addLeadingZero(a.getDate()); var hour = a.getHours(); var drawnHour = hour; if (hour === 0) { @@ -405,14 +409,15 @@ Rectangle { } else if (hour > 12) { drawnHour -= 12; } + drawnHour = addLeadingZero(drawnHour); var amOrPm = "AM"; if (hour >= 12) { amOrPm = "PM"; } - var min = a.getMinutes(); - var sec = a.getSeconds(); + var min = addLeadingZero(a.getMinutes()); + var sec = addLeadingZero(a.getSeconds()); return year + '-' + month + '-' + day + '
' + drawnHour + ':' + min + amOrPm; } // diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml index b94616bd7a..50891deb60 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml @@ -299,10 +299,14 @@ Item { // function getFormattedDate(timestamp) { + function addLeadingZero(n) { + return n < 10 ? '0' + n : '' + n; + } + var a = new Date(timestamp); var year = a.getFullYear(); - var month = a.getMonth(); - var day = a.getDate(); + var month = addLeadingZero(a.getMonth()); + var day = addLeadingZero(a.getDate()); var hour = a.getHours(); var drawnHour = hour; if (hour === 0) { @@ -310,14 +314,15 @@ Item { } else if (hour > 12) { drawnHour -= 12; } + drawnHour = addLeadingZero(drawnHour); var amOrPm = "AM"; if (hour >= 12) { amOrPm = "PM"; } - var min = a.getMinutes(); - var sec = a.getSeconds(); + var min = addLeadingZero(a.getMinutes()); + var sec = addLeadingZero(a.getSeconds()); return year + '-' + month + '-' + day + '
' + drawnHour + ':' + min + amOrPm; } From 69f869b339100aae670fadfff530c26b8554d44c Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 11 Oct 2017 09:15:53 -0700 Subject: [PATCH 19/21] Remove unecessary blocking call --- interface/src/ui/overlays/Overlays.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 0280cf2038..b59bcdb9b2 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -741,13 +741,6 @@ void Overlays::sendHoverLeaveOverlay(const OverlayID& id, const PointerEvent& ev } OverlayID Overlays::getKeyboardFocusOverlay() { - if (QThread::currentThread() != thread()) { - OverlayID result; - PROFILE_RANGE(script, __FUNCTION__); - BLOCKING_INVOKE_METHOD(this, "getKeyboardFocusOverlay", Q_RETURN_ARG(OverlayID, result)); - return result; - } - return qApp->getKeyboardFocusOverlay(); } From 403b18977b4b301f11e87ffb850b06c630878253 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 11 Oct 2017 14:37:23 -0700 Subject: [PATCH 20/21] remove unused HFMetaEvents --- interface/src/Application.cpp | 61 ------------------- .../ControllerScriptingInterface.cpp | 13 ---- .../scripting/ControllerScriptingInterface.h | 9 --- libraries/script-engine/src/EventTypes.cpp | 2 - libraries/script-engine/src/HFActionEvent.cpp | 40 ------------ libraries/script-engine/src/HFActionEvent.h | 38 ------------ libraries/script-engine/src/HFBackEvent.cpp | 28 --------- libraries/script-engine/src/HFBackEvent.h | 29 --------- libraries/script-engine/src/HFMetaEvent.cpp | 20 ------ libraries/script-engine/src/HFMetaEvent.h | 28 --------- 10 files changed, 268 deletions(-) delete mode 100644 libraries/script-engine/src/HFActionEvent.cpp delete mode 100644 libraries/script-engine/src/HFActionEvent.h delete mode 100644 libraries/script-engine/src/HFBackEvent.cpp delete mode 100644 libraries/script-engine/src/HFBackEvent.h delete mode 100644 libraries/script-engine/src/HFMetaEvent.cpp delete mode 100644 libraries/script-engine/src/HFMetaEvent.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 30390c007b..60ae1843d6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -79,8 +79,6 @@ #include #include #include -#include -#include #include #include #include @@ -2858,10 +2856,6 @@ bool Application::event(QEvent* event) { break; } - if (HFActionEvent::types().contains(event->type())) { - _controllerScriptingInterface->handleMetaEvent(static_cast(event)); - } - return QApplication::event(event); } @@ -3166,25 +3160,8 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_Equal: getMyAvatar()->resetSize(); break; - case Qt::Key_Space: { - if (!event->isAutoRepeat()) { - // FIXME -- I don't think we've tested the HFActionEvent in a while... this looks possibly dubious - // this starts an HFActionEvent - HFActionEvent startActionEvent(HFActionEvent::startType(), - computePickRay(getMouse().x, getMouse().y)); - sendEvent(this, &startActionEvent); - } - - break; - } case Qt::Key_Escape: { getActiveDisplayPlugin()->abandonCalibration(); - if (!event->isAutoRepeat()) { - // this starts the HFCancelEvent - HFBackEvent startBackEvent(HFBackEvent::startType()); - sendEvent(this, &startBackEvent); - } - break; } @@ -3210,30 +3187,6 @@ void Application::keyReleaseEvent(QKeyEvent* event) { if (_keyboardMouseDevice->isActive()) { _keyboardMouseDevice->keyReleaseEvent(event); } - - switch (event->key()) { - case Qt::Key_Space: { - if (!event->isAutoRepeat()) { - // FIXME -- I don't think we've tested the HFActionEvent in a while... this looks possibly dubious - // this ends the HFActionEvent - HFActionEvent endActionEvent(HFActionEvent::endType(), - computePickRay(getMouse().x, getMouse().y)); - sendEvent(this, &endActionEvent); - } - break; - } - case Qt::Key_Escape: { - if (!event->isAutoRepeat()) { - // this ends the HFCancelEvent - HFBackEvent endBackEvent(HFBackEvent::endType()); - sendEvent(this, &endBackEvent); - } - break; - } - default: - event->ignore(); - break; - } } void Application::focusOutEvent(QFocusEvent* event) { @@ -3370,13 +3323,6 @@ void Application::mousePressEvent(QMouseEvent* event) { if (_keyboardMouseDevice->isActive()) { _keyboardMouseDevice->mousePressEvent(event); } - - if (event->button() == Qt::LeftButton) { - // nobody handled this - make it an action event on the _window object - HFActionEvent actionEvent(HFActionEvent::startType(), - computePickRay(mappedEvent.x(), mappedEvent.y())); - sendEvent(this, &actionEvent); - } } } @@ -3431,13 +3377,6 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { if (_keyboardMouseDevice->isActive()) { _keyboardMouseDevice->mouseReleaseEvent(event); } - - if (event->button() == Qt::LeftButton) { - // fire an action end event - HFActionEvent actionEvent(HFActionEvent::endType(), - computePickRay(mappedEvent.x(), mappedEvent.y())); - sendEvent(this, &actionEvent); - } } } diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 5c55e2094b..4848531de7 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -13,23 +13,10 @@ #include #include -#include #include #include "Application.h" -void ControllerScriptingInterface::handleMetaEvent(HFMetaEvent* event) { - if (event->type() == HFActionEvent::startType()) { - emit actionStartEvent(static_cast(*event)); - } else if (event->type() == HFActionEvent::endType()) { - emit actionEndEvent(static_cast(*event)); - } else if (event->type() == HFBackEvent::startType()) { - emit backStartEvent(); - } else if (event->type() == HFBackEvent::endType()) { - emit backEndEvent(); - } -} - bool ControllerScriptingInterface::isKeyCaptured(QKeyEvent* event) const { return isKeyCaptured(KeyEvent(*event)); } diff --git a/interface/src/scripting/ControllerScriptingInterface.h b/interface/src/scripting/ControllerScriptingInterface.h index 8c825a17de..7a2c964622 100644 --- a/interface/src/scripting/ControllerScriptingInterface.h +++ b/interface/src/scripting/ControllerScriptingInterface.h @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -36,8 +35,6 @@ public: void emitKeyPressEvent(QKeyEvent* event); void emitKeyReleaseEvent(QKeyEvent* event); - void handleMetaEvent(HFMetaEvent* event); - void emitMouseMoveEvent(QMouseEvent* event); void emitMousePressEvent(QMouseEvent* event); void emitMouseDoublePressEvent(QMouseEvent* event); @@ -72,12 +69,6 @@ signals: void keyPressEvent(const KeyEvent& event); void keyReleaseEvent(const KeyEvent& event); - void actionStartEvent(const HFActionEvent& event); - void actionEndEvent(const HFActionEvent& event); - - void backStartEvent(); - void backEndEvent(); - void mouseMoveEvent(const MouseEvent& event); void mousePressEvent(const MouseEvent& event); void mouseDoublePressEvent(const MouseEvent& event); diff --git a/libraries/script-engine/src/EventTypes.cpp b/libraries/script-engine/src/EventTypes.cpp index 1bdf0f5034..abdd934e5a 100644 --- a/libraries/script-engine/src/EventTypes.cpp +++ b/libraries/script-engine/src/EventTypes.cpp @@ -9,7 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "HFActionEvent.h" #include "KeyEvent.h" #include "MouseEvent.h" #include "SpatialEvent.h" @@ -20,7 +19,6 @@ #include "EventTypes.h" void registerEventTypes(QScriptEngine* engine) { - qScriptRegisterMetaType(engine, HFActionEvent::toScriptValue, HFActionEvent::fromScriptValue); qScriptRegisterMetaType(engine, KeyEvent::toScriptValue, KeyEvent::fromScriptValue); qScriptRegisterMetaType(engine, MouseEvent::toScriptValue, MouseEvent::fromScriptValue); qScriptRegisterMetaType(engine, PointerEvent::toScriptValue, PointerEvent::fromScriptValue); diff --git a/libraries/script-engine/src/HFActionEvent.cpp b/libraries/script-engine/src/HFActionEvent.cpp deleted file mode 100644 index 3ed3bcb73c..0000000000 --- a/libraries/script-engine/src/HFActionEvent.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// HFActionEvent.cpp -// script-engine/src -// -// Created by Stephen Birarda on 2014-10-27. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "HFActionEvent.h" - -HFActionEvent::HFActionEvent(QEvent::Type type, const PickRay& actionRay) : - HFMetaEvent(type), - actionRay(actionRay) -{ - -} - -QEvent::Type HFActionEvent::startType() { - static QEvent::Type startType = HFMetaEvent::newEventType(); - return startType; -} - -QEvent::Type HFActionEvent::endType() { - static QEvent::Type endType = HFMetaEvent::newEventType(); - return endType; -} - -QScriptValue HFActionEvent::toScriptValue(QScriptEngine* engine, const HFActionEvent& event) { - QScriptValue obj = engine->newObject(); - obj.setProperty("actionRay", pickRayToScriptValue(engine, event.actionRay)); - return obj; -} - -void HFActionEvent::fromScriptValue(const QScriptValue& object, HFActionEvent& event) { - // not yet implemented -} - diff --git a/libraries/script-engine/src/HFActionEvent.h b/libraries/script-engine/src/HFActionEvent.h deleted file mode 100644 index c16b165ae3..0000000000 --- a/libraries/script-engine/src/HFActionEvent.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// HFActionEvent.h -// script-engine/src -// -// Created by Stephen Birarda on 2014-10-27. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_HFActionEvent_h -#define hifi_HFActionEvent_h - - -#include - -#include - -#include "HFMetaEvent.h" - -class HFActionEvent : public HFMetaEvent { -public: - HFActionEvent() {}; - HFActionEvent(QEvent::Type type, const PickRay& actionRay); - - static QEvent::Type startType(); - static QEvent::Type endType(); - - static QScriptValue toScriptValue(QScriptEngine* engine, const HFActionEvent& event); - static void fromScriptValue(const QScriptValue& object, HFActionEvent& event); - - PickRay actionRay; -}; - -Q_DECLARE_METATYPE(HFActionEvent) - -#endif // hifi_HFActionEvent_h \ No newline at end of file diff --git a/libraries/script-engine/src/HFBackEvent.cpp b/libraries/script-engine/src/HFBackEvent.cpp deleted file mode 100644 index c67b2e3431..0000000000 --- a/libraries/script-engine/src/HFBackEvent.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// HFBackEvent.cpp -// script-engine/src -// -// Created by Stephen Birarda on 2014-10-27. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "HFBackEvent.h" - -HFBackEvent::HFBackEvent(QEvent::Type type) : - HFMetaEvent(type) -{ - -} - -QEvent::Type HFBackEvent::startType() { - static QEvent::Type startType = HFMetaEvent::newEventType(); - return startType; -} - -QEvent::Type HFBackEvent::endType() { - static QEvent::Type endType = HFMetaEvent::newEventType(); - return endType; -} diff --git a/libraries/script-engine/src/HFBackEvent.h b/libraries/script-engine/src/HFBackEvent.h deleted file mode 100644 index bb7b348ea7..0000000000 --- a/libraries/script-engine/src/HFBackEvent.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// HFBackEvent.h -// script-engine/src -// -// Created by Stephen Birarda on 2014-10-27. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_HFBackEvent_h -#define hifi_HFBackEvent_h - -#include -#include - -#include "HFMetaEvent.h" - -class HFBackEvent : public HFMetaEvent { -public: - HFBackEvent() {}; - HFBackEvent(QEvent::Type type); - - static QEvent::Type startType(); - static QEvent::Type endType(); -}; - -#endif // hifi_HFBackEvent_h \ No newline at end of file diff --git a/libraries/script-engine/src/HFMetaEvent.cpp b/libraries/script-engine/src/HFMetaEvent.cpp deleted file mode 100644 index f06c349996..0000000000 --- a/libraries/script-engine/src/HFMetaEvent.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// -// HFMetaEvent.cpp -// script-engine/src -// -// Created by Stephen Birarda on 2014-10-27. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "HFMetaEvent.h" - -QSet HFMetaEvent::_types = QSet(); - -QEvent::Type HFMetaEvent::newEventType() { - QEvent::Type newType = static_cast(QEvent::registerEventType()); - _types.insert(newType); - return newType; -} \ No newline at end of file diff --git a/libraries/script-engine/src/HFMetaEvent.h b/libraries/script-engine/src/HFMetaEvent.h deleted file mode 100644 index 2fd71b8a3b..0000000000 --- a/libraries/script-engine/src/HFMetaEvent.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// HFMetaEvent.h -// script-engine/src -// -// Created by Stephen Birarda on 2014-10-27. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_HFMetaEvent_h -#define hifi_HFMetaEvent_h - -#include - -class HFMetaEvent : public QEvent { -public: - HFMetaEvent() : QEvent(HFMetaEvent::newEventType()) {}; - HFMetaEvent(QEvent::Type type) : QEvent(type) {}; - static const QSet& types() { return HFMetaEvent::_types; } -protected: - static QEvent::Type newEventType(); - - static QSet _types; -}; - -#endif // hifi_HFMetaEvent_h \ No newline at end of file From 592a4de1e5c4b276ddf765bfa328f1f24e14760e Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 11 Oct 2017 15:56:22 -0700 Subject: [PATCH 21/21] Fix the HDR generation of cube maps from equirect images (1x2) --- libraries/image/src/image/Image.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp index 58b920da4d..59ec4776a6 100644 --- a/libraries/image/src/image/Image.cpp +++ b/libraries/image/src/image/Image.cpp @@ -1202,10 +1202,6 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage& formatGPU = HDR_FORMAT; } - if (image.format() != QIMAGE_HDR_FORMAT) { - image = convertToHDRFormat(image, HDR_FORMAT); - } - // Find the layout of the cubemap in the 2D image // Use the original image size since processSourceImage may have altered the size / aspect ratio int foundLayout = CubeLayout::findLayout(srcImage.width(), srcImage.height()); @@ -1233,6 +1229,13 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage& faces.push_back(faceImage); } } + + if (image.format() != QIMAGE_HDR_FORMAT) { + for (auto& face : faces) { + face = convertToHDRFormat(face, HDR_FORMAT); + } + } + } else { qCDebug(imagelogging) << "Failed to find a known cube map layout from this image:" << QString(srcImageName.c_str()); return nullptr;