From 11a240e2db79671bbd1a41b4a3909034afc1d83f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 18 Jun 2018 12:47:13 -0700 Subject: [PATCH 001/109] Exploring the performance profile of the render engine --- interface/src/SecondaryCamera.cpp | 4 +- libraries/task/src/task/Config.h | 6 +- scripts/developer/utilities/lib/jet/jet.js | 114 ++++++++++++++ .../utilities/lib/jet/qml/TaskListView.qml | 128 ++++++++-------- .../lib/jet/qml/TaskTimeFrameView.qml | 141 ++++++++++++++++++ .../developer/utilities/lib/jet/qml/qmldir | 3 +- .../utilities/render/engineInspector.js | 10 +- .../utilities/render/engineInspector.qml | 3 +- 8 files changed, 338 insertions(+), 71 deletions(-) create mode 100644 scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml diff --git a/interface/src/SecondaryCamera.cpp b/interface/src/SecondaryCamera.cpp index b9a767f700..766c64043d 100644 --- a/interface/src/SecondaryCamera.cpp +++ b/interface/src/SecondaryCamera.cpp @@ -196,11 +196,13 @@ public: void run(const render::RenderContextPointer& renderContext, const RenderArgsPointer& cachedArgs) { auto args = renderContext->args; + if (cachedArgs) { args->_blitFramebuffer = cachedArgs->_blitFramebuffer; args->_viewport = cachedArgs->_viewport; - args->popViewFrustum(); args->_displayMode = cachedArgs->_displayMode; args->_renderMode = cachedArgs->_renderMode; + } + args->popViewFrustum(); gpu::doInBatch("EndSecondaryCameraFrame::run", args->_context, [&](gpu::Batch& batch) { batch.restoreContextStereo(); diff --git a/libraries/task/src/task/Config.h b/libraries/task/src/task/Config.h index 00fa01808b..c94ed5f8ce 100644 --- a/libraries/task/src/task/Config.h +++ b/libraries/task/src/task/Config.h @@ -98,10 +98,10 @@ public: JobConfig() = default; JobConfig(bool enabled) : alwaysEnabled{ false }, enabled{ enabled } {} - bool isEnabled() { return alwaysEnabled || enabled; } - void setEnabled(bool enable) { enabled = alwaysEnabled || enable; emit dirtyEnabled(); } + bool isEnabled() { return /*alwaysEnabled ||*/ enabled; } + void setEnabled(bool enable) { enabled = /*alwaysEnabled ||*/ enable; emit dirtyEnabled(); } - bool alwaysEnabled{ true }; + bool alwaysEnabled{ false }; bool enabled{ true }; virtual void setPresetList(const QJsonObject& object); diff --git a/scripts/developer/utilities/lib/jet/jet.js b/scripts/developer/utilities/lib/jet/jet.js index 16840e59bd..041be0f8a6 100644 --- a/scripts/developer/utilities/lib/jet/jet.js +++ b/scripts/developer/utilities/lib/jet/jet.js @@ -73,6 +73,120 @@ function job_print_functor(printout, showProps, maxDepth) { } } +// Use this function to create a functor that will build a tree datastructure of the Job visited + +function job_tree_model_array_functor(jobTreeArray, newNodeFunctor) { + var jobsRoot; + var numJobs = 0; + var jobTreePath = [] + if (newNodeFunctor === undefined) newNodeFunctor = function (node) {} + + return function (job, depth, index) { + var id = numJobs + var newItem = {"name": job.objectName, "level": depth, "index": index, "id": id, "subNode": [], "path": ""} + if (depth == 0) { + newNodeFunctor(newItem) + jobTreeArray.push(newItem) + numJobs++ + jobsRoot = jobTreeArray[0].subNode; + } else { + if (jobTreePath.length < depth) { + var node = jobsRoot; + var path; + for (var n = 0; n < jobTreePath.length; n++) { + newItem.path += (n > 0 ? "." : "") + node[jobTreePath[n]].name + node = node[jobTreePath[n]].subNode + } + + newNodeFunctor(newItem) + node.push((newItem)) + numJobs++ + jobTreePath.push(0); + } else if (jobTreePath.length >= depth) { + var node = jobsRoot; + for (var n = 0; n < (depth - 1); n++) { + newItem.path += (n > 0 ? "." : "") + node[jobTreePath[n]].name + node = node[jobTreePath[n]].subNode + } + + newNodeFunctor(newItem) + node.push((newItem)) + numJobs++ + jobTreePath[depth-1] = index; + while (jobTreePath.length > depth) { + jobTreePath.pop(); + } + } + } + return true; + } +} + +function job_tree_model_functor(jobTreeModel, maxLevel, newNodeFunctor) { + var jobsRoot; + var numJobs = 0; + var jobTreePath = [] + if (newNodeFunctor === undefined) newNodeFunctor = function (node) {} + + return function (job, depth, index) { + var id = numJobs + var newItem = {"name": job.objectName, "level": depth, "index": index, "id": id, "subNode": [], "path": "", "init": (depth < maxLevel), "ud": {}} + if (depth == 0) { + newNodeFunctor(newItem) + jobTreeModel.append(newItem) + numJobs++ + jobsRoot = jobTreeModel.get(0).subNode; + } else { + if (jobTreePath.length < depth) { + var node = jobsRoot; + var path; + for (var n = 0; n < jobTreePath.length; n++) { + newItem.path += (n > 0 ? "." : "") + node.get(jobTreePath[n]).name + node = node.get(jobTreePath[n]).subNode + } + + newNodeFunctor(newItem) + node.append((newItem)) + numJobs++ + jobTreePath.push(0); + } else if (jobTreePath.length >= depth) { + var node = jobsRoot; + for (var n = 0; n < (depth - 1); n++) { + newItem.path += (n > 0 ? "." : "") + node.get(jobTreePath[n]).name + node = node.get(jobTreePath[n]).subNode + } + + newNodeFunctor(newItem) + node.append((newItem)) + numJobs++ + jobTreePath[depth-1] = index; + while (jobTreePath.length > depth) { + jobTreePath.pop(); + } + } + } + return true; + } +} + + +// Traverse the jobTreenode data structure created above +function job_traverseTreeNode(root, functor, depth) { + // if (root.subNode.length) { + depth++; + for (var i = 0; i 0 ? "." : "") + node.get(jobTreePath[n]).name - node = node.get(jobTreePath[n]).subNode - } - node.append(newItem) - jobTreePath.push(0); - } else if (jobTreePath.length >= depth) { - var node = jobsRoot; - for (var n = 0; n < (depth - 1); n++) { - newItem.path += (n > 0 ? "." : "") + node.get(jobTreePath[n]).name - node = node.get(jobTreePath[n]).subNode - } - node.append(newItem) - jobTreePath[depth-1] = index; - while (jobTreePath.length > depth) { - jobTreePath.pop(); - } - } - } - return true; - } - + //var functor = Jet.job_tree_model_functor(jobsModel) + /* var functor = Jet.job_tree_model_functor(jobsModel, 1, function(node) { + node["cpuT"] = 0.0 + }) Jet.task_traverseTree(rootConfig, functor); - } + */ + + var tfunctor = Jet.job_tree_model_array_functor(jobsModel.engineJobItemModel, function(node) { + node["init"] = (node.level < 3) + node["fullpath"] = (node.path + "." + node.name) + node["cpuT"] = 0.0 + }) + + Jet.task_traverseTree(rootConfig, tfunctor); + + // var currentParentStach = [] + // currentParentStach.push(jobsModel); + + + Jet.job_traverseTreeNodeRoot(jobsModel.engineJobItemModel[0], function(node, depth, index) { + print(node.name + depth + " - " + index) + return true + }) + } + ListModel { id: jobsModel + property var engineJobItemModel : [] } Component { @@ -77,30 +64,49 @@ Rectangle { id: objRecursiveColumn clip: true visible: model.init - - MouseArea { - width: objRow.implicitWidth - height: objRow.implicitHeight - onDoubleClicked: { - for(var i = 1; i < parent.children.length - 1; ++i) { - parent.children[i].visible = !parent.children[i].visible - } - } - Row { - id: objRow - Item { - height: 1 - width: model.level * 15 - } - HifiControls.CheckBox { - property var config: root.rootConfig.getConfig(model.path + "." + model.name); - text: (objRecursiveColumn.children.length > 2 ? - objRecursiveColumn.children[1].visible ? - qsTr("- ") : qsTr("+ ") : qsTr(" ")) + model.name + " ms=" + config.cpuRunTime.toFixed(2) - checked: config.enabled - } + // visible: (node.level < 2) + + function switchFold() { + for(var i = 1; i < children.length - 1; ++i) { + children[i].visible = !children[i].visible } } + + Row { + id: objRow + Item { + height: 1 + width: model.level * 15 + } + + HifiControls.CheckBox { + id: objCheck + property var config: root.rootConfig.getConfig(model.path + "." + model.name); + text: " " + checked: config.enabled + onCheckedChanged: { config.enabled = checked } + } + + MouseArea { + width: objLabel.implicitWidth + height: objLabel.implicitHeight + onDoubleClicked: { + parent.parent.switchFold() + } + + HifiControls.Label { + id: objLabel + colorScheme: hifi.colorSchemes.dark + // property var config: root.rootConfig.getConfig(model.path + "." + model.name); + text: (objRecursiveColumn.children.length > 2 ? + objRecursiveColumn.children[1].visible ? + qsTr("- ") : qsTr("+ ") : qsTr(" ")) + model.name + + " ms=" + root.rootConfig.getConfig(model.path + "." + model.name).cpuRunTime.toFixed(3) + + " id=" + model.id + } + } + } + Repeater { model: subNode delegate: objRecursiveDelegate diff --git a/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml b/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml new file mode 100644 index 0000000000..ed1649a47a --- /dev/null +++ b/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml @@ -0,0 +1,141 @@ +// +// jet/TaskTimeFrameView.qml +// +// Created by Sam Gateau, 2018/06/15 +// Copyright 2018 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 +// + +import QtQuick 2.7 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "qrc:///qml/styles-uit" +import "qrc:///qml/controls-uit" as HifiControls + +import "../jet.js" as Jet + +Rectangle { + HifiConstants { id: hifi;} + color: hifi.colors.baseGray; + id: root; + + property var rootConfig : Workload + + property var jobsTree + property var jobsArray + + Component.onCompleted: { + if (!jobsTree) { jobsTree = new Array(); } + if (!jobsArray) { jobsArray = new Array(); } + + var tfunctor = Jet.job_tree_model_array_functor(jobsTree, function(node) { + var job = { "fullpath": (node.path + "." + node.name), "cpuT": 0.0, "depth": node.level } + jobsArray.push(job) + }) + Jet.task_traverseTree(rootConfig, tfunctor); + + for (var j = 0; j 0) { + + var rangeStack =new Array() + var frameDuration = Math.max(jobsArray[0].cpuT, 1) + rangeStack.push( { "b": 0.0, "e": frameDuration } ) + var timeScale = width * 0.9 / frameDuration; + + drawJob(ctx, 0, 0, jobsArray[0].cpuT, 0, timeScale) + + for (var i = 1; i lastDepth) { + timeOffset = rangeStack[lastDepth].b + while(rangeStack.length <= depth) { + rangeStack.push( { "b": timeOffset, "e": duration } ) + } + + } else { + if (depth < lastDepth) { + while(rangeStack.length != (depth + 1)) { + rangeStack.pop() + } + } + + timeOffset = rangeStack[depth].e + rangeStack[depth].b = timeOffset + rangeStack[depth].e = timeOffset + duration + } + + print("j " + i + " depth " + depth + " lastDepth " + lastDepth + " off " + timeOffset + " dur " + duration) + drawJob(ctx, depth, i, duration, timeOffset, timeScale) + } + } + } + } + } +} \ No newline at end of file diff --git a/scripts/developer/utilities/lib/jet/qml/qmldir b/scripts/developer/utilities/lib/jet/qml/qmldir index 3134545625..930641b10b 100644 --- a/scripts/developer/utilities/lib/jet/qml/qmldir +++ b/scripts/developer/utilities/lib/jet/qml/qmldir @@ -1,2 +1,3 @@ TaskList 1.0 TaskList.qml -TaskViewList 1.0 TaskViewList.qml \ No newline at end of file +TaskViewList 1.0 TaskViewList.qml +TaskTimeFrameView 1.0 TaskTimeFrameView.qml \ No newline at end of file diff --git a/scripts/developer/utilities/render/engineInspector.js b/scripts/developer/utilities/render/engineInspector.js index dcf13157b5..348ae8f54f 100644 --- a/scripts/developer/utilities/render/engineInspector.js +++ b/scripts/developer/utilities/render/engineInspector.js @@ -4,10 +4,12 @@ var window = new OverlayWindow({ title: 'Render Engine', source: qml, - width: 300, - height: 400 + width: 500, + height: 100 }); window.setPosition(200, 50); - //window.closed.connect(function() { Script.stop(); }); + window.closed.connect(function() { Script.stop(); }); } - openEngineTaskView(); \ No newline at end of file + openEngineTaskView(); + + \ No newline at end of file diff --git a/scripts/developer/utilities/render/engineInspector.qml b/scripts/developer/utilities/render/engineInspector.qml index 1b9941e64e..d2a6e01524 100644 --- a/scripts/developer/utilities/render/engineInspector.qml +++ b/scripts/developer/utilities/render/engineInspector.qml @@ -23,7 +23,8 @@ Item { property var mainViewTask: Render.getConfig("RenderMainView") - Jet.TaskListView { + //Jet.TaskListView { + Jet.TaskTimeFrameView { rootConfig: Render anchors.fill: render } From 3a910489c8b88b0c5d2a4de0f3cd3354deff3c62 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 20 Jun 2018 16:56:35 -0700 Subject: [PATCH 002/109] Regfining --- libraries/task/src/task/Config.h | 5 +- .../lib/jet/qml/TaskTimeFrameView.qml | 176 +++++++++++++++--- .../utilities/render/engineInspector.js | 60 +++++- .../utilities/render/engineInspector.qml | 7 +- 4 files changed, 217 insertions(+), 31 deletions(-) diff --git a/libraries/task/src/task/Config.h b/libraries/task/src/task/Config.h index c94ed5f8ce..a1e05cd043 100644 --- a/libraries/task/src/task/Config.h +++ b/libraries/task/src/task/Config.h @@ -123,7 +123,7 @@ public: // Running Time measurement // The new stats signal is emitted once per run time of a job when stats (cpu runtime) are updated - void setCPURunTime(const std::chrono::nanoseconds& runtime) { _msCPURunTime = std::chrono::duration(runtime).count(); emit newStats(); } + void setCPURunTime(const std::chrono::nanoseconds& runtime) { _msCPURunTime = std::chrono::duration(runtime).count(); /* emit newStats();*/ } double getCPURunTime() const { return _msCPURunTime; } // Describe the node graph data connections of the associated Job/Task @@ -230,7 +230,8 @@ public: auto tokens = path.split('.', QString::SkipEmptyParts); if (tokens.empty()) { - tokens.push_back(QString()); + return dynamic_cast(const_cast (root)); + // tokens.push_back(QString()); } else { while (tokens.size() > 1) { auto name = tokens.front(); diff --git a/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml b/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml index ed1649a47a..4eca5075d0 100644 --- a/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml +++ b/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml @@ -27,27 +27,32 @@ Rectangle { property var jobsTree property var jobsArray + Component.onCompleted: { if (!jobsTree) { jobsTree = new Array(); } if (!jobsArray) { jobsArray = new Array(); } var tfunctor = Jet.job_tree_model_array_functor(jobsTree, function(node) { - var job = { "fullpath": (node.path + "." + node.name), "cpuT": 0.0, "depth": node.level } + var job = { "fullpath": (node.path + "." + node.name), "cpuT": 0.0, "depth": node.level, "name": node.name } jobsArray.push(job) }) Jet.task_traverseTree(rootConfig, tfunctor); for (var j = 0; j ") + height: 24 + width: 24 + onClicked: { + print("list of highlight styles") + myCanvasTimer.running = !myCanvasTimer.running + } + } + } Canvas { id: mycanvas - anchors.fill:parent + anchors.top:myHeaderRow.bottom + anchors.bottom:parent.bottom + anchors.left:parent.left + anchors.right:parent.right - onPaint: { - print("mycanvasOnPaint " + jobsArray.length) - var lineHeight = 12; - var frameWidth = width; + property var frameDuration: 10 + property var frameViewBegin: 0 + property var frameViewRange: width - + function reset() { + frameViewBegin = 0 + frameViewRange = width + } + + function checkView() { + if (frameViewBegin > width * 0.9) { + frameViewBegin = width * 0.9 + } else if (frameViewBegin + frameViewRange < width * 0.1) { + frameViewBegin = width * 0.1 -frameViewRange + } + } + + function drag(deltaX) { + frameViewBegin -= deltaX + checkView() + } + + function pivotScale(pivotX, deltaX) { + var newRange = frameViewRange + 2 * deltaX + if (newRange <= 1) { + newRange = 2; + } + frameViewBegin = pivotX - frameViewRange * (pivotX - frameViewBegin) / newRange + frameViewRange = newRange + print( "pivot= " + pivotX + " deltaX= " + (deltaX)) + checkView() + } + + + onPaint: { + // print("mycanvasOnPaint " + jobsArray.length) + var lineHeight = 12; + + function getXFromTime(t) { + return (t / mycanvas.frameDuration) * mycanvas.frameViewRange - (mycanvas.frameViewBegin) + } + function getWFromDuration(d) { + return (d / mycanvas.frameDuration) * mycanvas.frameViewRange + } function displayBackground(ctx) { ctx.fillStyle = Qt.rgba(0, 0, 0, root.backgroundOpacity); ctx.fillRect(0, 0, width, height); @@ -80,15 +147,34 @@ Rectangle { ctx.lineTo(width, lineHeight + 1); ctx.moveTo(0, height); ctx.lineTo(width, height); + + var x0 = getXFromTime(0) + ctx.moveTo(x0, 0); + ctx.lineTo(x0, height); + + x0 = getXFromTime(5) + ctx.moveTo(x0, 0); + ctx.lineTo(x0, height); + + x0 = getXFromTime(10) + ctx.moveTo(x0, 0); + ctx.lineTo(x0, height); + ctx.stroke(); } - function drawJob(ctx, depth, index, duration, timeOffset, timeScale) { + function drawJob(ctx, depth, index, duration, timeOffset) { //print(root.jobsArray[index].cpuT) // ctx.fillStyle = Qt.rgba(255, 255, 0, root.backgroundOpacity); ctx.fillStyle = ( depth % 2 ? ( index % 2 ? "blue" : "yellow") : ( index % 2 ? "green" : "red")) - ctx.fillRect(timeOffset * timeScale, lineHeight * depth, duration * timeScale, lineHeight * 0.6); - + ctx.fillRect(getXFromTime(timeOffset), lineHeight * 2 * depth,getWFromDuration(duration), lineHeight); + + if (depth,getWFromDuration(duration) >= width * 0.1) { + ctx.fillStyle = "grey"; + ctx.textAlign = "center"; + ctx.fillText( root.jobsArray[index].name, getXFromTime(timeOffset + duration * 0.5), lineHeight * 2 * depth); + + } } var ctx = getContext("2d"); @@ -97,26 +183,22 @@ Rectangle { displayBackground(ctx); if (jobsArray.length > 0) { - + mycanvas.frameDuration = Math.max(jobsArray[0].cpuT, 1) var rangeStack =new Array() - var frameDuration = Math.max(jobsArray[0].cpuT, 1) - rangeStack.push( { "b": 0.0, "e": frameDuration } ) - var timeScale = width * 0.9 / frameDuration; - - drawJob(ctx, 0, 0, jobsArray[0].cpuT, 0, timeScale) + rangeStack.push( { "b": 0.0, "e": mycanvas.frameDuration } ) + + drawJob(ctx, 0, 0, jobsArray[0].cpuT, 0) for (var i = 1; i lastDepth) { timeOffset = rangeStack[lastDepth].b while(rangeStack.length <= depth) { - rangeStack.push( { "b": timeOffset, "e": duration } ) + rangeStack.push( { "b": timeOffset, "e": timeOffset + duration } ) } } else { @@ -130,12 +212,54 @@ Rectangle { rangeStack[depth].b = timeOffset rangeStack[depth].e = timeOffset + duration } - - print("j " + i + " depth " + depth + " lastDepth " + lastDepth + " off " + timeOffset + " dur " + duration) - drawJob(ctx, depth, i, duration, timeOffset, timeScale) + if (duration > 0.0) { + drawJob(ctx, depth, i, duration, timeOffset) } } } } } + + MouseArea { + id: hitbox + anchors.fill: mycanvas + acceptedButtons: Qt.LeftButton | Qt.RightButton + + property var pivotX + property var dragPos + onPressed: { + dragPos = { "x":mouse.x, "y":mouse.y } + pivotX = mouse.x + } + onPositionChanged: { + if (dragPos !== undefined) { + var delta = mouse.x - dragPos.x + + if (mouse.buttons & Qt.LeftButton) { + mycanvas.drag(delta) + } + + if (mouse.buttons & Qt.RightButton) { + mycanvas.pivotScale(pivotX, delta) + } + + dragPos.x = mouse.x + dragPos.y = mouse.y + mycanvas.requestPaint() + } + } + onReleased: { + dragPos = undefined + } + + onWheel: { + mycanvas.pivotScale(wheel.x, mycanvas.frameViewRange * 0.02 * (wheel.angleDelta.y / 120.0)) + mycanvas.requestPaint() + } + + onDoubleClicked: { + mycanvas.reset() + mycanvas.requestPaint() + } + } } \ No newline at end of file diff --git a/scripts/developer/utilities/render/engineInspector.js b/scripts/developer/utilities/render/engineInspector.js index 348ae8f54f..e6be7f1c3c 100644 --- a/scripts/developer/utilities/render/engineInspector.js +++ b/scripts/developer/utilities/render/engineInspector.js @@ -1,4 +1,4 @@ - function openEngineTaskView() { + /*function openEngineTaskView() { // Set up the qml ui var qml = Script.resolvePath('engineInspector.qml'); var window = new OverlayWindow({ @@ -10,6 +10,62 @@ window.setPosition(200, 50); window.closed.connect(function() { Script.stop(); }); } - openEngineTaskView(); + openEngineTaskView();*/ + (function() { + var TABLET_BUTTON_NAME = "Render Engine"; + var QMLAPP_URL = Script.resolvePath("./engineInspector.qml"); + var ICON_URL = Script.resolvePath("../../../system/assets/images/lod-i.svg"); + var ACTIVE_ICON_URL = Script.resolvePath("../../../system/assets/images/lod-a.svg"); + + var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + var button = tablet.addButton({ + text: TABLET_BUTTON_NAME, + icon: ICON_URL, + activeIcon: ACTIVE_ICON_URL + }); + + Script.scriptEnding.connect(function () { + killWindow() + button.clicked.disconnect(onClicked); + tablet.removeButton(button); + }); + + button.clicked.connect(onClicked); + + var onScreen = false; + var window; + + function onClicked() { + if (onScreen) { + killWindow() + } else { + createWindow() + } + } + + function createWindow() { + var qml = Script.resolvePath(QMLAPP_URL); + window = new OverlayWindow({ + title: 'Render Engine', + source: qml, + width: 500, + height: 100 + }); + window.setPosition(200, 50); + window.closed.connect(killWindow); + onScreen = true + button.editProperties({isActive: true}); + } + + function killWindow() { + if (window !== undefined) { + window.closed.disconnect(killWindow); + window.close() + window = undefined + } + onScreen = false + button.editProperties({isActive: false}) + } + }()); \ No newline at end of file diff --git a/scripts/developer/utilities/render/engineInspector.qml b/scripts/developer/utilities/render/engineInspector.qml index d2a6e01524..d3bd2e96fd 100644 --- a/scripts/developer/utilities/render/engineInspector.qml +++ b/scripts/developer/utilities/render/engineInspector.qml @@ -23,9 +23,14 @@ Item { property var mainViewTask: Render.getConfig("RenderMainView") - //Jet.TaskListView { + Jet.TaskTimeFrameView { rootConfig: Render anchors.fill: render } + /* Jet.TaskListView { + rootConfig: Render + anchors.fill: render + } */ + } \ No newline at end of file From 0f3cb0fb84a2928c699b888dbfa454ef394286c2 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 3 Jul 2018 12:50:52 +0200 Subject: [PATCH 003/109] INtroducing th eGraphics Engine to group al the graphics related (render and gpu) elements --- interface/src/Application.cpp | 176 ++++++------------ interface/src/Application.h | 33 ++-- interface/src/Application_render.cpp | 139 +++++++------- interface/src/Util.cpp | 108 ----------- interface/src/Util.h | 5 - interface/src/graphics/GraphicsEngine.cpp | 167 +++++++++++++++++ interface/src/graphics/GraphicsEngine.h | 57 ++++++ interface/src/graphics/RenderEventHandler.cpp | 71 +++++++ interface/src/graphics/RenderEventHandler.h | 47 +++++ interface/src/graphics/WorldBox.cpp | 138 ++++++++++++++ interface/src/graphics/WorldBox.h | 43 +++++ interface/src/ui/ApplicationOverlay.cpp | 2 +- .../src/DeferredLightingEffect.cpp | 7 +- .../render-utils/src/DeferredLightingEffect.h | 3 +- libraries/render-utils/src/LightStage.cpp | 10 +- 15 files changed, 686 insertions(+), 320 deletions(-) create mode 100644 interface/src/graphics/GraphicsEngine.cpp create mode 100644 interface/src/graphics/GraphicsEngine.h create mode 100644 interface/src/graphics/RenderEventHandler.cpp create mode 100644 interface/src/graphics/RenderEventHandler.h create mode 100644 interface/src/graphics/WorldBox.cpp create mode 100644 interface/src/graphics/WorldBox.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a60d72073c..dc7a34e728 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -83,7 +83,7 @@ #include #include #include -#include +//#include #include #include #include @@ -116,8 +116,8 @@ #include #include #include -#include -#include +//#include +//#include #include #include #include @@ -247,71 +247,7 @@ extern "C" { #include "AndroidHelper.h" #endif -enum ApplicationEvent { - // Execute a lambda function - Lambda = QEvent::User + 1, - // Trigger the next render - Render, - // Trigger the next idle - Idle, -}; - -class RenderEventHandler : public QObject { - using Parent = QObject; - Q_OBJECT -public: - RenderEventHandler(QOpenGLContext* context) { - _renderContext = new OffscreenGLCanvas(); - _renderContext->setObjectName("RenderContext"); - _renderContext->create(context); - if (!_renderContext->makeCurrent()) { - qFatal("Unable to make rendering context current"); - } - _renderContext->doneCurrent(); - - // Deleting the object with automatically shutdown the thread - connect(qApp, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater); - - // Transfer to a new thread - moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) { - hifi::qt::addBlockingForbiddenThread("Render", renderThread); - _renderContext->moveToThreadWithContext(renderThread); - qApp->_lastTimeRendered.start(); - }, std::bind(&RenderEventHandler::initialize, this), QThread::HighestPriority); - } - -private: - void initialize() { - setObjectName("Render"); - PROFILE_SET_THREAD_NAME("Render"); - setCrashAnnotation("render_thread_id", std::to_string((size_t)QThread::currentThreadId())); - if (!_renderContext->makeCurrent()) { - qFatal("Unable to make rendering context current on render thread"); - } - } - - void render() { - if (qApp->shouldPaint()) { - qApp->paintGL(); - } - } - - bool event(QEvent* event) override { - switch ((int)event->type()) { - case ApplicationEvent::Render: - render(); - qApp->_pendingRenderEvent.store(false); - return true; - - default: - break; - } - return Parent::event(event); - } - - OffscreenGLCanvas* _renderContext { nullptr }; -}; - +#include "graphics/RenderEventHandler.h" Q_LOGGING_CATEGORY(trace_app_input_mouse, "trace.app.input.mouse") @@ -2254,7 +2190,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo DependencyManager::get()->preloadSounds(); _pendingIdleEvent = false; - _pendingRenderEvent = false; + // _pendingRenderEvent = false; + _graphicsEngine.startup(); qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); @@ -2469,8 +2406,8 @@ void Application::cleanupBeforeQuit() { // The cleanup process enqueues the transactions but does not process them. Calling this here will force the actual // removal of the items. // See https://highfidelity.fogbugz.com/f/cases/5328 - _main3DScene->enqueueFrame(); // flush all the transactions - _main3DScene->processTransactionQueue(); // process and apply deletions + // _main3DScene->enqueueFrame(); // flush all the transactions + // _main3DScene->processTransactionQueue(); // process and apply deletions // first stop all timers directly or by invokeMethod // depending on what thread they run in @@ -2485,7 +2422,7 @@ void Application::cleanupBeforeQuit() { } _window->saveGeometry(); - _gpuContext->shutdown(); + // _gpuContext->shutdown(); // Destroy third party processes after scripts have finished using them. #ifdef HAVE_DDE @@ -2539,9 +2476,10 @@ Application::~Application() { assert(_shapeManager.getNumShapes() == 0); // shutdown render engine - _main3DScene = nullptr; - _renderEngine = nullptr; - + //_main3DScene = nullptr; + //_renderEngine = nullptr; + _graphicsEngine.shutdown(); + _gameWorkload.shutdown(); DependencyManager::destroy(); @@ -2655,7 +2593,7 @@ void Application::initializeGL() { } } - // Build an offscreen GL context for the main thread. + /* // Build an offscreen GL context for the main thread. _offscreenContext = new OffscreenGLCanvas(); _offscreenContext->setObjectName("MainThreadContext"); _offscreenContext->create(_glWidget->qglContext()); @@ -2664,34 +2602,36 @@ void Application::initializeGL() { } _offscreenContext->doneCurrent(); _offscreenContext->setThreadContext(); - +*/ _glWidget->makeCurrent(); glClearColor(0.2f, 0.2f, 0.2f, 1); glClear(GL_COLOR_BUFFER_BIT); _glWidget->swapBuffers(); // Move the GL widget context to the render event handler thread - _renderEventHandler = new RenderEventHandler(_glWidget->qglContext()); - if (!_offscreenContext->makeCurrent()) { - qFatal("Unable to make offscreen context current"); - } + // _renderEventHandler = new RenderEventHandler(_glWidget->qglContext()); + // if (!_offscreenContext->makeCurrent()) { + // qFatal("Unable to make offscreen context current"); + // } // Create the GPU backend - // Requires the window context, because that's what's used in the actual rendering - // and the GPU backend will make things like the VAO which cannot be shared across - // contexts - _glWidget->makeCurrent(); - gpu::Context::init(); - qApp->setProperty(hifi::properties::gl::MAKE_PROGRAM_CALLBACK, - QVariant::fromValue((void*)(&gpu::gl::GLBackend::makeProgram))); - _glWidget->makeCurrent(); - _gpuContext = std::make_shared(); + //// Requires the window context, because that's what's used in the actual rendering + //// and the GPU backend will make things like the VAO which cannot be shared across + //// contexts + //_glWidget->makeCurrent(); + //gpu::Context::init(); + //qApp->setProperty(hifi::properties::gl::MAKE_PROGRAM_CALLBACK, + // QVariant::fromValue((void*)(&gpu::gl::GLBackend::makeProgram))); + //_glWidget->makeCurrent(); + //_gpuContext = std::make_shared(); - DependencyManager::get()->setGPUContext(_gpuContext); + //DependencyManager::get()->setGPUContext(_gpuContext); - // Restore the default main thread context - _offscreenContext->makeCurrent(); + //// Restore the default main thread context + //_offscreenContext->makeCurrent(); + + _graphicsEngine.initializeGPU(_glWidget); } static const QString SPLASH_SKYBOX{ "{\"ProceduralEntity\":{ \"version\":2, \"shaderUrl\":\"qrc:///shaders/splashSkybox.frag\" } }" }; @@ -2705,7 +2645,7 @@ void Application::initializeDisplayPlugins() { // Once time initialization code DisplayPluginPointer targetDisplayPlugin; foreach(auto displayPlugin, displayPlugins) { - displayPlugin->setContext(_gpuContext); + displayPlugin->setContext(_graphicsEngine.getGPUContext()); if (displayPlugin->getName() == lastActiveDisplayPluginName) { targetDisplayPlugin = displayPlugin; } @@ -2719,14 +2659,14 @@ void Application::initializeDisplayPlugins() { setDisplayPlugin(defaultDisplayPlugin); // Now set the desired plugin if it's not the same as the default plugin - if (targetDisplayPlugin != defaultDisplayPlugin) { + if (targetDisplayPlugin && (targetDisplayPlugin != defaultDisplayPlugin)) { setDisplayPlugin(targetDisplayPlugin); } // Submit a default frame to render until the engine starts up updateRenderArgs(0.0f); - _offscreenContext->makeCurrent(); + _graphicsEngine._offscreenContext->makeCurrent(); #define ENABLE_SPLASH_FRAME 0 #if ENABLE_SPLASH_FRAME @@ -2769,11 +2709,12 @@ void Application::initializeDisplayPlugins() { } void Application::initializeRenderEngine() { - _offscreenContext->makeCurrent(); + // _offscreenContext->makeCurrent(); // FIXME: on low end systems os the shaders take up to 1 minute to compile, so we pause the deadlock watchdog thread. DeadlockWatchdogThread::withPause([&] { - // Set up the render engine + _graphicsEngine.initializeRender(DISABLE_DEFERRED); + /* // Set up the render engine render::CullFunctor cullFunctor = LODManager::shouldRender; _renderEngine->addJob("UpdateScene"); #ifndef Q_OS_ANDROID @@ -2785,7 +2726,7 @@ void Application::initializeRenderEngine() { // Now that OpenGL is initialized, we are sure we have a valid context and can create the various pipeline shaders with success. DependencyManager::get()->initializeShapePipelines(); - }); + */ }); } extern void setupPreferences(); @@ -2999,7 +2940,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) { surfaceContext->setContextProperty("LODManager", DependencyManager::get().data()); surfaceContext->setContextProperty("HMD", DependencyManager::get().data()); surfaceContext->setContextProperty("Scene", DependencyManager::get().data()); - surfaceContext->setContextProperty("Render", _renderEngine->getConfiguration().get()); + surfaceContext->setContextProperty("Render", _graphicsEngine.getRenderEngine()->getConfiguration().get()); surfaceContext->setContextProperty("Workload", _gameWorkload._engine->getConfiguration().get()); surfaceContext->setContextProperty("Reticle", getApplicationCompositor().getReticleInterface()); surfaceContext->setContextProperty("Snapshot", DependencyManager::get().data()); @@ -3454,8 +3395,8 @@ void Application::onPresent(quint32 frameCount) { postEvent(this, new QEvent((QEvent::Type)ApplicationEvent::Idle), Qt::HighEventPriority); } expected = false; - if (_renderEventHandler && !isAboutToQuit() && _pendingRenderEvent.compare_exchange_strong(expected, true)) { - postEvent(_renderEventHandler, new QEvent((QEvent::Type)ApplicationEvent::Render)); + if (_graphicsEngine.checkPendingRenderEvent() && !isAboutToQuit()) { + postEvent(_graphicsEngine._renderEventHandler, new QEvent((QEvent::Type)ApplicationEvent::Render)); } } @@ -4229,7 +4170,8 @@ bool Application::shouldPaint() const { #endif // Throttle if requested - if (displayPlugin->isThrottled() && (_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { + //if (displayPlugin->isThrottled() && (_graphicsEngine._renderEventHandler->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { + if (displayPlugin->isThrottled() && _graphicsEngine.shouldPaint()) { return false; } @@ -4481,7 +4423,7 @@ void Application::idle() { if (offscreenUi->size() != fromGlm(uiSize)) { qCDebug(interfaceapp) << "Device pixel ratio changed, triggering resize to " << uiSize; offscreenUi->resize(fromGlm(uiSize)); - _offscreenContext->makeCurrent(); + _graphicsEngine._offscreenContext->makeCurrent(); } } @@ -4493,8 +4435,8 @@ void Application::idle() { PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", int, ResourceCache::getPendingRequestCount()); PROFILE_COUNTER_IF_CHANGED(app, "currentProcessing", int, DependencyManager::get()->getStat("Processing").toInt()); PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get()->getStat("PendingProcessing").toInt()); - auto renderConfig = _renderEngine->getConfiguration(); - PROFILE_COUNTER_IF_CHANGED(render, "gpuTime", float, (float)_gpuContext->getFrameTimerGPUAverage()); + auto renderConfig = _graphicsEngine.getRenderEngine()->getConfiguration(); + PROFILE_COUNTER_IF_CHANGED(render, "gpuTime", float, (float)_graphicsEngine.getGPUContext()->getFrameTimerGPUAverage()); auto opaqueRangeTimer = renderConfig->getConfig("OpaqueRangeTimer"); auto linearDepth = renderConfig->getConfig("LinearDepth"); auto surfaceGeometry = renderConfig->getConfig("SurfaceGeometry"); @@ -4536,7 +4478,7 @@ void Application::idle() { bool showWarnings = getLogger()->extraDebugging(); PerformanceWarning warn(showWarnings, "idle()"); - if (!_offscreenContext->makeCurrent()) { + if (!_graphicsEngine._offscreenContext->makeCurrent()) { qFatal("Unable to make main thread context current"); } @@ -4866,12 +4808,12 @@ QVector Application::pasteEntities(float x, float y, float z) { } void Application::init() { - _offscreenContext->makeCurrent(); + _graphicsEngine._offscreenContext->makeCurrent(); // Make sure Login state is up to date DependencyManager::get()->toggleLoginDialog(); - if (!DISABLE_DEFERRED) { - DependencyManager::get()->init(); - } +// if (!DISABLE_DEFERRED) { + // DependencyManager::get()->init(); + // } DependencyManager::get()->init(); _timerStart.start(); @@ -4940,7 +4882,7 @@ void Application::init() { } }, Qt::QueuedConnection); - _gameWorkload.startup(getEntities()->getWorkloadSpace(), _main3DScene, _entitySimulation); + _gameWorkload.startup(getEntities()->getWorkloadSpace(), _graphicsEngine.getRenderScene(), _entitySimulation); _entitySimulation->setWorkloadSpace(getEntities()->getWorkloadSpace()); } @@ -4974,7 +4916,7 @@ void Application::updateLOD(float deltaTime) const { // adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode if (!isThrottleRendering()) { float presentTime = getActiveDisplayPlugin()->getAveragePresentTime(); - float engineRunTime = (float)(_renderEngine->getConfiguration().get()->getCPURunTime()); + float engineRunTime = (float)(_graphicsEngine.getRenderEngine()->getConfiguration().get()->getCPURunTime()); float gpuTime = getGPUContext()->getFrameTimerGPUAverage(); auto lodManager = DependencyManager::get(); lodManager->setRenderTimes(presentTime, engineRunTime, gpuTime); @@ -5364,7 +5306,7 @@ void Application::updateSecondaryCameraViewFrustum() { // camera should be. // Code based on SecondaryCameraJob - auto renderConfig = _renderEngine->getConfiguration(); + auto renderConfig = _graphicsEngine.getRenderEngine()->getConfiguration(); assert(renderConfig); auto camera = dynamic_cast(renderConfig->getConfig("SecondaryCamera")); @@ -5935,7 +5877,7 @@ void Application::updateRenderArgs(float deltaTime) { _viewFrustum.setProjection(adjustedProjection); _viewFrustum.calculate(); } - appRenderArgs._renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), + appRenderArgs._renderArgs = RenderArgs(_graphicsEngine.getGPUContext(), lodManager->getOctreeSizeScale(), lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); appRenderArgs._renderArgs._scene = getMain3DScene(); @@ -6597,7 +6539,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe scriptEngine->registerFunction("HMD", "getHUDLookAtPosition3D", HMDScriptingInterface::getHUDLookAtPosition3D, 0); scriptEngine->registerGlobalObject("Scene", DependencyManager::get().data()); - scriptEngine->registerGlobalObject("Render", _renderEngine->getConfiguration().get()); + scriptEngine->registerGlobalObject("Render", _graphicsEngine.getRenderEngine()->getConfiguration().get()); scriptEngine->registerGlobalObject("Workload", _gameWorkload._engine->getConfiguration().get()); GraphicsScriptingInterface::registerMetaTypes(scriptEngine.data()); @@ -8241,7 +8183,7 @@ QOpenGLContext* Application::getPrimaryContext() { } bool Application::makeRenderingContextCurrent() { - return _offscreenContext->makeCurrent(); + return _graphicsEngine._offscreenContext->makeCurrent(); } bool Application::isForeground() const { diff --git a/interface/src/Application.h b/interface/src/Application.h index 346ea258da..249c5a723a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -73,6 +73,7 @@ #include "UndoStackScriptingInterface.h" #include "workload/GameWorkload.h" +#include "graphics/GraphicsEngine.h" #include #include @@ -157,6 +158,7 @@ public: void updateSecondaryCameraViewFrustum(); void updateCamera(RenderArgs& renderArgs, float deltaTime); + bool shouldPaint() const; void paintGL(); void resizeGL(); @@ -271,10 +273,16 @@ public: void setMaxOctreePacketsPerSecond(int maxOctreePPS); int getMaxOctreePacketsPerSecond() const; - render::ScenePointer getMain3DScene() override { return _main3DScene; } +/* render::ScenePointer getMain3DScene() override { return _main3DScene; } const render::ScenePointer& getMain3DScene() const { return _main3DScene; } render::EnginePointer getRenderEngine() override { return _renderEngine; } gpu::ContextPointer getGPUContext() const { return _gpuContext; } + */ + render::ScenePointer getMain3DScene() override { return _graphicsEngine.getRenderScene(); } + const render::ScenePointer& getMain3DScene() const { return _graphicsEngine.getRenderScene(); } + render::EnginePointer getRenderEngine() override { return _graphicsEngine.getRenderEngine(); } + gpu::ContextPointer getGPUContext() const { return _graphicsEngine.getGPUContext(); } + const GameWorkload& getGameWorkload() const { return _gameWorkload; } @@ -490,7 +498,6 @@ private: bool handleFileOpenEvent(QFileOpenEvent* event); void cleanupBeforeQuit(); - bool shouldPaint() const; void idle(); void update(float deltaTime); @@ -510,7 +517,7 @@ private: void initializeAcceptedFiles(); - void runRenderFrame(RenderArgs* renderArgs/*, Camera& whichCamera, bool selfAvatarOnly = false*/); + // void runRenderFrame(RenderArgs* renderArgs/*, Camera& whichCamera, bool selfAvatarOnly = false*/); bool importJSONFromURL(const QString& urlString); bool importSVOFromURL(const QString& urlString); @@ -551,7 +558,7 @@ private: bool _previousSessionCrashed; - OffscreenGLCanvas* _offscreenContext { nullptr }; + // OffscreenGLCanvas* _offscreenContext { nullptr }; DisplayPluginPointer _displayPlugin; QMetaObject::Connection _displayPluginPresentConnection; mutable std::mutex _displayPluginLock; @@ -573,7 +580,7 @@ private: QTimer _minimizedWindowTimer; QElapsedTimer _timerStart; QElapsedTimer _lastTimeUpdated; - QElapsedTimer _lastTimeRendered; + // QElapsedTimer _lastTimeRendered; ShapeManager _shapeManager; PhysicalEntitySimulationPointer _entitySimulation; @@ -657,12 +664,14 @@ private: quint64 _lastFaceTrackerUpdate; - render::ScenePointer _main3DScene{ new render::Scene(glm::vec3(-0.5f * (float)TREE_SCALE), (float)TREE_SCALE) }; - render::EnginePointer _renderEngine{ new render::RenderEngine() }; - gpu::ContextPointer _gpuContext; // initialized during window creation + // render::ScenePointer _main3DScene{ new render::Scene(glm::vec3(-0.5f * (float)TREE_SCALE), (float)TREE_SCALE) }; + // render::EnginePointer _renderEngine{ new render::RenderEngine() }; + // gpu::ContextPointer _gpuContext; // initialized during window creation GameWorkload _gameWorkload; + GraphicsEngine _graphicsEngine; + mutable QMutex _renderArgsMutex{ QMutex::Recursive }; struct AppRenderArgs { render::Args _renderArgs; @@ -720,8 +729,6 @@ private: bool _keyboardDeviceHasFocus { true }; - QString _returnFromFullScreenMirrorTo; - ConnectionMonitor _connectionMonitor; QTimer _addAssetToWorldResizeTimer; @@ -754,12 +761,12 @@ private: QUrl _avatarOverrideUrl; bool _saveAvatarOverrideUrl { false }; - QObject* _renderEventHandler{ nullptr }; + // QObject* _renderEventHandler{ nullptr }; - friend class RenderEventHandler; + // friend class RenderEventHandler; std::atomic _pendingIdleEvent { true }; - std::atomic _pendingRenderEvent { true }; + // std::atomic _pendingRenderEvent { true }; bool quitWhenFinished { false }; }; diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index 2daa49dcf7..9fe259ea36 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -32,7 +32,8 @@ void Application::paintGL() { // Some plugins process message events, allowing paintGL to be called reentrantly. _renderFrameCount++; - _lastTimeRendered.start(); + // SG: Moved into the RenderEventHandler + //_lastTimeRendered.start(); auto lastPaintBegin = usecTimestampNow(); PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_renderFrameCount); @@ -88,10 +89,10 @@ void Application::paintGL() { { PROFILE_RANGE(render, "/gpuContextReset"); - _gpuContext->beginFrame(_appRenderArgs._view, HMDSensorPose); + _graphicsEngine.getGPUContext()->beginFrame(_appRenderArgs._view, HMDSensorPose); // Reset the gpu::Context Stages // Back to the default framebuffer; - gpu::doInBatch("Application_render::gpuContextReset", _gpuContext, [&](gpu::Batch& batch) { + gpu::doInBatch("Application_render::gpuContextReset", _graphicsEngine.getGPUContext(), [&](gpu::Batch& batch) { batch.resetStages(); }); } @@ -132,10 +133,10 @@ void Application::paintGL() { renderArgs._hudOperator = displayPlugin->getHUDOperator(); renderArgs._hudTexture = _applicationOverlay.getOverlayTexture(); renderArgs._blitFramebuffer = finalFramebuffer; - runRenderFrame(&renderArgs); + _graphicsEngine.render_runRenderFrame(&renderArgs); } - auto frame = _gpuContext->endFrame(); + auto frame = _graphicsEngine.getGPUContext()->endFrame(); frame->frameIndex = _renderFrameCount; frame->framebuffer = finalFramebuffer; frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) { @@ -163,68 +164,68 @@ void Application::paintGL() { // WorldBox Render Data & rendering functions - -class WorldBoxRenderData { -public: - typedef render::Payload Payload; - typedef Payload::DataPointer Pointer; - - int _val = 0; - static render::ItemID _item; // unique WorldBoxRenderData -}; - -render::ItemID WorldBoxRenderData::_item{ render::Item::INVALID_ITEM_ID }; - -namespace render { - template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape().withTagBits(ItemKey::TAG_BITS_0 | ItemKey::TAG_BITS_1); } - template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } - template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { - if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { - PerformanceTimer perfTimer("worldBox"); - - auto& batch = *args->_batch; - DependencyManager::get()->bindSimpleProgram(batch); - renderWorldBox(args, batch); - } - } -} - -void Application::runRenderFrame(RenderArgs* renderArgs) { - PROFILE_RANGE(render, __FUNCTION__); - PerformanceTimer perfTimer("display"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); - - // The pending changes collecting the changes here - render::Transaction transaction; - - if (DependencyManager::get()->shouldRenderEntities()) { - // render models... - PerformanceTimer perfTimer("entities"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::runRenderFrame() ... entities..."); - - RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; - - renderArgs->_debugFlags = renderDebugFlags; - } - - // Make sure the WorldBox is in the scene - // For the record, this one RenderItem is the first one we created and added to the scene. - // We could move that code elsewhere but you know... - if (!render::Item::isValidID(WorldBoxRenderData::_item)) { - auto worldBoxRenderData = std::make_shared(); - auto worldBoxRenderPayload = std::make_shared(worldBoxRenderData); - - WorldBoxRenderData::_item = _main3DScene->allocateID(); - - transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); - _main3DScene->enqueueTransaction(transaction); - } - - { - PerformanceTimer perfTimer("EngineRun"); - _renderEngine->getRenderContext()->args = renderArgs; - _renderEngine->run(); - } -} +// +//class WorldBoxRenderData { +//public: +// typedef render::Payload Payload; +// typedef Payload::DataPointer Pointer; +// +// int _val = 0; +// static render::ItemID _item; // unique WorldBoxRenderData +//}; +// +//render::ItemID WorldBoxRenderData::_item{ render::Item::INVALID_ITEM_ID }; +// +//namespace render { +// template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape().withTagBits(ItemKey::TAG_BITS_0 | ItemKey::TAG_BITS_1); } +// template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } +// template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { +// if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { +// PerformanceTimer perfTimer("worldBox"); +// +// auto& batch = *args->_batch; +// DependencyManager::get()->bindSimpleProgram(batch); +// renderWorldBox(args, batch); +// } +// } +//} +// +//void Application::runRenderFrame(RenderArgs* renderArgs) { +// PROFILE_RANGE(render, __FUNCTION__); +// PerformanceTimer perfTimer("display"); +// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); +// +// // The pending changes collecting the changes here +// render::Transaction transaction; +// +// if (DependencyManager::get()->shouldRenderEntities()) { +// // render models... +// PerformanceTimer perfTimer("entities"); +// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), +// "Application::runRenderFrame() ... entities..."); +// +// RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; +// +// renderArgs->_debugFlags = renderDebugFlags; +// } +// +// // Make sure the WorldBox is in the scene +// // For the record, this one RenderItem is the first one we created and added to the scene. +// // We could move that code elsewhere but you know... +// if (!render::Item::isValidID(WorldBoxRenderData::_item)) { +// auto worldBoxRenderData = std::make_shared(); +// auto worldBoxRenderPayload = std::make_shared(worldBoxRenderData); +// +// WorldBoxRenderData::_item = _main3DScene->allocateID(); +// +// transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); +// _main3DScene->enqueueTransaction(transaction); +// } +// +// { +// PerformanceTimer perfTimer("EngineRun"); +// _renderEngine->getRenderContext()->args = renderArgs; +// _renderEngine->run(); +// } +//} diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index e5e94da68a..e09872434a 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -36,114 +36,6 @@ using namespace std; -void renderWorldBox(RenderArgs* args, gpu::Batch& batch) { - auto geometryCache = DependencyManager::get(); - - // Show center of world - static const glm::vec3 RED(1.0f, 0.0f, 0.0f); - static const glm::vec3 GREEN(0.0f, 1.0f, 0.0f); - static const glm::vec3 BLUE(0.0f, 0.0f, 1.0f); - static const glm::vec3 GREY(0.5f, 0.5f, 0.5f); - static const glm::vec4 GREY4(0.5f, 0.5f, 0.5f, 1.0f); - - static const glm::vec4 DASHED_RED(1.0f, 0.0f, 0.0f, 1.0f); - static const glm::vec4 DASHED_GREEN(0.0f, 1.0f, 0.0f, 1.0f); - static const glm::vec4 DASHED_BLUE(0.0f, 0.0f, 1.0f, 1.0f); - static const float DASH_LENGTH = 1.0f; - static const float GAP_LENGTH = 1.0f; - auto transform = Transform{}; - static std::array geometryIds; - static std::once_flag initGeometryIds; - std::call_once(initGeometryIds, [&] { - for (size_t i = 0; i < geometryIds.size(); ++i) { - geometryIds[i] = geometryCache->allocateID(); - } - }); - - batch.setModelTransform(transform); - - geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(HALF_TREE_SCALE, 0.0f, 0.0f), RED, geometryIds[0]); - geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-HALF_TREE_SCALE, 0.0f, 0.0f), DASHED_RED, - DASH_LENGTH, GAP_LENGTH, geometryIds[1]); - - geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, HALF_TREE_SCALE, 0.0f), GREEN, geometryIds[2]); - geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -HALF_TREE_SCALE, 0.0f), DASHED_GREEN, - DASH_LENGTH, GAP_LENGTH, geometryIds[3]); - - geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, HALF_TREE_SCALE), BLUE, geometryIds[4]); - geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -HALF_TREE_SCALE), DASHED_BLUE, - DASH_LENGTH, GAP_LENGTH, geometryIds[5]); - - // X center boundaries - geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), - glm::vec3(HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), GREY, - geometryIds[6]); - geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), - glm::vec3(-HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY, - geometryIds[7]); - geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), - glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY, - geometryIds[8]); - geometryCache->renderLine(batch, glm::vec3(HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), - glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY, - geometryIds[9]); - - // Z center boundaries - geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, -HALF_TREE_SCALE), - glm::vec3(0.0f, -HALF_TREE_SCALE, HALF_TREE_SCALE), GREY, - geometryIds[10]); - geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, -HALF_TREE_SCALE), - glm::vec3(0.0f, HALF_TREE_SCALE, -HALF_TREE_SCALE), GREY, - geometryIds[11]); - geometryCache->renderLine(batch, glm::vec3(0.0f, HALF_TREE_SCALE, -HALF_TREE_SCALE), - glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY, - geometryIds[12]); - geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, HALF_TREE_SCALE), - glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY, - geometryIds[13]); - - // Center boundaries - geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), - glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY, - geometryIds[14]); - geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), - glm::vec3(HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), GREY, - geometryIds[15]); - geometryCache->renderLine(batch, glm::vec3(HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), - glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY, - geometryIds[16]); - geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), - glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY, - geometryIds[17]); - - - geometryCache->renderWireCubeInstance(args, batch, GREY4); - - // Draw meter markers along the 3 axis to help with measuring things - const float MARKER_DISTANCE = 1.0f; - const float MARKER_RADIUS = 0.05f; - - transform = Transform().setScale(MARKER_RADIUS); - batch.setModelTransform(transform); - geometryCache->renderSolidSphereInstance(args, batch, RED); - - transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, 0.0f)).setScale(MARKER_RADIUS); - batch.setModelTransform(transform); - geometryCache->renderSolidSphereInstance(args, batch, RED); - - transform = Transform().setTranslation(glm::vec3(0.0f, MARKER_DISTANCE, 0.0f)).setScale(MARKER_RADIUS); - batch.setModelTransform(transform); - geometryCache->renderSolidSphereInstance(args, batch, GREEN); - - transform = Transform().setTranslation(glm::vec3(0.0f, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); - batch.setModelTransform(transform); - geometryCache->renderSolidSphereInstance(args, batch, BLUE); - - transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); - batch.setModelTransform(transform); - geometryCache->renderSolidSphereInstance(args, batch, GREY); -} - // Do some basic timing tests and report the results void runTimingTests() { // How long does it take to make a call to get the time? diff --git a/interface/src/Util.h b/interface/src/Util.h index 976a26ce82..ef289f5416 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -15,14 +15,9 @@ #include #include -#include -#include - class ShapeEntityItem; class ShapeInfo; -void renderWorldBox(RenderArgs* args, gpu::Batch& batch); - void runTimingTests(); void runUnitTests(); diff --git a/interface/src/graphics/GraphicsEngine.cpp b/interface/src/graphics/GraphicsEngine.cpp new file mode 100644 index 0000000000..af207b988a --- /dev/null +++ b/interface/src/graphics/GraphicsEngine.cpp @@ -0,0 +1,167 @@ +// +// GraphicsEngine.cpp +// +// Created by Sam Gateau on 29/6/2018. +// Copyright 2018 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 "GraphicsEngine.h" + +#include + +#include "WorldBox.h" +#include "LODManager.h" + +#include +#include +#include +#include +#include + +#include "RenderEventHandler.h" + +#include +#include +#include + +GraphicsEngine::GraphicsEngine() { +} + +GraphicsEngine::~GraphicsEngine() { +} + +void GraphicsEngine::initializeGPU(GLWidget* glwidget) { + + // Build an offscreen GL context for the main thread. + _offscreenContext = new OffscreenGLCanvas(); + _offscreenContext->setObjectName("MainThreadContext"); + _offscreenContext->create(glwidget->qglContext()); + if (!_offscreenContext->makeCurrent()) { + qFatal("Unable to make offscreen context current"); + } + _offscreenContext->doneCurrent(); + _offscreenContext->setThreadContext(); + + _renderEventHandler = new RenderEventHandler(glwidget->qglContext()); + if (!_offscreenContext->makeCurrent()) { + qFatal("Unable to make offscreen context current"); + } + + // Requires the window context, because that's what's used in the actual rendering + // and the GPU backend will make things like the VAO which cannot be shared across + // contexts + glwidget->makeCurrent(); + gpu::Context::init(); + qApp->setProperty(hifi::properties::gl::MAKE_PROGRAM_CALLBACK, + QVariant::fromValue((void*)(&gpu::gl::GLBackend::makeProgram))); + glwidget->makeCurrent(); + _gpuContext = std::make_shared(); + + DependencyManager::get()->setGPUContext(_gpuContext); + + // Restore the default main thread context + _offscreenContext->makeCurrent(); +} + +void GraphicsEngine::initializeRender(bool disableDeferred) { + + // Set up the render engine + render::CullFunctor cullFunctor = LODManager::shouldRender; + _renderEngine->addJob("UpdateScene"); +#ifndef Q_OS_ANDROID + _renderEngine->addJob("SecondaryCameraJob", cullFunctor, !disableDeferred); +#endif + _renderEngine->addJob("RenderMainView", cullFunctor, !disableDeferred, render::ItemKey::TAG_BITS_0, render::ItemKey::TAG_BITS_0); + _renderEngine->load(); + _renderEngine->registerScene(_renderScene); + + // Now that OpenGL is initialized, we are sure we have a valid context and can create the various pipeline shaders with success. + DependencyManager::get()->initializeShapePipelines(); + + +} + +void GraphicsEngine::startup() { + + + static_cast(_renderEventHandler)->resumeThread(); +} + +void GraphicsEngine::shutdown() { + // The cleanup process enqueues the transactions but does not process them. Calling this here will force the actual + // removal of the items. + // See https://highfidelity.fogbugz.com/f/cases/5328 + _renderScene->enqueueFrame(); // flush all the transactions + _renderScene->processTransactionQueue(); // process and apply deletions + + _gpuContext->shutdown(); + + + // shutdown render engine + _renderScene = nullptr; + _renderEngine = nullptr; +} + + +void GraphicsEngine::render_runRenderFrame(RenderArgs* renderArgs) { + PROFILE_RANGE(render, __FUNCTION__); + PerformanceTimer perfTimer("render"); +// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); + + // The pending changes collecting the changes here + render::Transaction transaction; + + // this is not in use at all anymore + //if (DependencyManager::get()->shouldRenderEntities()) { + // render models... + // PerformanceTimer perfTimer("entities"); + // PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + // "Application::runRenderFrame() ... entities..."); + + //RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; + + //renderArgs->_debugFlags = renderDebugFlags; + //} + + // Make sure the WorldBox is in the scene + // For the record, this one RenderItem is the first one we created and added to the scene. + // We could move that code elsewhere but you know... + if (!render::Item::isValidID(WorldBoxRenderData::_item)) { + auto worldBoxRenderData = std::make_shared(); + auto worldBoxRenderPayload = std::make_shared(worldBoxRenderData); + + WorldBoxRenderData::_item = _renderScene->allocateID(); + + transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); + _renderScene->enqueueTransaction(transaction); + } + + { + // PerformanceTimer perfTimer("EngineRun"); + _renderEngine->getRenderContext()->args = renderArgs; + _renderEngine->run(); + } +} + +static const unsigned int THROTTLED_SIM_FRAMERATE = 15; +static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SIM_FRAMERATE; + + + + +bool GraphicsEngine::shouldPaint() const { + + // Throttle if requested + if ((static_cast(_renderEventHandler)->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { + return false; + } + + return true; +} + +bool GraphicsEngine::checkPendingRenderEvent() { + bool expected = false; + return (_renderEventHandler && static_cast(_renderEventHandler)->_pendingRenderEvent.compare_exchange_strong(expected, true)); +} diff --git a/interface/src/graphics/GraphicsEngine.h b/interface/src/graphics/GraphicsEngine.h new file mode 100644 index 0000000000..29128daafd --- /dev/null +++ b/interface/src/graphics/GraphicsEngine.h @@ -0,0 +1,57 @@ +// +// GraphicsEngine.h +// +// Created by Sam Gateau on 29/6/2018. +// Copyright 2018 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_GraphicsEngine_h +#define hifi_GraphicsEngine_h + +#include +#include + +#include + +#include + +class GraphicsEngine { +public: + GraphicsEngine(); + ~GraphicsEngine(); + + void initializeGPU(GLWidget*); + void initializeRender(bool disableDeferred); + void startup(); + void shutdown(); + + render::ScenePointer getRenderScene() const { return _renderScene; } + render::EnginePointer getRenderEngine() const { return _renderEngine; } + gpu::ContextPointer getGPUContext() const { return _gpuContext; } + + // Same as the one in application + bool shouldPaint() const; + bool checkPendingRenderEvent(); + +private: + // THread specific calls + void render_runRenderFrame(RenderArgs* renderArgs); + +protected: + + render::ScenePointer _renderScene{ new render::Scene(glm::vec3(-0.5f * (float)TREE_SCALE), (float)TREE_SCALE) }; + render::EnginePointer _renderEngine{ new render::RenderEngine() }; + + gpu::ContextPointer _gpuContext; // initialized during window creation + + QObject* _renderEventHandler{ nullptr }; + friend class RenderEventHandler; + + OffscreenGLCanvas* _offscreenContext{ nullptr }; + + friend class Application; +}; + +#endif // hifi_GraphicsEngine_h diff --git a/interface/src/graphics/RenderEventHandler.cpp b/interface/src/graphics/RenderEventHandler.cpp new file mode 100644 index 0000000000..0ca82201d5 --- /dev/null +++ b/interface/src/graphics/RenderEventHandler.cpp @@ -0,0 +1,71 @@ +// +// RenderEventHandler.cpp +// +// Created by Bradley Austin Davis on 29/6/2018. +// Copyright 2018 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 "RenderEventHandler.h" + +#include "Application.h" +#include +#include + +#include "CrashHandler.h" + +RenderEventHandler::RenderEventHandler(QOpenGLContext* context) { + _renderContext = new OffscreenGLCanvas(); + _renderContext->setObjectName("RenderContext"); + _renderContext->create(context); + if (!_renderContext->makeCurrent()) { + qFatal("Unable to make rendering context current"); + } + _renderContext->doneCurrent(); + + // Deleting the object with automatically shutdown the thread + connect(qApp, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater); + + // Transfer to a new thread + moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) { + hifi::qt::addBlockingForbiddenThread("Render", renderThread); + _renderContext->moveToThreadWithContext(renderThread); + _lastTimeRendered.start(); + }, std::bind(&RenderEventHandler::initialize, this), QThread::HighestPriority); +} + +void RenderEventHandler::initialize() { + setObjectName("Render"); + PROFILE_SET_THREAD_NAME("Render"); + setCrashAnnotation("render_thread_id", std::to_string((size_t)QThread::currentThreadId())); + if (!_renderContext->makeCurrent()) { + qFatal("Unable to make rendering context current on render thread"); + } + +} + +void RenderEventHandler::resumeThread() { + _pendingRenderEvent = false; +} + +void RenderEventHandler::render() { + if (qApp->shouldPaint()) { + _lastTimeRendered.start(); + qApp->paintGL(); + } +} + +bool RenderEventHandler::event(QEvent* event) { + switch ((int)event->type()) { + case ApplicationEvent::Render: + render(); + _pendingRenderEvent.store(false); + return true; + + default: + break; + } + return Parent::event(event); +} + diff --git a/interface/src/graphics/RenderEventHandler.h b/interface/src/graphics/RenderEventHandler.h new file mode 100644 index 0000000000..8b0e4c5e15 --- /dev/null +++ b/interface/src/graphics/RenderEventHandler.h @@ -0,0 +1,47 @@ +// +// RenderEventHandler.h +// +// Created by Bradley Austin Davis on 29/6/2018. +// Copyright 2018 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_RenderEventHandler_h +#define hifi_RenderEventHandler_h + +#include "gl/OffscreenGLCanvas.h" +#include +#include + +enum ApplicationEvent { + // Execute a lambda function + Lambda = QEvent::User + 1, + // Trigger the next render + Render, + // Trigger the next idle + Idle, +}; + +class RenderEventHandler : public QObject { + using Parent = QObject; + Q_OBJECT +public: + RenderEventHandler(QOpenGLContext* context); + + QElapsedTimer _lastTimeRendered; + std::atomic _pendingRenderEvent{ true }; + + void resumeThread(); + +private: + void initialize(); + + void render(); + + bool event(QEvent* event) override; + + OffscreenGLCanvas* _renderContext{ nullptr }; +}; + +#endif // #include hifi_RenderEventHandler_h \ No newline at end of file diff --git a/interface/src/graphics/WorldBox.cpp b/interface/src/graphics/WorldBox.cpp new file mode 100644 index 0000000000..908055e9c6 --- /dev/null +++ b/interface/src/graphics/WorldBox.cpp @@ -0,0 +1,138 @@ +// +// WorldBox.cpp +// +// Created by Sam Gateau on 01/07/2018. +// Copyright 2018 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 "WorldBox.h" + +#include "OctreeConstants.h" + +render::ItemID WorldBoxRenderData::_item{ render::Item::INVALID_ITEM_ID }; + + +namespace render { + template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape().withTagBits(ItemKey::TAG_BITS_0 | ItemKey::TAG_BITS_1); } + template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } + template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { + if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { + PerformanceTimer perfTimer("worldBox"); + + auto& batch = *args->_batch; + DependencyManager::get()->bindSimpleProgram(batch); + WorldBoxRenderData::renderWorldBox(args, batch); + } + } +} + +void WorldBoxRenderData::renderWorldBox(RenderArgs* args, gpu::Batch& batch) { + auto geometryCache = DependencyManager::get(); + + // Show center of world + static const glm::vec3 RED(1.0f, 0.0f, 0.0f); + static const glm::vec3 GREEN(0.0f, 1.0f, 0.0f); + static const glm::vec3 BLUE(0.0f, 0.0f, 1.0f); + static const glm::vec3 GREY(0.5f, 0.5f, 0.5f); + static const glm::vec4 GREY4(0.5f, 0.5f, 0.5f, 1.0f); + + static const glm::vec4 DASHED_RED(1.0f, 0.0f, 0.0f, 1.0f); + static const glm::vec4 DASHED_GREEN(0.0f, 1.0f, 0.0f, 1.0f); + static const glm::vec4 DASHED_BLUE(0.0f, 0.0f, 1.0f, 1.0f); + static const float DASH_LENGTH = 1.0f; + static const float GAP_LENGTH = 1.0f; + auto transform = Transform{}; + static std::array geometryIds; + static std::once_flag initGeometryIds; + std::call_once(initGeometryIds, [&] { + for (size_t i = 0; i < geometryIds.size(); ++i) { + geometryIds[i] = geometryCache->allocateID(); + } + }); + + batch.setModelTransform(transform); + + geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(HALF_TREE_SCALE, 0.0f, 0.0f), RED, geometryIds[0]); + geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-HALF_TREE_SCALE, 0.0f, 0.0f), DASHED_RED, + DASH_LENGTH, GAP_LENGTH, geometryIds[1]); + + geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, HALF_TREE_SCALE, 0.0f), GREEN, geometryIds[2]); + geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -HALF_TREE_SCALE, 0.0f), DASHED_GREEN, + DASH_LENGTH, GAP_LENGTH, geometryIds[3]); + + geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, HALF_TREE_SCALE), BLUE, geometryIds[4]); + geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -HALF_TREE_SCALE), DASHED_BLUE, + DASH_LENGTH, GAP_LENGTH, geometryIds[5]); + + // X center boundaries + geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), + glm::vec3(HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), GREY, + geometryIds[6]); + geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), + glm::vec3(-HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY, + geometryIds[7]); + geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), + glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY, + geometryIds[8]); + geometryCache->renderLine(batch, glm::vec3(HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), + glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY, + geometryIds[9]); + + // Z center boundaries + geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, -HALF_TREE_SCALE), + glm::vec3(0.0f, -HALF_TREE_SCALE, HALF_TREE_SCALE), GREY, + geometryIds[10]); + geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, -HALF_TREE_SCALE), + glm::vec3(0.0f, HALF_TREE_SCALE, -HALF_TREE_SCALE), GREY, + geometryIds[11]); + geometryCache->renderLine(batch, glm::vec3(0.0f, HALF_TREE_SCALE, -HALF_TREE_SCALE), + glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY, + geometryIds[12]); + geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, HALF_TREE_SCALE), + glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY, + geometryIds[13]); + + // Center boundaries + geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), + glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY, + geometryIds[14]); + geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), + glm::vec3(HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), GREY, + geometryIds[15]); + geometryCache->renderLine(batch, glm::vec3(HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), + glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY, + geometryIds[16]); + geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), + glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY, + geometryIds[17]); + + + geometryCache->renderWireCubeInstance(args, batch, GREY4); + + // Draw meter markers along the 3 axis to help with measuring things + const float MARKER_DISTANCE = 1.0f; + const float MARKER_RADIUS = 0.05f; + + transform = Transform().setScale(MARKER_RADIUS); + batch.setModelTransform(transform); + geometryCache->renderSolidSphereInstance(args, batch, RED); + + transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, 0.0f)).setScale(MARKER_RADIUS); + batch.setModelTransform(transform); + geometryCache->renderSolidSphereInstance(args, batch, RED); + + transform = Transform().setTranslation(glm::vec3(0.0f, MARKER_DISTANCE, 0.0f)).setScale(MARKER_RADIUS); + batch.setModelTransform(transform); + geometryCache->renderSolidSphereInstance(args, batch, GREEN); + + transform = Transform().setTranslation(glm::vec3(0.0f, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); + batch.setModelTransform(transform); + geometryCache->renderSolidSphereInstance(args, batch, BLUE); + + transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); + batch.setModelTransform(transform); + geometryCache->renderSolidSphereInstance(args, batch, GREY); +} + diff --git a/interface/src/graphics/WorldBox.h b/interface/src/graphics/WorldBox.h new file mode 100644 index 0000000000..114777ba0f --- /dev/null +++ b/interface/src/graphics/WorldBox.h @@ -0,0 +1,43 @@ +// +// WorldBox.h +// +// Created by Sam Gateau on 01/07/2018. +// Copyright 2018 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_WorldBox_h +#define hifi_WorldBox_h + +#include + +#include +#include + +#include +#include +#include "Menu.h" + + + +class WorldBoxRenderData { +public: + typedef render::Payload Payload; + typedef Payload::DataPointer Pointer; + + int _val = 0; + static render::ItemID _item; // unique WorldBoxRenderData + + + + static void renderWorldBox(RenderArgs* args, gpu::Batch& batch); +}; + +namespace render { + template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff); + template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff); + template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args); +} + +#endif // hifi_WorldBox_h \ No newline at end of file diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index ea660fb0e2..a0b4f856a1 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -55,7 +55,7 @@ ApplicationOverlay::~ApplicationOverlay() { // Renders the overlays either to a texture or to the screen void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { PROFILE_RANGE(render, __FUNCTION__); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()"); +// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()"); buildFramebufferObject(); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 9223e0fa03..6b6d8f00b7 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -712,11 +712,16 @@ void RenderDeferredCleanup::run(const render::RenderContextPointer& renderContex } } +RenderDeferred::RenderDeferred(bool renderShadows): + _renderShadows(renderShadows) +{ + DependencyManager::get()->init(); +} + void RenderDeferred::configure(const Config& config) { } void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs& inputs) { - PROFILE_RANGE(render, "DeferredLighting"); auto deferredTransform = inputs.get0(); auto deferredFramebuffer = inputs.get1(); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 9b55083ad7..96d3f42958 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -167,8 +167,7 @@ public: using Config = RenderDeferredConfig; using JobModel = render::Job::ModelI; - RenderDeferred() {} - RenderDeferred(bool renderShadows) : _renderShadows(renderShadows) {} + RenderDeferred(bool renderShadows = false); void configure(const Config& config); diff --git a/libraries/render-utils/src/LightStage.cpp b/libraries/render-utils/src/LightStage.cpp index ceac4ae3c8..9d6a8e6016 100644 --- a/libraries/render-utils/src/LightStage.cpp +++ b/libraries/render-utils/src/LightStage.cpp @@ -424,10 +424,12 @@ LightStageSetup::LightStageSetup() { } void LightStageSetup::run(const render::RenderContextPointer& renderContext) { - auto stage = renderContext->_scene->getStage(LightStage::getName()); - if (!stage) { - stage = std::make_shared(); - renderContext->_scene->resetStage(LightStage::getName(), stage); + if (renderContext->_scene) { + auto stage = renderContext->_scene->getStage(LightStage::getName()); + if (!stage) { + stage = std::make_shared(); + renderContext->_scene->resetStage(LightStage::getName(), stage); + } } } From f9bd6f5d039eec7c4f797cf6d4a8635d1d1daf36 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 4 Jul 2018 11:34:58 +0200 Subject: [PATCH 004/109] slowly clening up --- interface/src/Application.cpp | 4 ++-- interface/src/graphics/GraphicsEngine.cpp | 2 ++ interface/src/graphics/GraphicsEngine.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 12d5c537d1..dc091f3809 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2536,7 +2536,7 @@ Application::~Application() { // Can't log to file passed this point, FileLogger about to be deleted qInstallMessageHandler(LogHandler::verboseMessageHandler); - _renderEventHandler->deleteLater(); +// _renderEventHandler->deleteLater(); } void Application::initializeGL() { @@ -4178,7 +4178,7 @@ bool Application::shouldPaint() const { // Throttle if requested //if (displayPlugin->isThrottled() && (_graphicsEngine._renderEventHandler->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { - if (displayPlugin->isThrottled() && _graphicsEngine.shouldPaint()) { + if (displayPlugin->isThrottled() && !_graphicsEngine.shouldPaint()) { return false; } diff --git a/interface/src/graphics/GraphicsEngine.cpp b/interface/src/graphics/GraphicsEngine.cpp index af207b988a..eea54c7b8a 100644 --- a/interface/src/graphics/GraphicsEngine.cpp +++ b/interface/src/graphics/GraphicsEngine.cpp @@ -102,6 +102,8 @@ void GraphicsEngine::shutdown() { // shutdown render engine _renderScene = nullptr; _renderEngine = nullptr; + + _renderEventHandler->deleteLater(); } diff --git a/interface/src/graphics/GraphicsEngine.h b/interface/src/graphics/GraphicsEngine.h index 29128daafd..89d1eb1d94 100644 --- a/interface/src/graphics/GraphicsEngine.h +++ b/interface/src/graphics/GraphicsEngine.h @@ -36,7 +36,7 @@ public: bool checkPendingRenderEvent(); private: - // THread specific calls + // Thread specific calls void render_runRenderFrame(RenderArgs* renderArgs); protected: From d2a66b9e7de8a1f4a3a68c95a9de7665ec0e5295 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 4 Jul 2018 17:26:24 +0200 Subject: [PATCH 005/109] Moving the paintGL to a true GraphicsEngine::render_performFrame() --- interface/src/Application.cpp | 19 +- interface/src/Application.h | 29 +- interface/src/Application_render.cpp | 279 +++++++++--------- interface/src/graphics/GraphicsEngine.cpp | 180 +++++++++-- interface/src/graphics/GraphicsEngine.h | 35 +++ interface/src/graphics/RenderEventHandler.cpp | 6 +- interface/src/graphics/RenderEventHandler.h | 6 +- libraries/task/src/task/Config.h | 7 +- libraries/task/src/task/Task.h | 4 +- 9 files changed, 360 insertions(+), 205 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cbe0212a0b..fbba8c5c87 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1886,7 +1886,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto displayPlugin = qApp->getActiveDisplayPlugin(); - properties["render_rate"] = _renderLoopCounter.rate(); + properties["render_rate"] = getRenderLoopRate(); properties["target_render_rate"] = getTargetRenderFrameRate(); properties["present_rate"] = displayPlugin->presentRate(); properties["new_frame_present_rate"] = displayPlugin->newFramePresentRate(); @@ -2900,7 +2900,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) { surfaceContext->setContextProperty("Recording", DependencyManager::get().data()); surfaceContext->setContextProperty("Preferences", DependencyManager::get().data()); surfaceContext->setContextProperty("AddressManager", DependencyManager::get().data()); - surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); + surfaceContext->setContextProperty("FrameTimings", &_graphicsEngine._frameTimingsScriptingInterface); surfaceContext->setContextProperty("Rates", new RatesScriptingInterface(this)); surfaceContext->setContextProperty("TREE_SCALE", TREE_SCALE); @@ -4437,7 +4437,7 @@ void Application::idle() { if (displayPlugin) { PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate()); } - PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, _renderLoopCounter.rate()); + PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, getRenderLoopRate()); PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", int, ResourceCache::getLoadingRequests().length()); PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", int, ResourceCache::getPendingRequestCount()); PROFILE_COUNTER_IF_CHANGED(app, "currentProcessing", int, DependencyManager::get()->getStat("Processing").toInt()); @@ -5382,7 +5382,7 @@ void Application::updateSecondaryCameraViewFrustum() { static bool domainLoadingInProgress = false; void Application::update(float deltaTime) { - PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_renderFrameCount + 1); + PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_graphicsEngine._renderFrameCount + 1); if (!_physicsEnabled) { if (!domainLoadingInProgress) { @@ -5839,7 +5839,7 @@ void Application::update(float deltaTime) { // load the view frustum // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. - myAvatar->preDisplaySide(&_appRenderArgs._renderArgs); +// myAvatar->preDisplaySide(&_appRenderArgs._renderArgs); { @@ -5855,7 +5855,7 @@ void Application::update(float deltaTime) { } void Application::updateRenderArgs(float deltaTime) { - editRenderArgs([this, deltaTime](AppRenderArgs& appRenderArgs) { + _graphicsEngine.editRenderArgs([this, deltaTime](AppRenderArgs& appRenderArgs) { PerformanceTimer perfTimer("editRenderArgs"); appRenderArgs._headPose = getHMDSensorPose(); @@ -5969,6 +5969,13 @@ void Application::updateRenderArgs(float deltaTime) { QMutexLocker viewLocker(&_viewMutex); appRenderArgs._renderArgs.setViewFrustum(_displayViewFrustum); } + + + // HACK + // load the view frustum + // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. + // Then we can move this logic into the Avatar::simulate call. + myAvatar->preDisplaySide(&appRenderArgs._renderArgs); }); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 249c5a723a..6f4b24c434 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -78,7 +78,6 @@ #include #include #include -#include "FrameTimingsScriptingInterface.h" #include "Sound.h" @@ -159,7 +158,7 @@ public: void updateCamera(RenderArgs& renderArgs, float deltaTime); bool shouldPaint() const; - void paintGL(); +// void paintGL(); void resizeGL(); bool event(QEvent* event) override; @@ -208,8 +207,8 @@ public: Overlays& getOverlays() { return _overlays; } - size_t getRenderFrameCount() const { return _renderFrameCount; } - float getRenderLoopRate() const { return _renderLoopCounter.rate(); } + size_t getRenderFrameCount() const { return _graphicsEngine.getRenderFrameCount(); } + float getRenderLoopRate() const { return _graphicsEngine.getRenderLoopRate(); } float getTargetRenderFrameRate() const; // frames/second float getFieldOfView() { return _fieldOfView.get(); } @@ -569,14 +568,10 @@ private: QUndoStack _undoStack; UndoStackScriptingInterface _undoStackScriptingInterface; - uint32_t _renderFrameCount { 0 }; // Frame Rate Measurement - RateCounter<500> _renderLoopCounter; RateCounter<500> _gameLoopCounter; - FrameTimingsScriptingInterface _frameTimingsScriptingInterface; - QTimer _minimizedWindowTimer; QElapsedTimer _timerStart; QElapsedTimer _lastTimeUpdated; @@ -671,24 +666,6 @@ private: GameWorkload _gameWorkload; GraphicsEngine _graphicsEngine; - - mutable QMutex _renderArgsMutex{ QMutex::Recursive }; - struct AppRenderArgs { - render::Args _renderArgs; - glm::mat4 _eyeToWorld; - glm::mat4 _view; - glm::mat4 _eyeOffsets[2]; - glm::mat4 _eyeProjections[2]; - glm::mat4 _headPose; - glm::mat4 _sensorToWorld; - float _sensorToWorldScale { 1.0f }; - bool _isStereo{ false }; - }; - AppRenderArgs _appRenderArgs; - - - using RenderArgsEditor = std::function ; - void editRenderArgs(RenderArgsEditor editor); void updateRenderArgs(float deltaTime); diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index ab38096895..82010fa18f 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -19,151 +19,144 @@ #include "Util.h" -// Statically provided display and input plugins -extern DisplayPluginList getDisplayPlugins(); - -void Application::editRenderArgs(RenderArgsEditor editor) { - QMutexLocker renderLocker(&_renderArgsMutex); - editor(_appRenderArgs); - -} - -void Application::paintGL() { - // Some plugins process message events, allowing paintGL to be called reentrantly. - - _renderFrameCount++; - // SG: Moved into the RenderEventHandler - //_lastTimeRendered.start(); - - auto lastPaintBegin = usecTimestampNow(); - PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_renderFrameCount); - PerformanceTimer perfTimer("paintGL"); - - if (nullptr == _displayPlugin) { - return; - } - - DisplayPluginPointer displayPlugin; - { - PROFILE_RANGE(render, "/getActiveDisplayPlugin"); - displayPlugin = getActiveDisplayPlugin(); - } - - { - PROFILE_RANGE(render, "/pluginBeginFrameRender"); - // If a display plugin loses it's underlying support, it - // needs to be able to signal us to not use it - if (!displayPlugin->beginFrameRender(_renderFrameCount)) { - QMetaObject::invokeMethod(this, "updateDisplayMode"); - return; - } - } - - RenderArgs renderArgs; - glm::mat4 HMDSensorPose; - glm::mat4 eyeToWorld; - glm::mat4 sensorToWorld; - - bool isStereo; - glm::mat4 stereoEyeOffsets[2]; - glm::mat4 stereoEyeProjections[2]; - - { - QMutexLocker viewLocker(&_renderArgsMutex); - renderArgs = _appRenderArgs._renderArgs; - - // don't render if there is no context. - if (!_appRenderArgs._renderArgs._context) { - return; - } - - HMDSensorPose = _appRenderArgs._headPose; - eyeToWorld = _appRenderArgs._eyeToWorld; - sensorToWorld = _appRenderArgs._sensorToWorld; - isStereo = _appRenderArgs._isStereo; - for_each_eye([&](Eye eye) { - stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; - stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; - }); - } - - { - PROFILE_RANGE(render, "/gpuContextReset"); - _graphicsEngine.getGPUContext()->beginFrame(_appRenderArgs._view, HMDSensorPose); - // Reset the gpu::Context Stages - // Back to the default framebuffer; - gpu::doInBatch("Application_render::gpuContextReset", _graphicsEngine.getGPUContext(), [&](gpu::Batch& batch) { - batch.resetStages(); - }); - } - { - PROFILE_RANGE(render, "/renderOverlay"); - PerformanceTimer perfTimer("renderOverlay"); - // NOTE: There is no batch associated with this renderArgs - // the ApplicationOverlay class assumes it's viewport is setup to be the device size - renderArgs._viewport = glm::ivec4(0, 0, getDeviceSize() * getRenderResolutionScale()); - _applicationOverlay.renderOverlay(&renderArgs); - } - - { - PROFILE_RANGE(render, "/updateCompositor"); - getApplicationCompositor().setFrameInfo(_renderFrameCount, eyeToWorld, sensorToWorld); - } - - gpu::FramebufferPointer finalFramebuffer; - QSize finalFramebufferSize; - { - PROFILE_RANGE(render, "/getOutputFramebuffer"); - // Primary rendering pass - auto framebufferCache = DependencyManager::get(); - finalFramebufferSize = framebufferCache->getFrameBufferSize(); - // Final framebuffer that will be handled to the display-plugin - finalFramebuffer = framebufferCache->getFramebuffer(); - } - - { - if (isStereo) { - renderArgs._context->enableStereo(true); - renderArgs._context->setStereoProjections(stereoEyeProjections); - renderArgs._context->setStereoViews(stereoEyeOffsets); - } - - renderArgs._hudOperator = displayPlugin->getHUDOperator(); - renderArgs._hudTexture = _applicationOverlay.getOverlayTexture(); - renderArgs._blitFramebuffer = finalFramebuffer; - _graphicsEngine.render_runRenderFrame(&renderArgs); - } - - auto frame = _graphicsEngine.getGPUContext()->endFrame(); - frame->frameIndex = _renderFrameCount; - frame->framebuffer = finalFramebuffer; - frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) { - auto frameBufferCache = DependencyManager::get(); - if (frameBufferCache) { - frameBufferCache->releaseFramebuffer(framebuffer); - } - }; - // deliver final scene rendering commands to the display plugin - { - PROFILE_RANGE(render, "/pluginOutput"); - PerformanceTimer perfTimer("pluginOutput"); - _renderLoopCounter.increment(); - displayPlugin->submitFrame(frame); - } - - // Reset the framebuffer and stereo state - renderArgs._blitFramebuffer.reset(); - renderArgs._context->enableStereo(false); - - { - Stats::getInstance()->setRenderDetails(renderArgs._details); - } - - uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; - _frameTimingsScriptingInterface.addValue(lastPaintDuration); -} +//void Application::paintGL() { +// // Some plugins process message events, allowing paintGL to be called reentrantly. +// +// _renderFrameCount++; +// // SG: Moved into the RenderEventHandler +// //_lastTimeRendered.start(); +// +// auto lastPaintBegin = usecTimestampNow(); +// PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_renderFrameCount); +// PerformanceTimer perfTimer("paintGL"); +// +// if (nullptr == _displayPlugin) { +// return; +// } +// +// DisplayPluginPointer displayPlugin; +// { +// PROFILE_RANGE(render, "/getActiveDisplayPlugin"); +// displayPlugin = getActiveDisplayPlugin(); +// } +// +// { +// PROFILE_RANGE(render, "/pluginBeginFrameRender"); +// // If a display plugin loses it's underlying support, it +// // needs to be able to signal us to not use it +// if (!displayPlugin->beginFrameRender(_renderFrameCount)) { +// QMetaObject::invokeMethod(this, "updateDisplayMode"); +// return; +// } +// } +// +// RenderArgs renderArgs; +// glm::mat4 HMDSensorPose; +// glm::mat4 eyeToWorld; +// glm::mat4 sensorToWorld; +// +// bool isStereo; +// glm::mat4 stereoEyeOffsets[2]; +// glm::mat4 stereoEyeProjections[2]; +// +// { +// QMutexLocker viewLocker(&_renderArgsMutex); +// renderArgs = _appRenderArgs._renderArgs; +// +// // don't render if there is no context. +// if (!_appRenderArgs._renderArgs._context) { +// return; +// } +// +// HMDSensorPose = _appRenderArgs._headPose; +// eyeToWorld = _appRenderArgs._eyeToWorld; +// sensorToWorld = _appRenderArgs._sensorToWorld; +// isStereo = _appRenderArgs._isStereo; +// for_each_eye([&](Eye eye) { +// stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; +// stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; +// }); +// } +// +// { +// PROFILE_RANGE(render, "/gpuContextReset"); +// _graphicsEngine.getGPUContext()->beginFrame(_appRenderArgs._view, HMDSensorPose); +// // Reset the gpu::Context Stages +// // Back to the default framebuffer; +// gpu::doInBatch("Application_render::gpuContextReset", _graphicsEngine.getGPUContext(), [&](gpu::Batch& batch) { +// batch.resetStages(); +// }); +// } +// +// +// { +// PROFILE_RANGE(render, "/renderOverlay"); +// PerformanceTimer perfTimer("renderOverlay"); +// // NOTE: There is no batch associated with this renderArgs +// // the ApplicationOverlay class assumes it's viewport is setup to be the device size +// renderArgs._viewport = glm::ivec4(0, 0, getDeviceSize() * getRenderResolutionScale()); +// _applicationOverlay.renderOverlay(&renderArgs); +// } +// +// { +// PROFILE_RANGE(render, "/updateCompositor"); +// getApplicationCompositor().setFrameInfo(_renderFrameCount, eyeToWorld, sensorToWorld); +// } +// +// gpu::FramebufferPointer finalFramebuffer; +// QSize finalFramebufferSize; +// { +// PROFILE_RANGE(render, "/getOutputFramebuffer"); +// // Primary rendering pass +// auto framebufferCache = DependencyManager::get(); +// finalFramebufferSize = framebufferCache->getFrameBufferSize(); +// // Final framebuffer that will be handled to the display-plugin +// finalFramebuffer = framebufferCache->getFramebuffer(); +// } +// +// { +// if (isStereo) { +// renderArgs._context->enableStereo(true); +// renderArgs._context->setStereoProjections(stereoEyeProjections); +// renderArgs._context->setStereoViews(stereoEyeOffsets); +// } +// +// renderArgs._hudOperator = displayPlugin->getHUDOperator(); +// renderArgs._hudTexture = _applicationOverlay.getOverlayTexture(); +// renderArgs._blitFramebuffer = finalFramebuffer; +// _graphicsEngine.render_runRenderFrame(&renderArgs); +// } +// +// auto frame = _graphicsEngine.getGPUContext()->endFrame(); +// frame->frameIndex = _renderFrameCount; +// frame->framebuffer = finalFramebuffer; +// frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) { +// auto frameBufferCache = DependencyManager::get(); +// if (frameBufferCache) { +// frameBufferCache->releaseFramebuffer(framebuffer); +// } +// }; +// // deliver final scene rendering commands to the display plugin +// { +// PROFILE_RANGE(render, "/pluginOutput"); +// PerformanceTimer perfTimer("pluginOutput"); +// _renderLoopCounter.increment(); +// displayPlugin->submitFrame(frame); +// } +// +// // Reset the framebuffer and stereo state +// renderArgs._blitFramebuffer.reset(); +// renderArgs._context->enableStereo(false); +// +// { +// Stats::getInstance()->setRenderDetails(renderArgs._details); +// } +// +// uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; +// _frameTimingsScriptingInterface.addValue(lastPaintDuration); +//} // WorldBox Render Data & rendering functions diff --git a/interface/src/graphics/GraphicsEngine.cpp b/interface/src/graphics/GraphicsEngine.cpp index eea54c7b8a..f256b0dfb5 100644 --- a/interface/src/graphics/GraphicsEngine.cpp +++ b/interface/src/graphics/GraphicsEngine.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -25,6 +26,12 @@ #include #include #include +#include + +#include +#include +#include "ui/Stats.h" +#include "Application.h" GraphicsEngine::GraphicsEngine() { } @@ -44,7 +51,11 @@ void GraphicsEngine::initializeGPU(GLWidget* glwidget) { _offscreenContext->doneCurrent(); _offscreenContext->setThreadContext(); - _renderEventHandler = new RenderEventHandler(glwidget->qglContext()); + _renderEventHandler = new RenderEventHandler( + glwidget->qglContext(), + [this]() { this->render_performFrame(); } + ); + if (!_offscreenContext->makeCurrent()) { qFatal("Unable to make offscreen context current"); } @@ -84,8 +95,6 @@ void GraphicsEngine::initializeRender(bool disableDeferred) { } void GraphicsEngine::startup() { - - static_cast(_renderEventHandler)->resumeThread(); } @@ -110,27 +119,12 @@ void GraphicsEngine::shutdown() { void GraphicsEngine::render_runRenderFrame(RenderArgs* renderArgs) { PROFILE_RANGE(render, __FUNCTION__); PerformanceTimer perfTimer("render"); -// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); - - // The pending changes collecting the changes here - render::Transaction transaction; - - // this is not in use at all anymore - //if (DependencyManager::get()->shouldRenderEntities()) { - // render models... - // PerformanceTimer perfTimer("entities"); - // PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - // "Application::runRenderFrame() ... entities..."); - - //RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; - - //renderArgs->_debugFlags = renderDebugFlags; - //} // Make sure the WorldBox is in the scene // For the record, this one RenderItem is the first one we created and added to the scene. // We could move that code elsewhere but you know... if (!render::Item::isValidID(WorldBoxRenderData::_item)) { + render::Transaction transaction; auto worldBoxRenderData = std::make_shared(); auto worldBoxRenderPayload = std::make_shared(worldBoxRenderData); @@ -141,7 +135,6 @@ void GraphicsEngine::render_runRenderFrame(RenderArgs* renderArgs) { } { - // PerformanceTimer perfTimer("EngineRun"); _renderEngine->getRenderContext()->args = renderArgs; _renderEngine->run(); } @@ -154,7 +147,6 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI bool GraphicsEngine::shouldPaint() const { - // Throttle if requested if ((static_cast(_renderEventHandler)->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { return false; @@ -167,3 +159,149 @@ bool GraphicsEngine::checkPendingRenderEvent() { bool expected = false; return (_renderEventHandler && static_cast(_renderEventHandler)->_pendingRenderEvent.compare_exchange_strong(expected, true)); } + + + +void GraphicsEngine::render_performFrame() { + // Some plugins process message events, allowing paintGL to be called reentrantly. + + _renderFrameCount++; + // SG: Moved into the RenderEventHandler + //_lastTimeRendered.start(); + + auto lastPaintBegin = usecTimestampNow(); + PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_renderFrameCount); + PerformanceTimer perfTimer("paintGL"); + + /* if (nullptr == _displayPlugin) { + return; + }*/ + + DisplayPluginPointer displayPlugin; + { + PROFILE_RANGE(render, "/getActiveDisplayPlugin"); + displayPlugin = qApp->getActiveDisplayPlugin(); + } + + { + PROFILE_RANGE(render, "/pluginBeginFrameRender"); + // If a display plugin loses it's underlying support, it + // needs to be able to signal us to not use it + if (!displayPlugin->beginFrameRender(_renderFrameCount)) { + QMetaObject::invokeMethod(qApp, "updateDisplayMode"); + return; + } + } + + RenderArgs renderArgs; + glm::mat4 HMDSensorPose; + glm::mat4 eyeToWorld; + glm::mat4 sensorToWorld; + + bool isStereo; + glm::mat4 stereoEyeOffsets[2]; + glm::mat4 stereoEyeProjections[2]; + + { + QMutexLocker viewLocker(&_renderArgsMutex); + renderArgs = _appRenderArgs._renderArgs; + + // don't render if there is no context. + if (!_appRenderArgs._renderArgs._context) { + return; + } + + HMDSensorPose = _appRenderArgs._headPose; + eyeToWorld = _appRenderArgs._eyeToWorld; + sensorToWorld = _appRenderArgs._sensorToWorld; + isStereo = _appRenderArgs._isStereo; + for_each_eye([&](Eye eye) { + stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; + stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; + }); + } + + { + PROFILE_RANGE(render, "/gpuContextReset"); + getGPUContext()->beginFrame(_appRenderArgs._view, HMDSensorPose); + // Reset the gpu::Context Stages + // Back to the default framebuffer; + gpu::doInBatch("Application_render::gpuContextReset", getGPUContext(), [&](gpu::Batch& batch) { + batch.resetStages(); + }); + } + + + { + PROFILE_RANGE(render, "/renderOverlay"); + PerformanceTimer perfTimer("renderOverlay"); + // NOTE: There is no batch associated with this renderArgs + // the ApplicationOverlay class assumes it's viewport is setup to be the device size + renderArgs._viewport = glm::ivec4(0, 0, qApp->getDeviceSize() * qApp->getRenderResolutionScale()); + qApp->getApplicationOverlay().renderOverlay(&renderArgs); + } + + { + PROFILE_RANGE(render, "/updateCompositor"); + qApp->getApplicationCompositor().setFrameInfo(_renderFrameCount, eyeToWorld, sensorToWorld); + } + + gpu::FramebufferPointer finalFramebuffer; + QSize finalFramebufferSize; + { + PROFILE_RANGE(render, "/getOutputFramebuffer"); + // Primary rendering pass + auto framebufferCache = DependencyManager::get(); + finalFramebufferSize = framebufferCache->getFrameBufferSize(); + // Final framebuffer that will be handled to the display-plugin + finalFramebuffer = framebufferCache->getFramebuffer(); + } + + { + if (isStereo) { + renderArgs._context->enableStereo(true); + renderArgs._context->setStereoProjections(stereoEyeProjections); + renderArgs._context->setStereoViews(stereoEyeOffsets); + } + + renderArgs._hudOperator = displayPlugin->getHUDOperator(); + renderArgs._hudTexture = qApp->getApplicationOverlay().getOverlayTexture(); + renderArgs._blitFramebuffer = finalFramebuffer; + render_runRenderFrame(&renderArgs); + } + + auto frame = getGPUContext()->endFrame(); + frame->frameIndex = _renderFrameCount; + frame->framebuffer = finalFramebuffer; + frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) { + auto frameBufferCache = DependencyManager::get(); + if (frameBufferCache) { + frameBufferCache->releaseFramebuffer(framebuffer); + } + }; + // deliver final scene rendering commands to the display plugin + { + PROFILE_RANGE(render, "/pluginOutput"); + PerformanceTimer perfTimer("pluginOutput"); + _renderLoopCounter.increment(); + displayPlugin->submitFrame(frame); + } + + // Reset the framebuffer and stereo state + renderArgs._blitFramebuffer.reset(); + renderArgs._context->enableStereo(false); + + { + Stats::getInstance()->setRenderDetails(renderArgs._details); + } + + uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; + _frameTimingsScriptingInterface.addValue(lastPaintDuration); +} + + +void GraphicsEngine::editRenderArgs(RenderArgsEditor editor) { + QMutexLocker renderLocker(&_renderArgsMutex); + editor(_appRenderArgs); + +} \ No newline at end of file diff --git a/interface/src/graphics/GraphicsEngine.h b/interface/src/graphics/GraphicsEngine.h index 89d1eb1d94..780b4020d2 100644 --- a/interface/src/graphics/GraphicsEngine.h +++ b/interface/src/graphics/GraphicsEngine.h @@ -12,10 +12,30 @@ #include #include +#include #include #include +#include + +#include "FrameTimingsScriptingInterface.h" + + +struct AppRenderArgs { + render::Args _renderArgs; + glm::mat4 _eyeToWorld; + glm::mat4 _view; + glm::mat4 _eyeOffsets[2]; + glm::mat4 _eyeProjections[2]; + glm::mat4 _headPose; + glm::mat4 _sensorToWorld; + float _sensorToWorldScale{ 1.0f }; + bool _isStereo{ false }; +}; + +using RenderArgsEditor = std::function ; + class GraphicsEngine { public: @@ -35,12 +55,25 @@ public: bool shouldPaint() const; bool checkPendingRenderEvent(); + size_t getRenderFrameCount() const { return _renderFrameCount; } + float getRenderLoopRate() const { return _renderLoopCounter.rate(); } + + // Feed GRaphics Engine with new frame configuration + void editRenderArgs(RenderArgsEditor editor); + private: // Thread specific calls + void render_performFrame(); void render_runRenderFrame(RenderArgs* renderArgs); protected: + mutable QMutex _renderArgsMutex{ QMutex::Recursive }; + AppRenderArgs _appRenderArgs; + + RateCounter<500> _renderLoopCounter; + + uint32_t _renderFrameCount{ 0 }; render::ScenePointer _renderScene{ new render::Scene(glm::vec3(-0.5f * (float)TREE_SCALE), (float)TREE_SCALE) }; render::EnginePointer _renderEngine{ new render::RenderEngine() }; @@ -51,6 +84,8 @@ protected: OffscreenGLCanvas* _offscreenContext{ nullptr }; + FrameTimingsScriptingInterface _frameTimingsScriptingInterface; + friend class Application; }; diff --git a/interface/src/graphics/RenderEventHandler.cpp b/interface/src/graphics/RenderEventHandler.cpp index 0ca82201d5..95e931ebd8 100644 --- a/interface/src/graphics/RenderEventHandler.cpp +++ b/interface/src/graphics/RenderEventHandler.cpp @@ -15,7 +15,9 @@ #include "CrashHandler.h" -RenderEventHandler::RenderEventHandler(QOpenGLContext* context) { +RenderEventHandler::RenderEventHandler(QOpenGLContext* context, RenderCall renderCall) : + _renderCall(renderCall) +{ _renderContext = new OffscreenGLCanvas(); _renderContext->setObjectName("RenderContext"); _renderContext->create(context); @@ -52,7 +54,7 @@ void RenderEventHandler::resumeThread() { void RenderEventHandler::render() { if (qApp->shouldPaint()) { _lastTimeRendered.start(); - qApp->paintGL(); + _renderCall(); } } diff --git a/interface/src/graphics/RenderEventHandler.h b/interface/src/graphics/RenderEventHandler.h index 8b0e4c5e15..913898eb7f 100644 --- a/interface/src/graphics/RenderEventHandler.h +++ b/interface/src/graphics/RenderEventHandler.h @@ -27,7 +27,11 @@ class RenderEventHandler : public QObject { using Parent = QObject; Q_OBJECT public: - RenderEventHandler(QOpenGLContext* context); + + using RenderCall = std::function ; + RenderCall _renderCall; + + RenderEventHandler(QOpenGLContext* context, RenderCall renderCall); QElapsedTimer _lastTimeRendered; std::atomic _pendingRenderEvent{ true }; diff --git a/libraries/task/src/task/Config.h b/libraries/task/src/task/Config.h index 1ebc6aa967..0ecfa9bfd7 100644 --- a/libraries/task/src/task/Config.h +++ b/libraries/task/src/task/Config.h @@ -50,10 +50,10 @@ public: _default = toJsonValue(*this).toObject().toVariantMap(); _presets.unite(list.toVariantMap()); - if (C::alwaysEnabled || C::enabled) { + if (C::enabled) { _presets.insert(DEFAULT, _default); } - if (!C::alwaysEnabled) { + if (false) { //!C::alwaysEnabled) { _presets.insert(NONE, QVariantMap{{ "enabled", false }}); } @@ -96,12 +96,11 @@ public: using Persistent = PersistentConfig; JobConfig() = default; - JobConfig(bool enabled) : alwaysEnabled{ false }, enabled{ enabled } {} + JobConfig(bool enabled): enabled{ enabled } {} bool isEnabled() { return /*alwaysEnabled ||*/ enabled; } void setEnabled(bool enable) { enabled = /*alwaysEnabled ||*/ enable; emit dirtyEnabled(); } - bool alwaysEnabled{ false }; bool enabled{ true }; virtual void setPresetList(const QJsonObject& object); diff --git a/libraries/task/src/task/Task.h b/libraries/task/src/task/Task.h index 60ccd26b70..c15c0ceb13 100644 --- a/libraries/task/src/task/Task.h +++ b/libraries/task/src/task/Task.h @@ -164,7 +164,7 @@ public: void run(const ContextPointer& jobContext) override { jobContext->jobConfig = std::static_pointer_cast(Concept::_config); - if (jobContext->jobConfig->alwaysEnabled || jobContext->jobConfig->isEnabled()) { + if (/*jobContext->jobConfig->alwaysEnabled || */jobContext->jobConfig->isEnabled()) { jobRun(_data, jobContext, _input.get(), _output.edit()); } jobContext->jobConfig.reset(); @@ -339,7 +339,7 @@ public: void run(const ContextPointer& jobContext) override { auto config = std::static_pointer_cast(Concept::_config); - if (config->alwaysEnabled || config->enabled) { + if (config->enabled) { for (auto job : TaskConcept::_jobs) { job.run(jobContext); if (jobContext->taskFlow.doAbortTask()) { From 2eec5b01fa69874c580fb49febe32dbe16d7c41f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 6 Jul 2018 10:53:09 +0200 Subject: [PATCH 006/109] debugging and fixing the problem to get Config for complex path --- interface/src/Application.cpp | 6 ++--- libraries/task/src/task/Config.h | 23 ++++++++++++++----- .../utilities/lib/jet/qml/TaskListView.qml | 15 ++++++------ .../utilities/render/engineInspector.qml | 8 +++---- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fbba8c5c87..487fafe2df 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4444,7 +4444,7 @@ void Application::idle() { PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get()->getStat("PendingProcessing").toInt()); auto renderConfig = _graphicsEngine.getRenderEngine()->getConfiguration(); PROFILE_COUNTER_IF_CHANGED(render, "gpuTime", float, (float)_graphicsEngine.getGPUContext()->getFrameTimerGPUAverage()); - auto opaqueRangeTimer = renderConfig->getConfig("OpaqueRangeTimer"); +/* auto opaqueRangeTimer = renderConfig->getConfig("OpaqueRangeTimer"); auto linearDepth = renderConfig->getConfig("LinearDepth"); auto surfaceGeometry = renderConfig->getConfig("SurfaceGeometry"); auto renderDeferred = renderConfig->getConfig("RenderDeferred"); @@ -4456,7 +4456,7 @@ void Application::idle() { { "SurfaceGeometry", surfaceGeometry ? surfaceGeometry->property("gpuRunTime") : 0 }, { "RenderDeferred", renderDeferred ? renderDeferred->property("gpuRunTime") : 0 }, { "ToneAndPostRangeTimer", toneAndPostRangeTimer ? toneAndPostRangeTimer->property("gpuRunTime") : 0 } - }); + });*/ PROFILE_RANGE(app, __FUNCTION__); @@ -5759,7 +5759,7 @@ void Application::update(float deltaTime) { // TODO: Fix this by modeling the way the secondary camera works on how the main camera works // ie. Use a camera object stored in the game logic and informs the Engine on where the secondary // camera should be. - updateSecondaryCameraViewFrustum(); + // updateSecondaryCameraViewFrustum(); } quint64 now = usecTimestampNow(); diff --git a/libraries/task/src/task/Config.h b/libraries/task/src/task/Config.h index 0ecfa9bfd7..4a9414fd42 100644 --- a/libraries/task/src/task/Config.h +++ b/libraries/task/src/task/Config.h @@ -219,30 +219,41 @@ public: // optional sub_parent_names and finally from there looking for the job_name (assuming every job in the path were found) // // getter for qml integration, prefer the templated getter +#pragma optimize("", off) Q_INVOKABLE QObject* getConfig(const QString& name) { return getConfig(name.toStdString()); } // getter for cpp (strictly typed), prefer this getter template typename T::Config* getConfig(std::string job = "") const { const TaskConfig* root = this; - QString path = (job.empty() ? QString() : QString(job.c_str())); // an empty string is not a null string - auto tokens = path.split('.', QString::SkipEmptyParts); + std::string jobPath = (job); + //QString path = (job.empty() ? QString() : QString(job.c_str())); // an empty string is not a null string + //auto tokens = path.split('.', QString::SkipEmptyParts); + std::list tokens; + std::size_t pos = 0, found; + while ((found = jobPath.find_first_of('.', pos)) != std::string::npos) { + tokens.push_back(jobPath.substr(pos, found - pos)); + pos = found + 1; + } + tokens.push_back(jobPath.substr(pos)); + QString jobToken; if (tokens.empty()) { // return dynamic_cast(const_cast (root)); - tokens.push_back(QString()); + //tokens.push_back(std::string()); } else { while (tokens.size() > 1) { auto name = tokens.front(); tokens.pop_front(); - root = QObject::findChild(name); + root = root->findChild((name.empty() ? QString() : QString(name.c_str()))); if (!root) { return nullptr; } } + jobToken = QString(tokens.front().c_str()); } - return root->findChild(tokens.front()); + return root->findChild(jobToken); } - +#pragma optimize("", on) Q_INVOKABLE bool isTask() const override { return true; } Q_INVOKABLE QObjectList getSubConfigs() const override { auto list = findChildren(QRegExp(".*"), Qt::FindDirectChildrenOnly); diff --git a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml index 7c077f495a..f8997dfaf4 100644 --- a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml +++ b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml @@ -27,29 +27,29 @@ Rectangle { Component.onCompleted: { //var functor = Jet.job_tree_model_functor(jobsModel) - /* var functor = Jet.job_tree_model_functor(jobsModel, 1, function(node) { + var functor = Jet.job_tree_model_functor(jobsModel, 3, function(node) { node["cpuT"] = 0.0 }) Jet.task_traverseTree(rootConfig, functor); - */ + - var tfunctor = Jet.job_tree_model_array_functor(jobsModel.engineJobItemModel, function(node) { + /* var tfunctor = Jet.job_tree_model_array_functor(jobsModel.engineJobItemModel, function(node) { node["init"] = (node.level < 3) node["fullpath"] = (node.path + "." + node.name) node["cpuT"] = 0.0 }) Jet.task_traverseTree(rootConfig, tfunctor); - +*/ // var currentParentStach = [] // currentParentStach.push(jobsModel); - Jet.job_traverseTreeNodeRoot(jobsModel.engineJobItemModel[0], function(node, depth, index) { + /* Jet.job_traverseTreeNodeRoot(jobsModel.engineJobItemModel[0], function(node, depth, index) { print(node.name + depth + " - " + index) return true - }) + })*/ } @@ -64,8 +64,7 @@ Rectangle { id: objRecursiveColumn clip: true visible: model.init - // visible: (node.level < 2) - + function switchFold() { for(var i = 1; i < children.length - 1; ++i) { children[i].visible = !children[i].visible diff --git a/scripts/developer/utilities/render/engineInspector.qml b/scripts/developer/utilities/render/engineInspector.qml index d3bd2e96fd..7a2dfcc9e2 100644 --- a/scripts/developer/utilities/render/engineInspector.qml +++ b/scripts/developer/utilities/render/engineInspector.qml @@ -24,13 +24,13 @@ Item { property var mainViewTask: Render.getConfig("RenderMainView") - Jet.TaskTimeFrameView { + /* Jet.TaskTimeFrameView { rootConfig: Render anchors.fill: render - } - /* Jet.TaskListView { + }*/ + Jet.TaskListView { rootConfig: Render anchors.fill: render - } */ + } } \ No newline at end of file From 07299291fca218aea3167950227362d5af2ba23d Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 6 Jul 2018 19:29:06 +0200 Subject: [PATCH 007/109] clarifying the engine inspector and engine profiler --- interface/src/SecondaryCamera.cpp | 2 +- libraries/task/src/task/Config.cpp | 54 +++++++++++++++++ libraries/task/src/task/Config.h | 37 ++---------- .../utilities/lib/jet/qml/TaskListView.qml | 2 +- .../lib/jet/qml/TaskTimeFrameView.qml | 2 +- .../utilities/render/deferredLighting.qml | 19 ++++-- .../utilities/render/engineInspector.js | 2 +- .../utilities/render/engineInspector.qml | 20 +++---- .../utilities/render/engineProfiler.js | 59 +++++++++++++++++++ .../utilities/render/engineProfiler.qml | 31 ++++++++++ scripts/developer/utilities/render/luci.js | 32 ++++++++-- 11 files changed, 202 insertions(+), 58 deletions(-) create mode 100644 scripts/developer/utilities/render/engineProfiler.js create mode 100644 scripts/developer/utilities/render/engineProfiler.qml diff --git a/interface/src/SecondaryCamera.cpp b/interface/src/SecondaryCamera.cpp index a940aab4db..184762632f 100644 --- a/interface/src/SecondaryCamera.cpp +++ b/interface/src/SecondaryCamera.cpp @@ -171,7 +171,7 @@ void SecondaryCameraJobConfig::setOrientation(glm::quat orient) { } void SecondaryCameraJobConfig::enableSecondaryCameraRenderConfigs(bool enabled) { - qApp->getRenderEngine()->getConfiguration()->getConfig()->setEnabled(enabled); + qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCameraJob")->setEnabled(enabled); setEnabled(enabled); } diff --git a/libraries/task/src/task/Config.cpp b/libraries/task/src/task/Config.cpp index b378237c9c..ac7105be29 100644 --- a/libraries/task/src/task/Config.cpp +++ b/libraries/task/src/task/Config.cpp @@ -68,3 +68,57 @@ void TaskConfig::refresh() { _task->applyConfiguration(); } +TaskConfig* TaskConfig::getRootConfig(const std::string& jobPath, std::string& jobName) const { + TaskConfig* root = const_cast (this); + + std::list tokens; + std::size_t pos = 0, sepPos; + while ((sepPos = jobPath.find_first_of('.', pos)) != std::string::npos) { + std::string token = jobPath.substr(pos, sepPos - pos); + if (!token.empty()) { + tokens.push_back(token); + } + pos = sepPos + 1; + } + { + std::string token = jobPath.substr(pos, sepPos - pos); + if (!token.empty()) { + tokens.push_back(token); + } + } + + if (tokens.empty()) { + return root; + } + else { + while (tokens.size() > 1) { + auto taskName = tokens.front(); + tokens.pop_front(); + root = root->findChild((taskName.empty() ? QString() : QString(taskName.c_str()))); + if (!root) { + return nullptr; + } + } + jobName = tokens.front(); + } + return root; +} + +JobConfig* TaskConfig::getJobConfig(const std::string& jobPath) const { + std::string jobName; + auto root = getRootConfig(jobPath, jobName); + + if (!root) { + return nullptr; + } + if (jobName.empty()) { + return root; + } else { + + auto found = root->findChild((jobName.empty() ? QString() : QString(jobName.c_str()))); + if (!found) { + return nullptr; + } + return found; + } +} diff --git a/libraries/task/src/task/Config.h b/libraries/task/src/task/Config.h index 4a9414fd42..b76c57521f 100644 --- a/libraries/task/src/task/Config.h +++ b/libraries/task/src/task/Config.h @@ -219,41 +219,16 @@ public: // optional sub_parent_names and finally from there looking for the job_name (assuming every job in the path were found) // // getter for qml integration, prefer the templated getter -#pragma optimize("", off) Q_INVOKABLE QObject* getConfig(const QString& name) { return getConfig(name.toStdString()); } + // getter for cpp (strictly typed), prefer this getter - template typename T::Config* getConfig(std::string job = "") const { - const TaskConfig* root = this; - std::string jobPath = (job); - //QString path = (job.empty() ? QString() : QString(job.c_str())); // an empty string is not a null string - //auto tokens = path.split('.', QString::SkipEmptyParts); - std::list tokens; - std::size_t pos = 0, found; - while ((found = jobPath.find_first_of('.', pos)) != std::string::npos) { - tokens.push_back(jobPath.substr(pos, found - pos)); - pos = found + 1; - } - tokens.push_back(jobPath.substr(pos)); + TaskConfig* getRootConfig(const std::string& jobPath, std::string& jobName) const; + JobConfig* getJobConfig(const std::string& jobPath) const; - QString jobToken; - if (tokens.empty()) { - // return dynamic_cast(const_cast (root)); - //tokens.push_back(std::string()); - } else { - while (tokens.size() > 1) { - auto name = tokens.front(); - tokens.pop_front(); - root = root->findChild((name.empty() ? QString() : QString(name.c_str()))); - if (!root) { - return nullptr; - } - } - jobToken = QString(tokens.front().c_str()); - } - - return root->findChild(jobToken); + template typename T::Config* getConfig(std::string jobPath = "") const { + return dynamic_cast(getJobConfig(jobPath)); } -#pragma optimize("", on) + Q_INVOKABLE bool isTask() const override { return true; } Q_INVOKABLE QObjectList getSubConfigs() const override { auto list = findChildren(QRegExp(".*"), Qt::FindDirectChildrenOnly); diff --git a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml index f8997dfaf4..1229ef7dc7 100644 --- a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml +++ b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml @@ -19,7 +19,7 @@ import "../jet.js" as Jet Rectangle { HifiConstants { id: hifi;} - color: hifi.colors.baseGray; + // color: hifi.colors.baseGray; id: root; property var rootConfig : Workload diff --git a/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml b/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml index 4eca5075d0..267344fca5 100644 --- a/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml +++ b/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml @@ -19,7 +19,7 @@ import "../jet.js" as Jet Rectangle { HifiConstants { id: hifi;} - color: hifi.colors.baseGray; + // color: hifi.colors.baseGray; id: root; property var rootConfig : Workload diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 8a4a8f0622..abb15d5a38 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -277,11 +277,20 @@ Rectangle { } } Separator {} - HifiControls.Button { - text: "Engine" - // activeFocusOnPress: false - onClicked: { - sendToScript({method: "openEngineView"}); + Row { + HifiControls.Button { + text: "Inspector" + // activeFocusOnPress: false + onClicked: { + sendToScript({method: "openEngineInspector"}); + } + } + HifiControls.Button { + text: "EnProfilergine" + // activeFocusOnPress: false + onClicked: { + sendToScript({method: "openEngineProfiler"}); + } } } } diff --git a/scripts/developer/utilities/render/engineInspector.js b/scripts/developer/utilities/render/engineInspector.js index e6be7f1c3c..868a421c8d 100644 --- a/scripts/developer/utilities/render/engineInspector.js +++ b/scripts/developer/utilities/render/engineInspector.js @@ -47,7 +47,7 @@ function createWindow() { var qml = Script.resolvePath(QMLAPP_URL); window = new OverlayWindow({ - title: 'Render Engine', + title: 'Render Engine Inspector', source: qml, width: 500, height: 100 diff --git a/scripts/developer/utilities/render/engineInspector.qml b/scripts/developer/utilities/render/engineInspector.qml index 7a2dfcc9e2..52a9879038 100644 --- a/scripts/developer/utilities/render/engineInspector.qml +++ b/scripts/developer/utilities/render/engineInspector.qml @@ -1,7 +1,7 @@ // -// deferredLighting.qml +// EngineInspector.qml // -// Created by Sam Gateau on 6/6/2016 +// Created by Sam Gateau on 06/07/2018 // Copyright 2016 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -18,19 +18,13 @@ import "../lib/jet/qml" as Jet Item { HifiConstants { id: hifi;} - id: render; + id: root; anchors.fill: parent - property var mainViewTask: Render.getConfig("RenderMainView") + property var rootConfig: Render.getConfig("RenderMainView") - - /* Jet.TaskTimeFrameView { - rootConfig: Render - anchors.fill: render - }*/ Jet.TaskListView { - rootConfig: Render - anchors.fill: render - } - + rootConfig: root.rootConfig + anchors.fill: root + } } \ No newline at end of file diff --git a/scripts/developer/utilities/render/engineProfiler.js b/scripts/developer/utilities/render/engineProfiler.js new file mode 100644 index 0000000000..b9443da1e9 --- /dev/null +++ b/scripts/developer/utilities/render/engineProfiler.js @@ -0,0 +1,59 @@ + + + (function() { + var TABLET_BUTTON_NAME = "Render Engine Profiler"; + var QMLAPP_URL = Script.resolvePath("./engineProfiler.qml"); + var ICON_URL = Script.resolvePath("../../../system/assets/images/lod-i.svg"); + var ACTIVE_ICON_URL = Script.resolvePath("../../../system/assets/images/lod-a.svg"); + + var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + var button = tablet.addButton({ + text: TABLET_BUTTON_NAME, + icon: ICON_URL, + activeIcon: ACTIVE_ICON_URL + }); + + Script.scriptEnding.connect(function () { + killWindow() + button.clicked.disconnect(onClicked); + tablet.removeButton(button); + }); + + button.clicked.connect(onClicked); + + var onScreen = false; + var window; + + function onClicked() { + if (onScreen) { + killWindow() + } else { + createWindow() + } + } + + function createWindow() { + var qml = Script.resolvePath(QMLAPP_URL); + window = new OverlayWindow({ + title: 'Render Engine Profiler', + source: qml, + width: 500, + height: 100 + }); + window.setPosition(200, 50); + window.closed.connect(killWindow); + onScreen = true + button.editProperties({isActive: true}); + } + + function killWindow() { + if (window !== undefined) { + window.closed.disconnect(killWindow); + window.close() + window = undefined + } + onScreen = false + button.editProperties({isActive: false}) + } + }()); + \ No newline at end of file diff --git a/scripts/developer/utilities/render/engineProfiler.qml b/scripts/developer/utilities/render/engineProfiler.qml new file mode 100644 index 0000000000..bfa049d089 --- /dev/null +++ b/scripts/developer/utilities/render/engineProfiler.qml @@ -0,0 +1,31 @@ +// +// EngineProfiler.qml +// +// Created by Sam Gateau on 06/07/2018 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.3 + +import "qrc:///qml/styles-uit" +import "qrc:///qml/controls-uit" as HifiControls + +import "../lib/jet/qml" as Jet + +Item { + HifiConstants { id: hifi;} + id: root; + anchors.fill: parent + + property var rootConfig: Render.getConfig("") + + + Jet.TaskTimeFrameView { + rootConfig: root.rootConfig + anchors.fill: root + } +} \ No newline at end of file diff --git a/scripts/developer/utilities/render/luci.js b/scripts/developer/utilities/render/luci.js index 005d96780a..9f0f32ee41 100644 --- a/scripts/developer/utilities/render/luci.js +++ b/scripts/developer/utilities/render/luci.js @@ -90,19 +90,22 @@ function fromQml(message) { switch (message.method) { - case "openEngineView": - openEngineTaskView(); + case "openEngineInspector": + openEngineInspector(); + break; + case "openEngineProfiler": + openEngineProfiler(); break; } } var engineInspectorView = null - function openEngineTaskView() { + function openEngineInspector() { if (engineInspectorView == null) { var qml = Script.resolvePath('engineInspector.qml'); var window = new OverlayWindow({ - title: 'Render Engine', + title: 'Render Engine Inspector', source: qml, width: 300, height: 400 @@ -115,7 +118,23 @@ } } - + var engineProfilerView = null + function openEngineProfiler() { + if (engineProfilerView == null) { + var qml = Script.resolvePath('engineProfiler.qml'); + var window = new OverlayWindow({ + title: 'Render Engine Profiler', + source: qml, + width: 300, + height: 400 + }); + window.setPosition(200, 50); + engineProfilerView = window + window.closed.connect(function() { engineProfilerView = null; }); + } else { + engineProfilerView.setPosition(200, 50); + } + } Script.scriptEnding.connect(function () { if (onLuciScreen) { @@ -128,5 +147,8 @@ if (engineInspectorView !== null) { engineInspectorView.close() } + if (engineProfilerView !== null) { + engineProfilerView.close() + } }); }()); \ No newline at end of file From 66199e9aab72362238647ad57fa089d5d8c4064d Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 11 Jul 2018 11:57:18 +0200 Subject: [PATCH 008/109] Cleaning up the isENabled interface andthe qml --- libraries/render-utils/src/BloomEffect.cpp | 3 ++- .../render-utils/src/RenderShadowTask.cpp | 2 +- libraries/render/src/render/DrawSceneOctree.h | 2 -- libraries/render/src/render/DrawStatus.cpp | 2 +- libraries/task/src/task/Config.cpp | 14 ++++++++++++ libraries/task/src/task/Config.h | 22 +++++++++++-------- libraries/task/src/task/Task.h | 2 +- .../utilities/lib/jet/qml/TaskListView.qml | 10 ++++----- .../lib/jet/qml/TaskTimeFrameView.qml | 5 +++-- .../utilities/render/engineInspector.js | 10 ++++----- .../utilities/render/engineInspector.qml | 2 +- .../utilities/render/engineProfiler.js | 6 ++--- 12 files changed, 49 insertions(+), 31 deletions(-) diff --git a/libraries/render-utils/src/BloomEffect.cpp b/libraries/render-utils/src/BloomEffect.cpp index ee06e17578..b198442b15 100644 --- a/libraries/render-utils/src/BloomEffect.cpp +++ b/libraries/render-utils/src/BloomEffect.cpp @@ -333,7 +333,8 @@ void Bloom::configure(const Config& config) { for (auto i = 0; i < BLOOM_BLUR_LEVEL_COUNT; i++) { blurName.back() = '0' + i; auto blurConfig = config.getConfig(blurName); - blurConfig->setProperty("filterScale", 1.0f); + blurConfig->filterScale = 1.0f; + //blurConfig->setProperty("filterScale", 1.0f); } } diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 91eb777199..d9ae0caade 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -282,7 +282,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende } void RenderShadowTask::configure(const Config& configuration) { - DependencyManager::get()->setShadowMapEnabled(configuration.enabled); + DependencyManager::get()->setShadowMapEnabled(configuration.isEnabled()); // This is a task, so must still propogate configure() to its Jobs // Task::configure(configuration); } diff --git a/libraries/render/src/render/DrawSceneOctree.h b/libraries/render/src/render/DrawSceneOctree.h index 9c416262ca..97cf45ebcf 100644 --- a/libraries/render/src/render/DrawSceneOctree.h +++ b/libraries/render/src/render/DrawSceneOctree.h @@ -20,7 +20,6 @@ namespace render { class DrawSceneOctreeConfig : public Job::Config { Q_OBJECT - Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty()) Q_PROPERTY(bool showVisibleCells READ getShowVisibleCells WRITE setShowVisibleCells NOTIFY dirty()) Q_PROPERTY(bool showEmptyCells READ getShowEmptyCells WRITE setShowEmptyCells NOTIFY dirty()) Q_PROPERTY(int numAllocatedCells READ getNumAllocatedCells) @@ -82,7 +81,6 @@ namespace render { class DrawItemSelectionConfig : public Job::Config { Q_OBJECT - Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty()) Q_PROPERTY(bool showInsideItems READ getShowInsideItems WRITE setShowInsideItems NOTIFY dirty()) Q_PROPERTY(bool showInsideSubcellItems READ getShowInsideSubcellItems WRITE setShowInsideSubcellItems NOTIFY dirty()) Q_PROPERTY(bool showPartialItems READ getShowPartialItems WRITE setShowPartialItems NOTIFY dirty()) diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 496b2000a9..b1e7620b19 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -29,7 +29,7 @@ using namespace render; void DrawStatusConfig::dirtyHelper() { - enabled = showNetwork || showDisplay; + _isEnabled = showNetwork || showDisplay; emit dirty(); } diff --git a/libraries/task/src/task/Config.cpp b/libraries/task/src/task/Config.cpp index ac7105be29..c0e9c41468 100644 --- a/libraries/task/src/task/Config.cpp +++ b/libraries/task/src/task/Config.cpp @@ -18,6 +18,17 @@ using namespace task; +JobConfig::~JobConfig() { + +} + +void JobConfig::setEnabled(bool enable) { + if (_isEnabled != enable) { + _isEnabled = enable; + emit dirtyEnabled(); + } +} + void JobConfig::setPresetList(const QJsonObject& object) { for (auto it = object.begin(); it != object.end(); it++) { JobConfig* child = findChild(it.key(), Qt::FindDirectChildrenOnly); @@ -30,6 +41,7 @@ void JobConfig::setPresetList(const QJsonObject& object) { void TaskConfig::connectChildConfig(QConfigPointer childConfig, const std::string& name) { childConfig->setParent(this); childConfig->setObjectName(name.c_str()); + // childConfig->propagateParentEnabled((_isParentEnabled ? _isEnabled : false)); // Connect loaded->refresh QObject::connect(childConfig.get(), SIGNAL(loaded()), this, SLOT(refresh())); @@ -57,6 +69,8 @@ void TaskConfig::transferChildrenConfigs(QConfigPointer source) { QObject::connect(child, SIGNAL(dirtyEnabled()), this, SLOT(refresh())); } } + + // propagateParentEnabledToSubs(); } void TaskConfig::refresh() { diff --git a/libraries/task/src/task/Config.h b/libraries/task/src/task/Config.h index b76c57521f..ab3303110b 100644 --- a/libraries/task/src/task/Config.h +++ b/libraries/task/src/task/Config.h @@ -50,12 +50,10 @@ public: _default = toJsonValue(*this).toObject().toVariantMap(); _presets.unite(list.toVariantMap()); - if (C::enabled) { + if (C::isEnabled()) { _presets.insert(DEFAULT, _default); } - if (false) { //!C::alwaysEnabled) { - _presets.insert(NONE, QVariantMap{{ "enabled", false }}); - } + _presets.insert(NONE, QVariantMap{{ "enabled", false }}); auto preset = _preset.get(); if (preset != _preset.getDefault() && _presets.contains(preset)) { @@ -92,16 +90,21 @@ class JobConfig : public QObject { Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY dirtyEnabled()) double _msCPURunTime{ 0.0 }; + +protected: + friend class TaskConfig; + + bool _isEnabled{ true }; + public: using Persistent = PersistentConfig; JobConfig() = default; - JobConfig(bool enabled): enabled{ enabled } {} + JobConfig(bool enabled): _isEnabled{ enabled } {} + ~JobConfig(); - bool isEnabled() { return /*alwaysEnabled ||*/ enabled; } - void setEnabled(bool enable) { enabled = /*alwaysEnabled ||*/ enable; emit dirtyEnabled(); } - - bool enabled{ true }; + bool isEnabled() const { return _isEnabled; } + void setEnabled(bool enable); virtual void setPresetList(const QJsonObject& object); @@ -199,6 +202,7 @@ public: */ class TaskConfig : public JobConfig { Q_OBJECT + public: using Persistent = PersistentConfig; diff --git a/libraries/task/src/task/Task.h b/libraries/task/src/task/Task.h index c15c0ceb13..8d2fd867c4 100644 --- a/libraries/task/src/task/Task.h +++ b/libraries/task/src/task/Task.h @@ -339,7 +339,7 @@ public: void run(const ContextPointer& jobContext) override { auto config = std::static_pointer_cast(Concept::_config); - if (config->enabled) { + if (config->isEnabled()) { for (auto job : TaskConcept::_jobs) { job.run(jobContext); if (jobContext->taskFlow.doAbortTask()) { diff --git a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml index 1229ef7dc7..02225aba62 100644 --- a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml +++ b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml @@ -19,7 +19,7 @@ import "../jet.js" as Jet Rectangle { HifiConstants { id: hifi;} - // color: hifi.colors.baseGray; + color: Qt.rgba(hifi.colors.baseGray.r, hifi.colors.baseGray.g, hifi.colors.baseGray.b, 0.8); id: root; property var rootConfig : Workload @@ -82,8 +82,8 @@ Rectangle { id: objCheck property var config: root.rootConfig.getConfig(model.path + "." + model.name); text: " " - checked: config.enabled - onCheckedChanged: { config.enabled = checked } + checked: root.rootConfig.getConfig(model.path + "." + model.name).enabled + onCheckedChanged: { root.rootConfig.getConfig(model.path + "." + model.name).enabled = checked } } MouseArea { @@ -95,12 +95,12 @@ Rectangle { HifiControls.Label { id: objLabel - colorScheme: hifi.colorSchemes.dark // property var config: root.rootConfig.getConfig(model.path + "." + model.name); + colorScheme: (root.rootConfig.getConfig(model.path + "." + model.name) ? hifi.colorSchemes.dark : hifi.colorSchemes.light) text: (objRecursiveColumn.children.length > 2 ? objRecursiveColumn.children[1].visible ? qsTr("- ") : qsTr("+ ") : qsTr(" ")) + model.name - + " ms=" + root.rootConfig.getConfig(model.path + "." + model.name).cpuRunTime.toFixed(3) + // + " ms=" + config.cpuRunTime.toFixed(3) + " id=" + model.id } } diff --git a/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml b/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml index 267344fca5..e1d9bd7ce1 100644 --- a/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml +++ b/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml @@ -19,7 +19,7 @@ import "../jet.js" as Jet Rectangle { HifiConstants { id: hifi;} - // color: hifi.colors.baseGray; + color: Qt.rgba(hifi.colors.baseGray.r, hifi.colors.baseGray.g, hifi.colors.baseGray.b, 0.8); id: root; property var rootConfig : Workload @@ -59,7 +59,8 @@ Rectangle { function pullFreshValues() { for (var j = 0; j Date: Fri, 13 Jul 2018 13:12:06 +0200 Subject: [PATCH 009/109] typo --- libraries/gpu/src/gpu/Buffer.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libraries/gpu/src/gpu/Buffer.cpp b/libraries/gpu/src/gpu/Buffer.cpp index d085b4df76..b3716c3490 100644 --- a/libraries/gpu/src/gpu/Buffer.cpp +++ b/libraries/gpu/src/gpu/Buffer.cpp @@ -163,13 +163,6 @@ Buffer::Size Buffer::getSize() const { const Element BufferView::DEFAULT_ELEMENT = Element( gpu::SCALAR, gpu::UINT8, gpu::RAW ); - -BufferPointer _buffer; -Size _offset{ 0 }; -Size _size{ 0 }; -Element _element{ DEFAULT_ELEMENT }; -uint16 _stride{ 0 }; - BufferView::BufferView(const BufferView& view) : _buffer(view._buffer), _offset(view._offset), From c24083c1f0c981458552c84ff3fe04d3de0c9720 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 25 Jul 2018 10:50:15 +0200 Subject: [PATCH 010/109] drafting along the RenderTHread class --- interface/src/Application.cpp | 67 ++++++----- interface/src/Application.h | 2 +- interface/src/graphics/GraphicsEngine.cpp | 38 +++++- interface/src/graphics/GraphicsEngine.h | 6 + interface/src/graphics/RenderEventHandler.cpp | 5 +- interface/src/graphics/RenderEventHandler.h | 5 +- interface/src/graphics/RenderThread.cpp | 1 + interface/src/graphics/RenderThread.h | 108 ++++++++++++++++++ 8 files changed, 187 insertions(+), 45 deletions(-) create mode 100644 interface/src/graphics/RenderThread.cpp create mode 100644 interface/src/graphics/RenderThread.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0ad27e0dd3..24dcf4ce72 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2425,6 +2425,7 @@ void Application::cleanupBeforeQuit() { } _window->saveGeometry(); + // _gpuContext->shutdown(); // Destroy third party processes after scripts have finished using them. @@ -4178,41 +4179,37 @@ bool Application::acceptSnapshot(const QString& urlString) { } return true; } - -static uint32_t _renderedFrameIndex { INVALID_FRAME }; - -bool Application::shouldPaint() const { - if (_aboutToQuit || _window->isMinimized()) { - return false; - } - - - auto displayPlugin = getActiveDisplayPlugin(); - -#ifdef DEBUG_PAINT_DELAY - static uint64_t paintDelaySamples{ 0 }; - static uint64_t paintDelayUsecs{ 0 }; - - paintDelayUsecs += displayPlugin->getPaintDelayUsecs(); - - static const int PAINT_DELAY_THROTTLE = 1000; - if (++paintDelaySamples % PAINT_DELAY_THROTTLE == 0) { - qCDebug(interfaceapp).nospace() << - "Paint delay (" << paintDelaySamples << " samples): " << - (float)paintDelaySamples / paintDelayUsecs << "us"; - } -#endif - - // Throttle if requested - //if (displayPlugin->isThrottled() && (_graphicsEngine._renderEventHandler->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { - if (displayPlugin->isThrottled() && !_graphicsEngine.shouldPaint()) { - return false; - } - - // Sync up the _renderedFrameIndex - _renderedFrameIndex = displayPlugin->presentCount(); - return true; -} +// +//bool Application::shouldPaint() const { +// if (_aboutToQuit || _window->isMinimized()) { +// return false; +// } +// +// +// auto displayPlugin = getActiveDisplayPlugin(); +// +//#ifdef DEBUG_PAINT_DELAY +// static uint64_t paintDelaySamples{ 0 }; +// static uint64_t paintDelayUsecs{ 0 }; +// +// paintDelayUsecs += displayPlugin->getPaintDelayUsecs(); +// +// static const int PAINT_DELAY_THROTTLE = 1000; +// if (++paintDelaySamples % PAINT_DELAY_THROTTLE == 0) { +// qCDebug(interfaceapp).nospace() << +// "Paint delay (" << paintDelaySamples << " samples): " << +// (float)paintDelaySamples / paintDelayUsecs << "us"; +// } +//#endif +// +// // Throttle if requested +// //if (displayPlugin->isThrottled() && (_graphicsEngine._renderEventHandler->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { +// if (displayPlugin->isThrottled() && !_graphicsEngine.shouldPaint()) { +// return false; +// } +// +// return true; +//} #ifdef Q_OS_WIN #include diff --git a/interface/src/Application.h b/interface/src/Application.h index fb8edf3b86..6d57ca9d8d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -157,7 +157,7 @@ public: void updateSecondaryCameraViewFrustum(); void updateCamera(RenderArgs& renderArgs, float deltaTime); - bool shouldPaint() const; + // bool shouldPaint() const; // void paintGL(); void resizeGL(); diff --git a/interface/src/graphics/GraphicsEngine.cpp b/interface/src/graphics/GraphicsEngine.cpp index 21c9a9b22d..d115d8914c 100644 --- a/interface/src/graphics/GraphicsEngine.cpp +++ b/interface/src/graphics/GraphicsEngine.cpp @@ -53,6 +53,7 @@ void GraphicsEngine::initializeGPU(GLWidget* glwidget) { _renderEventHandler = new RenderEventHandler( glwidget->qglContext(), + [this]() { return this->shouldPaint(); }, [this]() { this->render_performFrame(); } ); @@ -147,12 +148,37 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI bool GraphicsEngine::shouldPaint() const { - // Throttle if requested - if ((static_cast(_renderEventHandler)->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { - return false; - } - - return true; + +// if (_aboutToQuit || _window->isMinimized()) { +// return false; + // } + + + auto displayPlugin = qApp->getActiveDisplayPlugin(); + +#ifdef DEBUG_PAINT_DELAY + static uint64_t paintDelaySamples{ 0 }; + static uint64_t paintDelayUsecs{ 0 }; + + paintDelayUsecs += displayPlugin->getPaintDelayUsecs(); + + static const int PAINT_DELAY_THROTTLE = 1000; + if (++paintDelaySamples % PAINT_DELAY_THROTTLE == 0) { + qCDebug(interfaceapp).nospace() << + "Paint delay (" << paintDelaySamples << " samples): " << + (float)paintDelaySamples / paintDelayUsecs << "us"; + } +#endif + + // Throttle if requested + //if (displayPlugin->isThrottled() && (_graphicsEngine._renderEventHandler->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { + if ( displayPlugin->isThrottled() && + (static_cast(_renderEventHandler)->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { + return false; + } + + return true; + // } } bool GraphicsEngine::checkPendingRenderEvent() { diff --git a/interface/src/graphics/GraphicsEngine.h b/interface/src/graphics/GraphicsEngine.h index 780b4020d2..bc2121429a 100644 --- a/interface/src/graphics/GraphicsEngine.h +++ b/interface/src/graphics/GraphicsEngine.h @@ -16,6 +16,8 @@ #include +#include "RenderThread.h" + #include #include @@ -51,6 +53,8 @@ public: render::EnginePointer getRenderEngine() const { return _renderEngine; } gpu::ContextPointer getGPUContext() const { return _gpuContext; } + FrameQueuePointer getFrameQueue() const { return _frameQueue; } + // Same as the one in application bool shouldPaint() const; bool checkPendingRenderEvent(); @@ -79,6 +83,8 @@ protected: gpu::ContextPointer _gpuContext; // initialized during window creation + FrameQueuePointer _frameQueue{ new FrameQueue() }; + QObject* _renderEventHandler{ nullptr }; friend class RenderEventHandler; diff --git a/interface/src/graphics/RenderEventHandler.cpp b/interface/src/graphics/RenderEventHandler.cpp index 95e931ebd8..5b587ab171 100644 --- a/interface/src/graphics/RenderEventHandler.cpp +++ b/interface/src/graphics/RenderEventHandler.cpp @@ -15,7 +15,8 @@ #include "CrashHandler.h" -RenderEventHandler::RenderEventHandler(QOpenGLContext* context, RenderCall renderCall) : +RenderEventHandler::RenderEventHandler(QOpenGLContext* context, CheckCall checkCall, RenderCall renderCall) : + _checkCall(checkCall), _renderCall(renderCall) { _renderContext = new OffscreenGLCanvas(); @@ -52,7 +53,7 @@ void RenderEventHandler::resumeThread() { } void RenderEventHandler::render() { - if (qApp->shouldPaint()) { + if (_checkCall()) { _lastTimeRendered.start(); _renderCall(); } diff --git a/interface/src/graphics/RenderEventHandler.h b/interface/src/graphics/RenderEventHandler.h index 913898eb7f..43b16a76bd 100644 --- a/interface/src/graphics/RenderEventHandler.h +++ b/interface/src/graphics/RenderEventHandler.h @@ -28,10 +28,13 @@ class RenderEventHandler : public QObject { Q_OBJECT public: + using CheckCall = std::function ; using RenderCall = std::function ; + + CheckCall _checkCall; RenderCall _renderCall; - RenderEventHandler(QOpenGLContext* context, RenderCall renderCall); + RenderEventHandler(QOpenGLContext* context, CheckCall checkCall, RenderCall renderCall); QElapsedTimer _lastTimeRendered; std::atomic _pendingRenderEvent{ true }; diff --git a/interface/src/graphics/RenderThread.cpp b/interface/src/graphics/RenderThread.cpp new file mode 100644 index 0000000000..63df2033e8 --- /dev/null +++ b/interface/src/graphics/RenderThread.cpp @@ -0,0 +1 @@ +#include "RenderThread.h" \ No newline at end of file diff --git a/interface/src/graphics/RenderThread.h b/interface/src/graphics/RenderThread.h new file mode 100644 index 0000000000..abddf746e6 --- /dev/null +++ b/interface/src/graphics/RenderThread.h @@ -0,0 +1,108 @@ +#ifndef PRODUCERCONSUMERPIPE_H +#define PRODUCERCONSUMERPIPE_H + +#include +#include +#include +#include +#include + +// Producer is blocked if the consumer doesn't consume enough +// Consumer reads same value if producer doesn't produce enough +template +class ProducerConsumerPipe { +public: + + ProducerConsumerPipe(); + ProducerConsumerPipe(const T& initValue); + + const T& read(); + void read(T& value, const T& resetValue); + void write(const T& value); + bool isWritePossible(); + +private: + + short _readIndex; + short _writeIndex; + std::array _values; + std::array _used; + + void initialize(); + void updateReadIndex(); +}; + +template +ProducerConsumerPipe::ProducerConsumerPipe() { + initialize(); +} + +template +ProducerConsumerPipe::ProducerConsumerPipe(const T& initValue) { + _values.fill(initValue); + initialize(); +} + +template +void ProducerConsumerPipe::initialize() { + _readIndex = 0; + _writeIndex = 2; + _used[_readIndex].test_and_set(std::memory_order_acquire); + _used[_writeIndex].test_and_set(std::memory_order_acquire); + _used[1].clear(); +} + +template +void ProducerConsumerPipe::updateReadIndex() { + int nextReadIndex = (_readIndex + 1) % _values.size(); + + if (!_used[nextReadIndex].test_and_set(std::memory_order_acquire)) { + int readIndex = _readIndex; + _used[readIndex].clear(std::memory_order_release); + _readIndex = nextReadIndex; + } +} + +template +const T& ProducerConsumerPipe::read() { + updateReadIndex(); + return _values[_readIndex]; +} + +template +void ProducerConsumerPipe::read(T& value, const T& resetValue) { + updateReadIndex(); + value = _values[_readIndex]; + _values[_readIndex] = resetValue; +} + +template +bool ProducerConsumerPipe::isWritePossible() { + int nextWriteIndex = (_writeIndex + 1) % _values.size(); + return (_used[nextWriteIndex].test_and_set(std::memory_order_acquire)); +} + +template +void ProducerConsumerPipe::write(const T& value) { + int nextWriteIndex = (_writeIndex + 1) % _values.size(); + int writeIndex = _writeIndex; + + _values[writeIndex] = value; + + while (_used[nextWriteIndex].test_and_set(std::memory_order_acquire)) { + // spin + std::this_thread::yield(); + } + _used[writeIndex].clear(std::memory_order_release); + _writeIndex = nextWriteIndex; +} + + +#include + +using FrameQueue = ProducerConsumerPipe; + +using FrameQueuePointer = std::shared_ptr; + + +#endif From c0bbe1599b2cd5fc1eda5af267dc4414e277089d Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 30 Jul 2018 11:28:56 +0200 Subject: [PATCH 011/109] Trying to sync the thotling for all render threads --- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 6 +++--- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 11 ++++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index d8b8cbd54a..7e95727fcc 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -165,11 +165,11 @@ static const uint32_t MIN_THROTTLE_CHECK_FRAMES = 60; bool Basic2DWindowOpenGLDisplayPlugin::isThrottled() const { static auto lastCheck = presentCount(); // Don't access the menu API every single frame - if ((presentCount() - lastCheck) > MIN_THROTTLE_CHECK_FRAMES) { + // if ((presentCount() - lastCheck) > MIN_THROTTLE_CHECK_FRAMES) { static const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus"; // FIXME - this value duplicated in Menu.h _isThrottled = (!_container->isForeground() && _container->isOptionChecked(ThrottleFPSIfNotFocus)); - lastCheck = presentCount(); - } + // lastCheck = presentCount(); + // } return _isThrottled; } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 9200843cf8..b18f9f988b 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -198,7 +198,16 @@ public: // If there's no active plugin, just sleep if (currentPlugin == nullptr) { // Minimum sleep ends up being about 2 ms anyway - QThread::msleep(1); + QThread::msleep(16); + continue; + } + + static uint _vsyncLoopIndex = 0; + _vsyncLoopIndex++; + + if (currentPlugin->isThrottled() && (_vsyncLoopIndex % 8)) { + // Minimum sleep ends up being about 2 ms anyway + QThread::msleep(16); continue; } From e8c5324e3936b368ce8517f635a06435bfc7bda2 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 25 Oct 2018 11:59:04 -0700 Subject: [PATCH 012/109] start removing branching --- libraries/gpu/src/gpu/Noise.slh | 3 +- .../src/graphics/MaterialTextures.slh | 48 ++++++++++++------- .../render-utils/src/DeferredBufferRead.slh | 33 +++++-------- .../render-utils/src/DeferredBufferWrite.slh | 6 ++- .../render-utils/src/DeferredTransform.slh | 3 +- libraries/render-utils/src/Fade.slh | 10 ++-- libraries/render-utils/src/Haze.slh | 42 ++++++++-------- libraries/render-utils/src/Highlight.slh | 32 ++++++------- .../render-utils/src/LightClusterGrid.slh | 3 +- .../src/LightClusterGrid_shared.slh | 31 +++++------- libraries/render-utils/src/LightPoint.slh | 24 +++++----- libraries/render-utils/src/LightSpot.slh | 22 ++++----- libraries/render-utils/src/Shadow.slh | 20 ++++---- libraries/render/src/render/BlurTask.slh | 12 ++--- 14 files changed, 144 insertions(+), 145 deletions(-) diff --git a/libraries/gpu/src/gpu/Noise.slh b/libraries/gpu/src/gpu/Noise.slh index d300e71ba9..a6a658cbd1 100644 --- a/libraries/gpu/src/gpu/Noise.slh +++ b/libraries/gpu/src/gpu/Noise.slh @@ -231,7 +231,8 @@ float snoise(vec2 v) { // Other corners vec2 i1; - i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); + float check = float(x0.x > x0.y); + i1 = vec2(check, 1.0 - check); vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; diff --git a/libraries/graphics/src/graphics/MaterialTextures.slh b/libraries/graphics/src/graphics/MaterialTextures.slh index db329c3852..d393d0bcbd 100644 --- a/libraries/graphics/src/graphics/MaterialTextures.slh +++ b/libraries/graphics/src/graphics/MaterialTextures.slh @@ -151,29 +151,37 @@ float fetchScatteringMap(vec2 uv) { <@func fetchMaterialTexturesCoord0(matKey, texcoord0, albedo, roughness, normal, metallic, emissive, scattering)@> + float check; <@if albedo@> - vec4 <$albedo$> = (((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0) ? fetchAlbedoMap(<$texcoord0$>) : vec4(1.0)); + check = float((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0); + vec4 <$albedo$> = check * fetchAlbedoMap(<$texcoord0$>) + vec4(1.0 - check); <@endif@> <@if roughness@> - float <$roughness$> = (((<$matKey$> & ROUGHNESS_MAP_BIT) != 0) ? fetchRoughnessMap(<$texcoord0$>) : 1.0); + check = float((<$matKey$> & ROUGHNESS_MAP_BIT) != 0); + float <$roughness$> = check * fetchRoughnessMap(<$texcoord0$>) + (1.0 - check); <@endif@> <@if normal@> - vec3 <$normal$> = (((<$matKey$> & NORMAL_MAP_BIT) != 0) ? fetchNormalMap(<$texcoord0$>) : vec3(0.0, 1.0, 0.0)); + check = float((<$matKey$> & NORMAL_MAP_BIT) != 0); + vec3 <$normal$> = check * fetchNormalMap(<$texcoord0$>) + vec3(0.0, 1.0 - check, 0.0); <@endif@> <@if metallic@> - float <$metallic$> = (((<$matKey$> & METALLIC_MAP_BIT) != 0) ? fetchMetallicMap(<$texcoord0$>) : 0.0); + check = float((<$matKey$> & METALLIC_MAP_BIT) != 0); + float <$metallic$> = check * fetchMetallicMap(<$texcoord0$>); <@endif@> <@if emissive@> - vec3 <$emissive$> = (((<$matKey$> & EMISSIVE_MAP_BIT) != 0) ? fetchEmissiveMap(<$texcoord0$>) : vec3(0.0)); + check = float((<$matKey$> & EMISSIVE_MAP_BIT) != 0); + vec3 <$emissive$> = check * fetchEmissiveMap(<$texcoord0$>); <@endif@> <@if scattering@> - float <$scattering$> = (((<$matKey$> & SCATTERING_MAP_BIT) != 0) ? fetchScatteringMap(<$texcoord0$>) : 0.0); + check = float((<$matKey$> & SCATTERING_MAP_BIT) != 0); + float <$scattering$> = check * fetchScatteringMap(<$texcoord0$>); <@endif@> <@endfunc@> <@func fetchMaterialTexturesCoord1(matKey, texcoord1, occlusion, lightmapVal)@> <@if occlusion@> - float <$occlusion$> = (((<$matKey$> & OCCLUSION_MAP_BIT) != 0) ? fetchOcclusionMap(<$texcoord1$>) : 1.0); + float check1 = float((<$matKey$> & OCCLUSION_MAP_BIT) != 0); + float <$occlusion$> = check1 * fetchOcclusionMap(<$texcoord1$>) + (1.0 - check1); <@endif@> <@if lightmapVal@> vec3 <$lightmapVal$> = fetchLightmapMap(<$texcoord1$>); @@ -217,20 +225,20 @@ vec3 fetchLightmapMap(vec2 uv) { <@func evalMaterialAlbedo(fetchedAlbedo, materialAlbedo, matKey, albedo)@> { - <$albedo$>.xyz = (((<$matKey$> & ALBEDO_VAL_BIT) != 0) ? <$materialAlbedo$> : vec3(1.0)); + float check = float((<$matKey$> & ALBEDO_VAL_BIT) != 0); + <$albedo$>.xyz = check * <$materialAlbedo$> + vec3(1.0 - check); - if (((<$matKey$> & ALBEDO_MAP_BIT) != 0)) { - <$albedo$>.xyz *= <$fetchedAlbedo$>.xyz; - } + check = float((<$matKey$> & ALBEDO_MAP_BIT) != 0); + <$albedo$>.xyz *= check * <$fetchedAlbedo$>.xyz + vec3(1.0 - check); } <@endfunc@> <@func evalMaterialOpacity(fetchedOpacity, materialOpacity, matKey, opacity)@> { const float OPACITY_MASK_THRESHOLD = 0.5; - <$opacity$> = (((<$matKey$> & (OPACITY_TRANSLUCENT_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0) ? - (((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0) ? step(OPACITY_MASK_THRESHOLD, <$fetchedOpacity$>) : <$fetchedOpacity$>) : - 1.0) * <$materialOpacity$>; + float check = float((<$matKey$> & (OPACITY_TRANSLUCENT_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0); + float check2 = float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0); + <$opacity$> = (check * (check2 * step(OPACITY_MASK_THRESHOLD, <$fetchedOpacity$>) + (1.0 - check2) * <$fetchedOpacity$>) + (1.0 - check)) * <$materialOpacity$>; } <@endfunc@> @@ -251,19 +259,22 @@ vec3 fetchLightmapMap(vec2 uv) { <@func evalMaterialRoughness(fetchedRoughness, materialRoughness, matKey, roughness)@> { - <$roughness$> = (((<$matKey$> & ROUGHNESS_MAP_BIT) != 0) ? <$fetchedRoughness$> : <$materialRoughness$>); + float check = float((<$matKey$> & ROUGHNESS_MAP_BIT) != 0); + <$roughness$> = check * <$fetchedRoughness$> + (1.0 - check) * <$materialRoughness$>; } <@endfunc@> <@func evalMaterialMetallic(fetchedMetallic, materialMetallic, matKey, metallic)@> { - <$metallic$> = (((<$matKey$> & METALLIC_MAP_BIT) != 0) ? <$fetchedMetallic$> : <$materialMetallic$>); + float check = float((<$matKey$> & METALLIC_MAP_BIT) != 0); + <$metallic$> = check * <$fetchedMetallic$> + (1.0 - check) * <$materialMetallic$>; } <@endfunc@> <@func evalMaterialEmissive(fetchedEmissive, materialEmissive, matKey, emissive)@> { - <$emissive$> = (((<$matKey$> & EMISSIVE_MAP_BIT) != 0) ? <$fetchedEmissive$> : <$materialEmissive$>); + float check = float((<$matKey$> & EMISSIVE_MAP_BIT) != 0); + <$emissive$> = check * <$fetchedEmissive$> + (1.0 - check) * <$materialEmissive$>; } <@endfunc@> @@ -275,7 +286,8 @@ vec3 fetchLightmapMap(vec2 uv) { <@func evalMaterialScattering(fetchedScattering, materialScattering, matKey, scattering)@> { - <$scattering$> = (((<$matKey$> & SCATTERING_MAP_BIT) != 0) ? <$fetchedScattering$> : <$materialScattering$>); + float check = float((<$matKey$> & SCATTERING_MAP_BIT) != 0); + <$scattering$> = check * <$fetchedScattering$> + (1.0 - check) * <$materialScattering$>; } <@endfunc@> diff --git a/libraries/render-utils/src/DeferredBufferRead.slh b/libraries/render-utils/src/DeferredBufferRead.slh index f3b8c0404a..bf0100d0d3 100644 --- a/libraries/render-utils/src/DeferredBufferRead.slh +++ b/libraries/render-utils/src/DeferredBufferRead.slh @@ -76,14 +76,12 @@ DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) { // Diffuse color and unpack the mode and the metallicness frag.albedo = diffuseVal.xyz; - frag.scattering = 0.0; unpackModeMetallic(diffuseVal.w, frag.mode, frag.metallic); frag.obscurance = min(specularVal.w, frag.obscurance); - if (frag.mode == FRAG_MODE_SCATTERING) { - frag.scattering = specularVal.x; - } + float check = float(frag.mode == FRAG_MODE_SCATTERING); + frag.scattering = check * specularVal.x; frag.fresnel = getFresnelF0(frag.metallic, diffuseVal.xyz); @@ -122,14 +120,11 @@ DeferredFragment unpackDeferredFragmentNoPositionNoAmbient(vec2 texcoord) { <$declareDeferredFrameTransform()$> vec4 unpackDeferredPosition(float depthValue, vec2 texcoord) { - int side = 0; - if (isStereo()) { - if (texcoord.x > 0.5) { - texcoord.x -= 0.5; - side = 1; - } - texcoord.x *= 2.0; - } + float check = float(isStereo()); + float check2 = float(texcoord.x > 0.5); + texcoord.x -= check * check2 * 0.5; + int side = int(check * check2); + texcoord.x *= check * 2.0 + (1.0 - check) * 1.0; return vec4(evalEyePositionFromZdb(side, depthValue, texcoord), 1.0); } @@ -142,19 +137,15 @@ vec4 unpackDeferredPositionFromZdb(vec2 texcoord) { vec4 unpackDeferredPositionFromZeye(vec2 texcoord) { float Zeye = -texture(linearZeyeMap, texcoord).x; - int side = 0; - if (isStereo()) { - if (texcoord.x > 0.5) { - texcoord.x -= 0.5; - side = 1; - } - texcoord.x *= 2.0; - } + float check = float(isStereo()); + float check2 = float(texcoord.x > 0.5); + texcoord.x -= check * check2 * 0.5; + int side = int(check * check2); + texcoord.x *= check * 2.0 + (1.0 - check) * 1.0; return vec4(evalEyePositionFromZeye(side, Zeye, texcoord), 1.0); } DeferredFragment unpackDeferredFragment(DeferredFrameTransform deferredTransform, vec2 texcoord) { - float depthValue = texture(depthMap, texcoord).r; DeferredFragment frag = unpackDeferredFragmentNoPosition(texcoord); diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh index 769e602dc5..a531affd85 100644 --- a/libraries/render-utils/src/DeferredBufferWrite.slh +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -32,9 +32,11 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness if (alpha != 1.0) { discard; } - _fragColor0 = vec4(albedo, ((scattering > 0.0) ? packScatteringMetallic(metallic) : packShadedMetallic(metallic))); + + float check = float(scattering > 0.0); + _fragColor0 = vec4(albedo, check * packScatteringMetallic(metallic) + (1.0 - check) * packShadedMetallic(metallic)); _fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0)); - _fragColor2 = vec4(((scattering > 0.0) ? vec3(scattering) : emissive), occlusion); + _fragColor2 = vec4(check * vec3(scattering) + (1.0 - check) * emissive, occlusion); _fragColor3 = vec4(isEmissiveEnabled() * emissive, 1.0); } diff --git a/libraries/render-utils/src/DeferredTransform.slh b/libraries/render-utils/src/DeferredTransform.slh index 8a8805e928..3ec763efe2 100644 --- a/libraries/render-utils/src/DeferredTransform.slh +++ b/libraries/render-utils/src/DeferredTransform.slh @@ -126,7 +126,8 @@ vec2 getSideImageSize(int resolutionLevel) { ivec4 getStereoSideInfo(int xPos, int resolutionLevel) { int sideWidth = int(getStereoSideWidth(resolutionLevel)); - return ivec4(xPos < sideWidth ? ivec2(0, 0) : ivec2(1, sideWidth), sideWidth, isStereo()); + int check = int(xPos < sideWidth); + return ivec4((1 - check) * ivec2(1, sideWidth), sideWidth, isStereo()); } float evalZeyeFromZdb(float depth) { diff --git a/libraries/render-utils/src/Fade.slh b/libraries/render-utils/src/Fade.slh index a7523f969b..6770f53200 100644 --- a/libraries/render-utils/src/Fade.slh +++ b/libraries/render-utils/src/Fade.slh @@ -85,7 +85,12 @@ float evalFadeGradient(FadeObjectParams params, vec3 position) { } float evalFadeAlpha(FadeObjectParams params, vec3 position) { - return evalFadeGradient(params, position)-params.threshold; + float alpha = evalFadeGradient(params, position) - params.threshold; + + float check = float(fadeParameters[params.category]._isInverted != 0); + alpha *= -check + (1.0 - check); + + return alpha; } void applyFadeClip(FadeObjectParams params, vec3 position) { @@ -96,9 +101,6 @@ void applyFadeClip(FadeObjectParams params, vec3 position) { void applyFade(FadeObjectParams params, vec3 position, out vec3 emissive) { float alpha = evalFadeAlpha(params, position); - if (fadeParameters[params.category]._isInverted!=0) { - alpha = -alpha; - } if (alpha < 0.0) { discard; diff --git a/libraries/render-utils/src/Haze.slh b/libraries/render-utils/src/Haze.slh index a7654da8d2..f5795565cc 100644 --- a/libraries/render-utils/src/Haze.slh +++ b/libraries/render-utils/src/Haze.slh @@ -63,20 +63,18 @@ vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirectionWS, vec3 // Height at which haze density is reduced by 95% (default set to 2000.0 for safety ,this should never happen) float height_95p = 2000.0; const float log_p_005 = log(0.05); - if (hazeParams.hazeKeyLightAltitudeFactor > 0.0f) { - height_95p = -log_p_005 / hazeParams.hazeKeyLightAltitudeFactor; + + { + float check = float(hazeParams.hazeKeyLightAltitudeFactor > 0.0f); + height_95p = check * -log_p_005 / hazeParams.hazeKeyLightAltitudeFactor + (1.0 - check) * height_95p; } // Note that we need the sine to be positive - float sin_pitch = abs(lightDirectionWS.y); - - float distance; const float minimumSinPitch = 0.001; - if (sin_pitch < minimumSinPitch) { - distance = height_95p / minimumSinPitch; - } else { - distance = height_95p / sin_pitch; - } + float sin_pitch = abs(lightDirectionWS.y); + sin_pitch = max(sin_pitch, minimumSinPitch); + + float distance = height_95p / sin_pitch; // Integration is from the fragment towards the light source // Note that the haze base reference affects only the haze density as function of altitude @@ -128,6 +126,7 @@ vec4 computeHazeColor(vec3 fragPositionES, vec3 fragPositionWS, vec3 eyePosition } vec4 potentialFragColor; + const float EPSILON = 0.0000001f; if ((hazeParams.hazeMode & HAZE_MODE_IS_MODULATE_COLOR) == HAZE_MODE_IS_MODULATE_COLOR) { // Compute separately for each colour @@ -143,9 +142,10 @@ vec4 computeHazeColor(vec3 fragPositionES, vec3 fragPositionWS, vec3 eyePosition const float slopeThreshold = 0.01; float deltaHeight = fragPositionWS.y - eyeWorldHeight; - if (abs(deltaHeight) > slopeThreshold) { - float t = hazeParams.hazeHeightFactor * deltaHeight; - hazeIntegral *= (1.0 - exp (-t)) / t; + float t = hazeParams.hazeHeightFactor * deltaHeight; + if (abs(t) > EPSILON) { + float check = float(abs(deltaHeight) > slopeThreshold); + hazeIntegral *= check * (1.0 - exp(-t)) / t + (1.0 - check); } vec3 hazeAmount = 1.0 - exp(-hazeIntegral); @@ -171,13 +171,10 @@ vec4 computeHazeColor(vec3 fragPositionES, vec3 fragPositionWS, vec3 eyePosition const float slopeThreshold = 0.01; float deltaHeight = fragPositionWS.y - eyeWorldHeight; - if (abs(deltaHeight) > slopeThreshold) { - float t = hazeParams.hazeHeightFactor * deltaHeight; - // Protect from wild values - const float EPSILON = 0.0000001f; - if (abs(t) > EPSILON) { - hazeIntegral *= (1.0 - exp (-t)) / t; - } + float t = hazeParams.hazeHeightFactor * deltaHeight; + if (abs(t) > EPSILON) { + float check = float(abs(deltaHeight) > slopeThreshold); + hazeIntegral *= check * (1.0 - exp(-t)) / t + (1.0 - check); } float hazeAmount = 1.0 - exp(-hazeIntegral); @@ -189,9 +186,8 @@ vec4 computeHazeColor(vec3 fragPositionES, vec3 fragPositionWS, vec3 eyePosition // Mix with background at far range const float BLEND_DISTANCE = 27000.0f; vec4 outFragColor = potentialFragColor; - if (distance > BLEND_DISTANCE) { - outFragColor.a *= hazeParams.backgroundBlend; - } + float check = float(distance > BLEND_DISTANCE); + outFragColor.a *= check * hazeParams.backgroundBlend + (1.0 - check); return outFragColor; } diff --git a/libraries/render-utils/src/Highlight.slh b/libraries/render-utils/src/Highlight.slh index 264b57acbb..eee22ecb0a 100644 --- a/libraries/render-utils/src/Highlight.slh +++ b/libraries/render-utils/src/Highlight.slh @@ -45,11 +45,9 @@ void main(void) { highlightedDepth = -evalZeyeFromZdb(highlightedDepth); sceneDepth = -evalZeyeFromZdb(sceneDepth); - if (sceneDepth < highlightedDepth) { - outFragColor = vec4(params._fillOccludedColor, params._fillOccludedAlpha); - } else { - outFragColor = vec4(params._fillUnoccludedColor, params._fillUnoccludedAlpha); - } + float check = float(sceneDepth < highlightedDepth); + outFragColor = check * vec4(params._fillOccludedColor, params._fillOccludedAlpha) + + (1.0 - check) * vec4(params._fillUnoccludedColor, params._fillUnoccludedAlpha); <@else@> discard; <@endif@> @@ -67,14 +65,13 @@ void main(void) { float outlinedDepth = 0.0; float sumOutlineDepth = 0.0; - for (y=0 ; y=0.0 && uv.y<=1.0) { - for (x=0 ; x=0.0 && uv.x<=1.0) - { + if (uv.y >= 0.0 && uv.y <= 1.0) { + for (x = 0; x < params._blurKernelSize; x++) { + if (uv.x >= 0.0 && uv.x <= 1.0) { outlinedDepth = texture(highlightedDepthMap, uv).x; float touch = (outlinedDepth < FAR_Z) ? 1.0 : 0.0; sumOutlineDepth = max(outlinedDepth * touch, sumOutlineDepth); @@ -86,10 +83,9 @@ void main(void) { } } - if (intensity > 0.0) { - // sumOutlineDepth /= intensity; - } else { - sumOutlineDepth = FAR_Z; + { + float check = float(intensity > 0.0); + sumOutlineDepth = check * sumOutlineDepth + (1.0 - check) * FAR_Z; } intensity /= weight; @@ -106,10 +102,10 @@ void main(void) { sceneDepth = -evalZeyeFromZdb(sceneDepth); // Are we occluded? - if (sceneDepth < outlinedDepth) { - outFragColor = vec4(params._outlineOccludedColor, intensity * params._outlineOccludedAlpha); - } else { - outFragColor = vec4(params._outlineUnoccludedColor, intensity * params._outlineUnoccludedAlpha); + { + float check = float(sceneDepth < outlinedDepth); + outFragColor = check * vec4(params._outlineOccludedColor, intensity * params._outlineOccludedAlpha) + + (1.0 - check) * vec4(params._outlineUnoccludedColor, intensity * params._outlineUnoccludedAlpha); } } } diff --git a/libraries/render-utils/src/LightClusterGrid.slh b/libraries/render-utils/src/LightClusterGrid.slh index 62af92e6ce..46eba68fff 100644 --- a/libraries/render-utils/src/LightClusterGrid.slh +++ b/libraries/render-utils/src/LightClusterGrid.slh @@ -83,7 +83,8 @@ int clusterGrid_getClusterLightId(int index, int offset) { return element; */ int element = _clusterGridContent[GRID_FETCH_BUFFER((elementIndex >> 1))]; - return (((elementIndex & 0x00000001) == 1) ? (element >> 16) : element) & 0x0000FFFF; + int check = int((elementIndex & 0x00000001) == 1); + return (check * (element >> 16) + (1 - check) * element) & 0x0000FFFF; } diff --git a/libraries/render-utils/src/LightClusterGrid_shared.slh b/libraries/render-utils/src/LightClusterGrid_shared.slh index 6d43e71920..be9d980062 100644 --- a/libraries/render-utils/src/LightClusterGrid_shared.slh +++ b/libraries/render-utils/src/LightClusterGrid_shared.slh @@ -5,6 +5,12 @@ #define float_exp2 exp2 #endif +#ifdef __cplusplus +# define _MIN glm::min +#else +# define _MIN min +#endif + float frustumGrid_depthRampGridToVolume(float ngrid) { // return ngrid; // return sqrt(ngrid); @@ -87,14 +93,9 @@ ivec3 frustumGrid_indexToCluster(int index) { } vec3 frustumGrid_clusterPosToEye(vec3 clusterPos) { - vec3 cvpos = clusterPos; - - vec3 volumePos = frustumGrid_gridToVolume(cvpos, frustumGrid.dims); - vec3 eyePos = frustumGrid_volumeToEye(volumePos, frustumGrid.eyeToGridProj, frustumGrid.rangeNear, frustumGrid.rangeFar); - return eyePos; } @@ -116,27 +117,19 @@ int frustumGrid_eyeDepthToClusterLayer(float eyeZ) { int gridZ = int(frustumGrid_volumeToGridDepth(volumeZ, frustumGrid.dims)); - if (gridZ >= frustumGrid.dims.z) { - gridZ = frustumGrid.dims.z; - } - - - return gridZ; + return _MIN(gridZ, frustumGrid.dims.z); } ivec3 frustumGrid_eyeToClusterPos(vec3 eyePos) { // make sure the frontEyePos is always in the front to eval the grid pos correctly vec3 frontEyePos = eyePos; - frontEyePos.z = (eyePos.z > 0.0f ? -eyePos.z : eyePos.z); + frontEyePos.z = -abs(eyePos.z); vec3 volumePos = frustumGrid_eyeToVolume(frontEyePos, frustumGrid.eyeToGridProj, frustumGrid.rangeNear, frustumGrid.rangeFar); vec3 gridPos = frustumGrid_volumeToGrid(volumePos, frustumGrid.dims); - - if (gridPos.z >= float(frustumGrid.dims.z)) { - gridPos.z = float(frustumGrid.dims.z); - } + gridPos.z = _MIN(gridPos.z, float(frustumGrid.dims.z)); ivec3 igridPos = ivec3(floor(gridPos)); @@ -154,7 +147,8 @@ ivec3 frustumGrid_eyeToClusterPos(vec3 eyePos) { int frustumGrid_eyeToClusterDirH(vec3 eyeDir) { if (eyeDir.z >= 0.0f) { - return (eyeDir.x > 0.0f ? frustumGrid.dims.x : -1); + int check = int(eyeDir.x > 0.0f); + return check * frustumGrid.dims.x + (check - 1); } float eyeDepth = -eyeDir.z; @@ -168,7 +162,8 @@ int frustumGrid_eyeToClusterDirH(vec3 eyeDir) { int frustumGrid_eyeToClusterDirV(vec3 eyeDir) { if (eyeDir.z >= 0.0f) { - return (eyeDir.y > 0.0f ? frustumGrid.dims.y : -1); + int check = int(eyeDir.y > 0.0f); + return check * frustumGrid.dims.y + (check - 1); } float eyeDepth = -eyeDir.z; diff --git a/libraries/render-utils/src/LightPoint.slh b/libraries/render-utils/src/LightPoint.slh index 1a361e3717..f5cda3d9d4 100644 --- a/libraries/render-utils/src/LightPoint.slh +++ b/libraries/render-utils/src/LightPoint.slh @@ -39,14 +39,13 @@ void evalLightingPoint(out vec3 diffuse, out vec3 specular, Light light, lightEnergy *= isPointEnabled(); diffuse *= lightEnergy * isDiffuseEnabled(); specular *= lightEnergy * isSpecularEnabled(); - - if (isShowLightContour() > 0.0) { - // Show edge + + { + // Show edges float edge = abs(2.0 * ((lightVolume_getRadius(light.volume) - fragLightDistance) / (0.1)) - 1.0); - if (edge < 1.0) { - float edgeCoord = exp2(-8.0*edge*edge); - diffuse = vec3(edgeCoord * edgeCoord * getLightColor(light)); - } + float check = float(isShowLightContour() > 0.0 && edge < 1.0); + float edgeCoord = exp2(-8.0 * edge * edge); + diffuse = check * vec3(edgeCoord * edgeCoord * getLightColor(light)) + (1.0 - check) * diffuse; } } @@ -59,12 +58,13 @@ bool evalLightPointEdge(out vec3 color, Light light, vec4 fragLightDirLen, vec3 // Allright we re valid in the volume float fragLightDistance = fragLightDirLen.w; vec3 fragLightDir = fragLightDirLen.xyz; - - // Show edges + float edge = abs(2.0 * ((lightVolume_getRadius(light.volume) - fragLightDistance) / (0.1)) - 1.0); - if (edge < 1.0) { - float edgeCoord = exp2(-8.0*edge*edge); - color = vec3(edgeCoord * edgeCoord * getLightColor(light)); + { + // Show edges + float check = float(edge < 1.0); + float edgeCoord = exp2(-8.0 * edge * edge); + color = check * vec3(edgeCoord * edgeCoord * getLightColor(light)) + (1.0 - check) * color; } return (edge < 1.0); diff --git a/libraries/render-utils/src/LightSpot.slh b/libraries/render-utils/src/LightSpot.slh index 2546c0225c..395fe892e7 100644 --- a/libraries/render-utils/src/LightSpot.slh +++ b/libraries/render-utils/src/LightSpot.slh @@ -40,17 +40,16 @@ void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light, lightEnergy *= isSpotEnabled(); diffuse *= lightEnergy * isDiffuseEnabled(); specular *= lightEnergy * isSpecularEnabled(); - - if (isShowLightContour() > 0.0) { + + { // Show edges float edgeDistR = (lightVolume_getRadius(light.volume) - fragLightDistance); float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -lightVolume_getSpotOutsideNormal2(light.volume)); float edgeDist = min(edgeDistR, edgeDistS); float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0); - if (edge < 1.0) { - float edgeCoord = exp2(-8.0*edge*edge); - diffuse = vec3(edgeCoord * edgeCoord * getLightColor(light)); - } + float check = float(isShowLightContour() > 0.0 && edge < 1.0); + float edgeCoord = exp2(-8.0 * edge * edge); + diffuse = check * vec3(edgeCoord * edgeCoord * getLightColor(light)) + (1.0 - check) * diffuse; } } @@ -63,19 +62,18 @@ bool evalLightSpotEdge(out vec3 color, Light light, vec4 fragLightDirLen, float float fragLightDistance = fragLightDirLen.w; vec3 fragLightDir = fragLightDirLen.xyz; - // Show edges float edgeDistR = (lightVolume_getRadius(light.volume) - fragLightDistance); float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -lightVolume_getSpotOutsideNormal2(light.volume)); float edgeDist = min(edgeDistR, edgeDistS); float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0); - if (edge < 1.0) { - float edgeCoord = exp2(-8.0*edge*edge); - color = vec3(edgeCoord * edgeCoord * getLightColor(light)); + { + // Show edges + float check = float(edge < 1.0); + float edgeCoord = exp2(-8.0 * edge * edge); + color = check * vec3(edgeCoord * edgeCoord * getLightColor(light)) + (1.0 - check) * color; } return (edge < 1.0); } <@endfunc@> - - diff --git a/libraries/render-utils/src/Shadow.slh b/libraries/render-utils/src/Shadow.slh index 9506c9805d..10922350ed 100644 --- a/libraries/render-utils/src/Shadow.slh +++ b/libraries/render-utils/src/Shadow.slh @@ -115,17 +115,21 @@ float evalShadowAttenuation(vec3 worldLightDir, vec4 worldPosition, float viewDe isPixelOnCascade.z = isShadowCascadeProjectedOnPixel(cascadeShadowCoords[2]); isPixelOnCascade.w = isShadowCascadeProjectedOnPixel(cascadeShadowCoords[3]); - if (isPixelOnCascade.x) { - cascadeAttenuations.x = evalShadowCascadeAttenuation(0, offsets, cascadeShadowCoords[0], oneMinusNdotL); + { + float check = float(isPixelOnCascade.x); + cascadeAttenuations.x = check * evalShadowCascadeAttenuation(0, offsets, cascadeShadowCoords[0], oneMinusNdotL) + (1.0 - check); } - if (isPixelOnCascade.y) { - cascadeAttenuations.y = evalShadowCascadeAttenuation(1, offsets, cascadeShadowCoords[1], oneMinusNdotL); + { + float check = float(isPixelOnCascade.y); + cascadeAttenuations.y = check * evalShadowCascadeAttenuation(1, offsets, cascadeShadowCoords[1], oneMinusNdotL) + (1.0 - check); } - if (isPixelOnCascade.z) { - cascadeAttenuations.z = evalShadowCascadeAttenuation(2, offsets, cascadeShadowCoords[2], oneMinusNdotL); + { + float check = float(isPixelOnCascade.z); + cascadeAttenuations.z = check * evalShadowCascadeAttenuation(2, offsets, cascadeShadowCoords[2], oneMinusNdotL) + (1.0 - check); } - if (isPixelOnCascade.w) { - cascadeAttenuations.w = evalShadowCascadeAttenuation(3, offsets, cascadeShadowCoords[3], oneMinusNdotL); + { + float check = float(isPixelOnCascade.w); + cascadeAttenuations.w = check * evalShadowCascadeAttenuation(3, offsets, cascadeShadowCoords[3], oneMinusNdotL) + (1.0 - check); } cascadeWeights.x = evalShadowCascadeWeight(cascadeShadowCoords[0]); diff --git a/libraries/render/src/render/BlurTask.slh b/libraries/render/src/render/BlurTask.slh index db6b8e3bab..1133435b4d 100644 --- a/libraries/render/src/render/BlurTask.slh +++ b/libraries/render/src/render/BlurTask.slh @@ -99,9 +99,9 @@ vec4 pixelShaderGaussian(vec2 texcoord, vec2 direction, vec2 pixelStep) { } } - if (totalWeight>0.0) { - srcBlurred /= totalWeight; - } + float check = float(totalWeight > 0.0); + srcBlurred *= check / totalWeight + (1.0 - check); + srcBlurred.a = getOutputAlpha(); return srcBlurred; } @@ -160,9 +160,9 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep } } - if (totalWeight>0.0) { - srcBlurred /= totalWeight; - } + float check = float(totalWeight > 0.0); + srcBlurred *= check / totalWeight + (1.0 - check); + return srcBlurred; } From dc9405775f05bf38a4818bdfdfbe0ea4c0678f2a Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 25 Oct 2018 14:29:14 -0700 Subject: [PATCH 013/109] more branching removal --- .../InterleavedSrgbToLinear.slf | 4 +- .../src/display-plugins/SrgbToLinear.slf | 2 +- .../src/textured_particle.slv | 9 +- .../src/graphics/MaterialTextures.slh | 49 ++++----- libraries/graphics/src/graphics/skybox.slf | 10 +- .../render-utils/src/DeferredBufferRead.slh | 23 ++-- .../render-utils/src/DeferredBufferWrite.slh | 4 +- .../render-utils/src/DeferredTransform.slh | 3 +- libraries/render-utils/src/Fade.slh | 4 +- libraries/render-utils/src/Haze.slf | 15 ++- libraries/render-utils/src/Haze.slh | 14 +-- libraries/render-utils/src/Highlight.slh | 19 ++-- .../render-utils/src/LightClusterGrid.slh | 3 +- .../src/LightClusterGrid_shared.slh | 12 ++- libraries/render-utils/src/LightPoint.slh | 22 ++-- libraries/render-utils/src/LightSpot.slh | 30 +++--- libraries/render-utils/src/Shadow.slh | 20 +--- libraries/render-utils/src/Skinning.slh | 15 ++- .../render-utils/src/SubsurfaceScattering.slh | 5 +- .../src/deferred_light_limited.slv | 8 +- .../render-utils/src/deferred_light_point.slv | 4 +- .../render-utils/src/deferred_light_spot.slv | 4 +- .../src/directional_ambient_light.slf | 11 +- .../src/directional_ambient_light_shadow.slf | 12 +-- .../src/directional_skybox_light.slf | 12 +-- .../src/directional_skybox_light_shadow.slf | 12 +-- .../render-utils/src/drawWorkloadProxy.slv | 4 +- .../render-utils/src/forward_model_unlit.slf | 3 - libraries/render-utils/src/glowLine.slv | 10 +- libraries/render-utils/src/grid.slf | 10 +- .../src/lightClusters_drawClusterContent.slf | 2 +- .../src/lightClusters_drawClusterContent.slv | 2 +- .../lightClusters_drawClusterFromDepth.slf | 12 +-- .../lightClusters_drawClusterFromDepth.slv | 2 +- .../src/lightClusters_drawGrid.slv | 2 +- .../src/local_lights_drawOutline.slf | 11 +- libraries/render-utils/src/parabola.slv | 7 +- libraries/render-utils/src/sdf_text3D.slf | 20 +--- .../src/sdf_text3D_transparent.slf | 43 ++++---- libraries/render-utils/src/simple.slf | 2 +- .../render-utils/src/simple_textured.slf | 5 +- .../render-utils/src/simple_textured_fade.slf | 18 ++-- .../src/simple_textured_unlit.slf | 18 ++-- .../src/simple_textured_unlit_fade.slf | 18 ++-- .../src/simple_transparent_textured.slf | 9 +- .../src/simple_transparent_textured_fade.slf | 19 ++-- .../src/simple_transparent_textured_unlit.slf | 13 ++- ...simple_transparent_textured_unlit_fade.slf | 13 ++- libraries/render-utils/src/ssao.slh | 47 +++----- .../render-utils/src/ssao_debugOcclusion.slf | 27 ++--- .../render-utils/src/ssao_makeOcclusion.slf | 9 +- .../render-utils/src/stencil_drawMask.slf | 7 +- .../subsurfaceScattering_drawScattering.slf | 12 +-- .../src/surfaceGeometry_makeCurvature.slf | 12 +-- libraries/render-utils/src/taa.slf | 16 +-- libraries/render-utils/src/taa.slh | 100 ++++++++---------- libraries/render-utils/src/taa_blend.slf | 38 ++----- .../render-utils/src/zone_drawAmbient.slf | 2 +- .../render-utils/src/zone_drawSkybox.slf | 11 +- libraries/render/src/render/BlurTask.slh | 14 +-- .../render/src/render/drawCellBounds.slv | 2 +- .../render/src/render/drawItemBounds.slf | 10 +- .../render/src/render/drawItemBounds.slv | 7 +- .../render/src/render/drawItemStatus.slf | 11 +- 64 files changed, 356 insertions(+), 538 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf b/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf index e70053dcd9..66acff616c 100644 --- a/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf +++ b/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf @@ -14,8 +14,6 @@ void main(void) { ivec2 texCoord = ivec2(floor(varTexCoord0 * vec2(textureData.textureSize))); texCoord.x /= 2; int row = int(floor(gl_FragCoord.y)); - if (row % 2 > 0) { - texCoord.x += (textureData.textureSize.x / 2); - } + texCoord.x += int(row % 2 > 0) * (textureData.textureSize.x / 2); outFragColor = vec4(pow(texelFetch(colorMap, texCoord, 0).rgb, vec3(2.2)), 1.0); } diff --git a/libraries/display-plugins/src/display-plugins/SrgbToLinear.slf b/libraries/display-plugins/src/display-plugins/SrgbToLinear.slf index aad9e71e0e..8b324c81a5 100644 --- a/libraries/display-plugins/src/display-plugins/SrgbToLinear.slf +++ b/libraries/display-plugins/src/display-plugins/SrgbToLinear.slf @@ -9,7 +9,7 @@ layout(location=0) out vec4 outFragColor; float sRGBFloatToLinear(float value) { const float SRGB_ELBOW = 0.04045; - return (value <= SRGB_ELBOW) ? value / 12.92 : pow((value + 0.055) / 1.055, 2.4); + return mix(pow((value + 0.055) / 1.055, 2.4), value / 12.92, float(value <= SRGB_ELBOW)); } vec3 colorToLinearRGB(vec3 srgb) { diff --git a/libraries/entities-renderer/src/textured_particle.slv b/libraries/entities-renderer/src/textured_particle.slv index 4d17fe132b..98d25eae2e 100644 --- a/libraries/entities-renderer/src/textured_particle.slv +++ b/libraries/entities-renderer/src/textured_particle.slv @@ -80,10 +80,11 @@ float interpolate3Points(float y1, float y2, float y3, float u) { halfSlope = (y3 - y1) / 2.0f; float slope12 = y2 - y1; float slope23 = y3 - y2; - if (abs(halfSlope) > abs(slope12)) { - halfSlope = slope12; - } else if (abs(halfSlope) > abs(slope23)) { - halfSlope = slope23; + + { + float check = float(abs(halfSlope) > abs(slope12)); + halfSlope = mix(halfSlope, slope12, check); + halfSlope = mix(halfSlope, slope23, (1.0 - check) * float(abs(halfSlope) > abs(slope23))); } } diff --git a/libraries/graphics/src/graphics/MaterialTextures.slh b/libraries/graphics/src/graphics/MaterialTextures.slh index d393d0bcbd..615582dea5 100644 --- a/libraries/graphics/src/graphics/MaterialTextures.slh +++ b/libraries/graphics/src/graphics/MaterialTextures.slh @@ -151,37 +151,29 @@ float fetchScatteringMap(vec2 uv) { <@func fetchMaterialTexturesCoord0(matKey, texcoord0, albedo, roughness, normal, metallic, emissive, scattering)@> - float check; <@if albedo@> - check = float((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0); - vec4 <$albedo$> = check * fetchAlbedoMap(<$texcoord0$>) + vec4(1.0 - check); + vec4 <$albedo$> = mix(vec4(1.0), fetchAlbedoMap(<$texcoord0$>), float((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0)); <@endif@> <@if roughness@> - check = float((<$matKey$> & ROUGHNESS_MAP_BIT) != 0); - float <$roughness$> = check * fetchRoughnessMap(<$texcoord0$>) + (1.0 - check); + float <$roughness$> = mix(1.0, fetchRoughnessMap(<$texcoord0$>), float((<$matKey$> & ROUGHNESS_MAP_BIT) != 0)); <@endif@> <@if normal@> - check = float((<$matKey$> & NORMAL_MAP_BIT) != 0); - vec3 <$normal$> = check * fetchNormalMap(<$texcoord0$>) + vec3(0.0, 1.0 - check, 0.0); + vec3 <$normal$> = mix(vec3(0.0, 1.0, 0.0), fetchNormalMap(<$texcoord0$>), float((<$matKey$> & NORMAL_MAP_BIT) != 0)); <@endif@> <@if metallic@> - check = float((<$matKey$> & METALLIC_MAP_BIT) != 0); - float <$metallic$> = check * fetchMetallicMap(<$texcoord0$>); + float <$metallic$> = float((<$matKey$> & METALLIC_MAP_BIT) != 0) * fetchMetallicMap(<$texcoord0$>); <@endif@> <@if emissive@> - check = float((<$matKey$> & EMISSIVE_MAP_BIT) != 0); - vec3 <$emissive$> = check * fetchEmissiveMap(<$texcoord0$>); + vec3 <$emissive$> = float((<$matKey$> & EMISSIVE_MAP_BIT) != 0) * fetchEmissiveMap(<$texcoord0$>); <@endif@> <@if scattering@> - check = float((<$matKey$> & SCATTERING_MAP_BIT) != 0); - float <$scattering$> = check * fetchScatteringMap(<$texcoord0$>); + float <$scattering$> = float((<$matKey$> & SCATTERING_MAP_BIT) != 0) * fetchScatteringMap(<$texcoord0$>); <@endif@> <@endfunc@> <@func fetchMaterialTexturesCoord1(matKey, texcoord1, occlusion, lightmapVal)@> <@if occlusion@> - float check1 = float((<$matKey$> & OCCLUSION_MAP_BIT) != 0); - float <$occlusion$> = check1 * fetchOcclusionMap(<$texcoord1$>) + (1.0 - check1); + float <$occlusion$> = mix(1.0, fetchOcclusionMap(<$texcoord1$>), float((<$matKey$> & OCCLUSION_MAP_BIT) != 0)); <@endif@> <@if lightmapVal@> vec3 <$lightmapVal$> = fetchLightmapMap(<$texcoord1$>); @@ -225,20 +217,19 @@ vec3 fetchLightmapMap(vec2 uv) { <@func evalMaterialAlbedo(fetchedAlbedo, materialAlbedo, matKey, albedo)@> { - float check = float((<$matKey$> & ALBEDO_VAL_BIT) != 0); - <$albedo$>.xyz = check * <$materialAlbedo$> + vec3(1.0 - check); - - check = float((<$matKey$> & ALBEDO_MAP_BIT) != 0); - <$albedo$>.xyz *= check * <$fetchedAlbedo$>.xyz + vec3(1.0 - check); + <$albedo$>.xyz = mix(vec3(1.0), <$materialAlbedo$>, float((<$matKey$> & ALBEDO_VAL_BIT) != 0)); + <$albedo$>.xyz *= mix(vec3(1.0), <$fetchedAlbedo$>.xyz, float((<$matKey$> & ALBEDO_MAP_BIT) != 0)); } <@endfunc@> <@func evalMaterialOpacity(fetchedOpacity, materialOpacity, matKey, opacity)@> { const float OPACITY_MASK_THRESHOLD = 0.5; - float check = float((<$matKey$> & (OPACITY_TRANSLUCENT_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0); - float check2 = float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0); - <$opacity$> = (check * (check2 * step(OPACITY_MASK_THRESHOLD, <$fetchedOpacity$>) + (1.0 - check2) * <$fetchedOpacity$>) + (1.0 - check)) * <$materialOpacity$>; + <$opacity$> = mix(1.0, + mix(<$fetchedOpacity$>, + step(OPACITY_MASK_THRESHOLD, <$fetchedOpacity$>), + float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0)), + float((<$matKey$> & (OPACITY_TRANSLUCENT_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0)) * <$materialOpacity$>; } <@endfunc@> @@ -259,22 +250,19 @@ vec3 fetchLightmapMap(vec2 uv) { <@func evalMaterialRoughness(fetchedRoughness, materialRoughness, matKey, roughness)@> { - float check = float((<$matKey$> & ROUGHNESS_MAP_BIT) != 0); - <$roughness$> = check * <$fetchedRoughness$> + (1.0 - check) * <$materialRoughness$>; + <$roughness$> = mix(<$materialRoughness$>, <$fetchedRoughness$>, float((<$matKey$> & ROUGHNESS_MAP_BIT) != 0)); } <@endfunc@> <@func evalMaterialMetallic(fetchedMetallic, materialMetallic, matKey, metallic)@> { - float check = float((<$matKey$> & METALLIC_MAP_BIT) != 0); - <$metallic$> = check * <$fetchedMetallic$> + (1.0 - check) * <$materialMetallic$>; + <$metallic$> = mix(<$materialMetallic$>, <$fetchedMetallic$>, float((<$matKey$> & METALLIC_MAP_BIT) != 0)); } <@endfunc@> <@func evalMaterialEmissive(fetchedEmissive, materialEmissive, matKey, emissive)@> { - float check = float((<$matKey$> & EMISSIVE_MAP_BIT) != 0); - <$emissive$> = check * <$fetchedEmissive$> + (1.0 - check) * <$materialEmissive$>; + <$emissive$> = mix(<$materialEmissive$>, <$fetchedEmissive$>, float((<$matKey$> & EMISSIVE_MAP_BIT) != 0)); } <@endfunc@> @@ -286,8 +274,7 @@ vec3 fetchLightmapMap(vec2 uv) { <@func evalMaterialScattering(fetchedScattering, materialScattering, matKey, scattering)@> { - float check = float((<$matKey$> & SCATTERING_MAP_BIT) != 0); - <$scattering$> = check * <$fetchedScattering$> + (1.0 - check) * <$materialScattering$>; + <$scattering$> = mix(<$materialScattering$>, <$fetchedScattering$>, float((<$matKey$> & SCATTERING_MAP_BIT) != 0)); } <@endfunc@> diff --git a/libraries/graphics/src/graphics/skybox.slf b/libraries/graphics/src/graphics/skybox.slf index b24bf0f583..c20dd94bf4 100755 --- a/libraries/graphics/src/graphics/skybox.slf +++ b/libraries/graphics/src/graphics/skybox.slf @@ -30,11 +30,9 @@ void main(void) { vec3 color = skybox.color.rgb; // blend is only set if there is a cubemap - if (skybox.color.a > 0.0) { - color = texture(cubeMap, coord).rgb; - if (skybox.color.a < 1.0) { - color *= skybox.color.rgb; - } - } + float check = float(skybox.color.a > 0.0); + color = mix(color, texture(cubeMap, coord).rgb, check); + color *= mix(vec3(1.0), skybox.color.rgb, check * float(skybox.color.a < 1.0)); + _fragColor = vec4(color, 0.0); } diff --git a/libraries/render-utils/src/DeferredBufferRead.slh b/libraries/render-utils/src/DeferredBufferRead.slh index bf0100d0d3..a6a6a6b1ac 100644 --- a/libraries/render-utils/src/DeferredBufferRead.slh +++ b/libraries/render-utils/src/DeferredBufferRead.slh @@ -79,10 +79,7 @@ DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) { unpackModeMetallic(diffuseVal.w, frag.mode, frag.metallic); frag.obscurance = min(specularVal.w, frag.obscurance); - - float check = float(frag.mode == FRAG_MODE_SCATTERING); - frag.scattering = check * specularVal.x; - + frag.scattering = float(frag.mode == FRAG_MODE_SCATTERING) * specularVal.x; frag.fresnel = getFresnelF0(frag.metallic, diffuseVal.xyz); return frag; @@ -121,10 +118,10 @@ DeferredFragment unpackDeferredFragmentNoPositionNoAmbient(vec2 texcoord) { vec4 unpackDeferredPosition(float depthValue, vec2 texcoord) { float check = float(isStereo()); - float check2 = float(texcoord.x > 0.5); - texcoord.x -= check * check2 * 0.5; - int side = int(check * check2); - texcoord.x *= check * 2.0 + (1.0 - check) * 1.0; + float check2 = check * float(texcoord.x > 0.5); + texcoord.x -= check2 * 0.5; + int side = int(check2); + texcoord.x *= mix(1.0, 2.0, check); return vec4(evalEyePositionFromZdb(side, depthValue, texcoord), 1.0); } @@ -137,11 +134,13 @@ vec4 unpackDeferredPositionFromZdb(vec2 texcoord) { vec4 unpackDeferredPositionFromZeye(vec2 texcoord) { float Zeye = -texture(linearZeyeMap, texcoord).x; + float check = float(isStereo()); - float check2 = float(texcoord.x > 0.5); - texcoord.x -= check * check2 * 0.5; - int side = int(check * check2); - texcoord.x *= check * 2.0 + (1.0 - check) * 1.0; + float check2 = check * float(texcoord.x > 0.5); + texcoord.x -= check2 * 0.5; + int side = int(check2); + texcoord.x *= mix(1.0, 2.0, check); + return vec4(evalEyePositionFromZeye(side, Zeye, texcoord), 1.0); } diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh index a531affd85..fe2f518665 100644 --- a/libraries/render-utils/src/DeferredBufferWrite.slh +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -34,9 +34,9 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness } float check = float(scattering > 0.0); - _fragColor0 = vec4(albedo, check * packScatteringMetallic(metallic) + (1.0 - check) * packShadedMetallic(metallic)); + _fragColor0 = vec4(albedo, mix(packShadedMetallic(metallic), packScatteringMetallic(metallic), check)); _fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0)); - _fragColor2 = vec4(check * vec3(scattering) + (1.0 - check) * emissive, occlusion); + _fragColor2 = vec4(mix(emissive, vec3(scattering), check), occlusion); _fragColor3 = vec4(isEmissiveEnabled() * emissive, 1.0); } diff --git a/libraries/render-utils/src/DeferredTransform.slh b/libraries/render-utils/src/DeferredTransform.slh index 3ec763efe2..434cc18c1f 100644 --- a/libraries/render-utils/src/DeferredTransform.slh +++ b/libraries/render-utils/src/DeferredTransform.slh @@ -126,8 +126,7 @@ vec2 getSideImageSize(int resolutionLevel) { ivec4 getStereoSideInfo(int xPos, int resolutionLevel) { int sideWidth = int(getStereoSideWidth(resolutionLevel)); - int check = int(xPos < sideWidth); - return ivec4((1 - check) * ivec2(1, sideWidth), sideWidth, isStereo()); + return ivec4((1 - int(xPos < sideWidth)) * ivec2(1, sideWidth), sideWidth, isStereo()); } float evalZeyeFromZdb(float depth) { diff --git a/libraries/render-utils/src/Fade.slh b/libraries/render-utils/src/Fade.slh index 6770f53200..1ff0e2c01d 100644 --- a/libraries/render-utils/src/Fade.slh +++ b/libraries/render-utils/src/Fade.slh @@ -86,9 +86,7 @@ float evalFadeGradient(FadeObjectParams params, vec3 position) { float evalFadeAlpha(FadeObjectParams params, vec3 position) { float alpha = evalFadeGradient(params, position) - params.threshold; - - float check = float(fadeParameters[params.category]._isInverted != 0); - alpha *= -check + (1.0 - check); + alpha *= mix(1.0, -1.0, float(fadeParameters[params.category]._isInverted != 0)); return alpha; } diff --git a/libraries/render-utils/src/Haze.slf b/libraries/render-utils/src/Haze.slf index 8d90b4c816..b64d4172c6 100644 --- a/libraries/render-utils/src/Haze.slf +++ b/libraries/render-utils/src/Haze.slf @@ -25,14 +25,13 @@ LAYOUT(binding=RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH) uniform sampler2D linearD vec4 unpackPositionFromZeye(vec2 texcoord) { float Zeye = -texture(linearDepthMap, texcoord).x; - int side = 0; - if (isStereo()) { - if (texcoord.x > 0.5) { - texcoord.x -= 0.5; - side = 1; - } - texcoord.x *= 2.0; - } + + float check = float(isStereo()); + float check2 = check * float(texcoord.x > 0.5); + texcoord.x -= check2 * 0.5; + int side = int(check2); + texcoord.x *= mix(1.0, 2.0, check); + return vec4(evalEyePositionFromZeye(side, Zeye, texcoord), 1.0); } diff --git a/libraries/render-utils/src/Haze.slh b/libraries/render-utils/src/Haze.slh index f5795565cc..0bf1d5d689 100644 --- a/libraries/render-utils/src/Haze.slh +++ b/libraries/render-utils/src/Haze.slh @@ -64,9 +64,8 @@ vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirectionWS, vec3 float height_95p = 2000.0; const float log_p_005 = log(0.05); - { - float check = float(hazeParams.hazeKeyLightAltitudeFactor > 0.0f); - height_95p = check * -log_p_005 / hazeParams.hazeKeyLightAltitudeFactor + (1.0 - check) * height_95p; + if (hazeParams.hazeKeyLightAltitudeFactor > 0.0f) { + height_95p = -log_p_005 / hazeParams.hazeKeyLightAltitudeFactor; } // Note that we need the sine to be positive @@ -144,8 +143,7 @@ vec4 computeHazeColor(vec3 fragPositionES, vec3 fragPositionWS, vec3 eyePosition float deltaHeight = fragPositionWS.y - eyeWorldHeight; float t = hazeParams.hazeHeightFactor * deltaHeight; if (abs(t) > EPSILON) { - float check = float(abs(deltaHeight) > slopeThreshold); - hazeIntegral *= check * (1.0 - exp(-t)) / t + (1.0 - check); + hazeIntegral *= mix(1.0, (1.0 - exp(-t)) / t, float(abs(deltaHeight) > slopeThreshold)); } vec3 hazeAmount = 1.0 - exp(-hazeIntegral); @@ -173,8 +171,7 @@ vec4 computeHazeColor(vec3 fragPositionES, vec3 fragPositionWS, vec3 eyePosition float deltaHeight = fragPositionWS.y - eyeWorldHeight; float t = hazeParams.hazeHeightFactor * deltaHeight; if (abs(t) > EPSILON) { - float check = float(abs(deltaHeight) > slopeThreshold); - hazeIntegral *= check * (1.0 - exp(-t)) / t + (1.0 - check); + hazeIntegral *= mix(1.0, (1.0 - exp(-t)) / t, float(abs(deltaHeight) > slopeThreshold)); } float hazeAmount = 1.0 - exp(-hazeIntegral); @@ -186,8 +183,7 @@ vec4 computeHazeColor(vec3 fragPositionES, vec3 fragPositionWS, vec3 eyePosition // Mix with background at far range const float BLEND_DISTANCE = 27000.0f; vec4 outFragColor = potentialFragColor; - float check = float(distance > BLEND_DISTANCE); - outFragColor.a *= check * hazeParams.backgroundBlend + (1.0 - check); + outFragColor.a *= mix(1.0, hazeParams.backgroundBlend, float(distance > BLEND_DISTANCE)); return outFragColor; } diff --git a/libraries/render-utils/src/Highlight.slh b/libraries/render-utils/src/Highlight.slh index eee22ecb0a..85ff352207 100644 --- a/libraries/render-utils/src/Highlight.slh +++ b/libraries/render-utils/src/Highlight.slh @@ -45,9 +45,9 @@ void main(void) { highlightedDepth = -evalZeyeFromZdb(highlightedDepth); sceneDepth = -evalZeyeFromZdb(sceneDepth); - float check = float(sceneDepth < highlightedDepth); - outFragColor = check * vec4(params._fillOccludedColor, params._fillOccludedAlpha) + - (1.0 - check) * vec4(params._fillUnoccludedColor, params._fillUnoccludedAlpha); + outFragColor = mix(vec4(params._fillUnoccludedColor, params._fillUnoccludedAlpha), + vec4(params._fillOccludedColor, params._fillOccludedAlpha), + float(sceneDepth < highlightedDepth)); <@else@> discard; <@endif@> @@ -83,10 +83,7 @@ void main(void) { } } - { - float check = float(intensity > 0.0); - sumOutlineDepth = check * sumOutlineDepth + (1.0 - check) * FAR_Z; - } + sumOutlineDepth = mix(FAR_Z, sumOutlineDepth, float(intensity > 0.0)); intensity /= weight; if (intensity < OPACITY_EPSILON) { @@ -102,11 +99,9 @@ void main(void) { sceneDepth = -evalZeyeFromZdb(sceneDepth); // Are we occluded? - { - float check = float(sceneDepth < outlinedDepth); - outFragColor = check * vec4(params._outlineOccludedColor, intensity * params._outlineOccludedAlpha) + - (1.0 - check) * vec4(params._outlineUnoccludedColor, intensity * params._outlineUnoccludedAlpha); - } + outFragColor = mix(vec4(params._outlineUnoccludedColor, intensity * params._outlineUnoccludedAlpha), + vec4(params._outlineOccludedColor, intensity * params._outlineOccludedAlpha), + float(sceneDepth < outlinedDepth)); } } diff --git a/libraries/render-utils/src/LightClusterGrid.slh b/libraries/render-utils/src/LightClusterGrid.slh index 46eba68fff..df8ba001f5 100644 --- a/libraries/render-utils/src/LightClusterGrid.slh +++ b/libraries/render-utils/src/LightClusterGrid.slh @@ -83,8 +83,7 @@ int clusterGrid_getClusterLightId(int index, int offset) { return element; */ int element = _clusterGridContent[GRID_FETCH_BUFFER((elementIndex >> 1))]; - int check = int((elementIndex & 0x00000001) == 1); - return (check * (element >> 16) + (1 - check) * element) & 0x0000FFFF; + return int(mix(element, element >> 16, int((elementIndex & 0x00000001) == 1))) & 0x0000FFFF; } diff --git a/libraries/render-utils/src/LightClusterGrid_shared.slh b/libraries/render-utils/src/LightClusterGrid_shared.slh index be9d980062..476ca6284f 100644 --- a/libraries/render-utils/src/LightClusterGrid_shared.slh +++ b/libraries/render-utils/src/LightClusterGrid_shared.slh @@ -7,8 +7,12 @@ #ifdef __cplusplus # define _MIN glm::min +# define _MIX(x, y, a) glm::mix((float)x, (float)y, (float)a) +# define _ABS(x) (int)fabsf() #else # define _MIN min +# define _MIX mix +# define _ABS abs #endif float frustumGrid_depthRampGridToVolume(float ngrid) { @@ -124,7 +128,7 @@ ivec3 frustumGrid_eyeToClusterPos(vec3 eyePos) { // make sure the frontEyePos is always in the front to eval the grid pos correctly vec3 frontEyePos = eyePos; - frontEyePos.z = -abs(eyePos.z); + frontEyePos.z = -_ABS(eyePos.z); vec3 volumePos = frustumGrid_eyeToVolume(frontEyePos, frustumGrid.eyeToGridProj, frustumGrid.rangeNear, frustumGrid.rangeFar); @@ -147,8 +151,7 @@ ivec3 frustumGrid_eyeToClusterPos(vec3 eyePos) { int frustumGrid_eyeToClusterDirH(vec3 eyeDir) { if (eyeDir.z >= 0.0f) { - int check = int(eyeDir.x > 0.0f); - return check * frustumGrid.dims.x + (check - 1); + return int(_MIX(-1, frustumGrid.dims.x, int(eyeDir.x > 0.0f))); } float eyeDepth = -eyeDir.z; @@ -162,8 +165,7 @@ int frustumGrid_eyeToClusterDirH(vec3 eyeDir) { int frustumGrid_eyeToClusterDirV(vec3 eyeDir) { if (eyeDir.z >= 0.0f) { - int check = int(eyeDir.y > 0.0f); - return check * frustumGrid.dims.y + (check - 1); + return int(_MIX(-1, frustumGrid.dims.y, int(eyeDir.y > 0.0f))); } float eyeDepth = -eyeDir.z; diff --git a/libraries/render-utils/src/LightPoint.slh b/libraries/render-utils/src/LightPoint.slh index f5cda3d9d4..7c59cf85ef 100644 --- a/libraries/render-utils/src/LightPoint.slh +++ b/libraries/render-utils/src/LightPoint.slh @@ -39,14 +39,11 @@ void evalLightingPoint(out vec3 diffuse, out vec3 specular, Light light, lightEnergy *= isPointEnabled(); diffuse *= lightEnergy * isDiffuseEnabled(); specular *= lightEnergy * isSpecularEnabled(); - - { - // Show edges - float edge = abs(2.0 * ((lightVolume_getRadius(light.volume) - fragLightDistance) / (0.1)) - 1.0); - float check = float(isShowLightContour() > 0.0 && edge < 1.0); - float edgeCoord = exp2(-8.0 * edge * edge); - diffuse = check * vec3(edgeCoord * edgeCoord * getLightColor(light)) + (1.0 - check) * diffuse; - } + + // Show edges + float edge = abs(2.0 * ((lightVolume_getRadius(light.volume) - fragLightDistance) / (0.1)) - 1.0); + float edgeCoord = exp2(-8.0 * edge * edge); + diffuse = mix(diffuse, vec3(edgeCoord * edgeCoord * getLightColor(light)), float(isShowLightContour() > 0.0 && edge < 1.0)); } <@endfunc@> @@ -59,13 +56,10 @@ bool evalLightPointEdge(out vec3 color, Light light, vec4 fragLightDirLen, vec3 float fragLightDistance = fragLightDirLen.w; vec3 fragLightDir = fragLightDirLen.xyz; + // Show edges float edge = abs(2.0 * ((lightVolume_getRadius(light.volume) - fragLightDistance) / (0.1)) - 1.0); - { - // Show edges - float check = float(edge < 1.0); - float edgeCoord = exp2(-8.0 * edge * edge); - color = check * vec3(edgeCoord * edgeCoord * getLightColor(light)) + (1.0 - check) * color; - } + float edgeCoord = exp2(-8.0 * edge * edge); + color = mix(color, vec3(edgeCoord * edgeCoord * getLightColor(light)), float(edge < 1.0)); return (edge < 1.0); } diff --git a/libraries/render-utils/src/LightSpot.slh b/libraries/render-utils/src/LightSpot.slh index 395fe892e7..799021c459 100644 --- a/libraries/render-utils/src/LightSpot.slh +++ b/libraries/render-utils/src/LightSpot.slh @@ -40,17 +40,14 @@ void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light, lightEnergy *= isSpotEnabled(); diffuse *= lightEnergy * isDiffuseEnabled(); specular *= lightEnergy * isSpecularEnabled(); - - { - // Show edges - float edgeDistR = (lightVolume_getRadius(light.volume) - fragLightDistance); - float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -lightVolume_getSpotOutsideNormal2(light.volume)); - float edgeDist = min(edgeDistR, edgeDistS); - float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0); - float check = float(isShowLightContour() > 0.0 && edge < 1.0); - float edgeCoord = exp2(-8.0 * edge * edge); - diffuse = check * vec3(edgeCoord * edgeCoord * getLightColor(light)) + (1.0 - check) * diffuse; - } + + // Show edges + float edgeDistR = (lightVolume_getRadius(light.volume) - fragLightDistance); + float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -lightVolume_getSpotOutsideNormal2(light.volume)); + float edgeDist = min(edgeDistR, edgeDistS); + float edge = abs(2.0 * (edgeDist * 10.0) - 1.0); + float edgeCoord = exp2(-8.0 * edge * edge); + diffuse = mix(diffuse, vec3(edgeCoord * edgeCoord * getLightColor(light)), float(isShowLightContour() > 0.0 && edge < 1.0)); } <@endfunc@> @@ -62,16 +59,13 @@ bool evalLightSpotEdge(out vec3 color, Light light, vec4 fragLightDirLen, float float fragLightDistance = fragLightDirLen.w; vec3 fragLightDir = fragLightDirLen.xyz; + // Show edges float edgeDistR = (lightVolume_getRadius(light.volume) - fragLightDistance); float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -lightVolume_getSpotOutsideNormal2(light.volume)); float edgeDist = min(edgeDistR, edgeDistS); - float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0); - { - // Show edges - float check = float(edge < 1.0); - float edgeCoord = exp2(-8.0 * edge * edge); - color = check * vec3(edgeCoord * edgeCoord * getLightColor(light)) + (1.0 - check) * color; - } + float edge = abs(2.0 * (edgeDist * 10.0) - 1.0); + float edgeCoord = exp2(-8.0 * edge * edge); + color = mix(color, vec3(edgeCoord * edgeCoord * getLightColor(light)), float(edge < 1.0)); return (edge < 1.0); } diff --git a/libraries/render-utils/src/Shadow.slh b/libraries/render-utils/src/Shadow.slh index 10922350ed..b503844554 100644 --- a/libraries/render-utils/src/Shadow.slh +++ b/libraries/render-utils/src/Shadow.slh @@ -115,22 +115,10 @@ float evalShadowAttenuation(vec3 worldLightDir, vec4 worldPosition, float viewDe isPixelOnCascade.z = isShadowCascadeProjectedOnPixel(cascadeShadowCoords[2]); isPixelOnCascade.w = isShadowCascadeProjectedOnPixel(cascadeShadowCoords[3]); - { - float check = float(isPixelOnCascade.x); - cascadeAttenuations.x = check * evalShadowCascadeAttenuation(0, offsets, cascadeShadowCoords[0], oneMinusNdotL) + (1.0 - check); - } - { - float check = float(isPixelOnCascade.y); - cascadeAttenuations.y = check * evalShadowCascadeAttenuation(1, offsets, cascadeShadowCoords[1], oneMinusNdotL) + (1.0 - check); - } - { - float check = float(isPixelOnCascade.z); - cascadeAttenuations.z = check * evalShadowCascadeAttenuation(2, offsets, cascadeShadowCoords[2], oneMinusNdotL) + (1.0 - check); - } - { - float check = float(isPixelOnCascade.w); - cascadeAttenuations.w = check * evalShadowCascadeAttenuation(3, offsets, cascadeShadowCoords[3], oneMinusNdotL) + (1.0 - check); - } + cascadeAttenuations.x = mix(1.0, evalShadowCascadeAttenuation(0, offsets, cascadeShadowCoords[0], oneMinusNdotL), float(isPixelOnCascade.x)); + cascadeAttenuations.y = mix(1.0, evalShadowCascadeAttenuation(1, offsets, cascadeShadowCoords[1], oneMinusNdotL), float(isPixelOnCascade.y)); + cascadeAttenuations.z = mix(1.0, evalShadowCascadeAttenuation(2, offsets, cascadeShadowCoords[2], oneMinusNdotL), float(isPixelOnCascade.z)); + cascadeAttenuations.w = mix(1.0, evalShadowCascadeAttenuation(3, offsets, cascadeShadowCoords[3], oneMinusNdotL), float(isPixelOnCascade.w)); cascadeWeights.x = evalShadowCascadeWeight(cascadeShadowCoords[0]); cascadeWeights.y = evalShadowCascadeWeight(cascadeShadowCoords[1]); diff --git a/libraries/render-utils/src/Skinning.slh b/libraries/render-utils/src/Skinning.slh index 63246e85a1..30d5efd64e 100644 --- a/libraries/render-utils/src/Skinning.slh +++ b/libraries/render-utils/src/Skinning.slh @@ -81,9 +81,7 @@ void evalSkinning(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPositio // to ensure that we rotate along the shortest arc, reverse dual quaternions with negative polarity. float dqClusterWeight = clusterWeight; - if (dot(real, polarityReference) < 0.0) { - dqClusterWeight = -clusterWeight; - } + dqClusterWeight *= mix(1.0, -1.0, float(dot(real, polarityReference) < 0.0)); sAccum += scale * clusterWeight; rAccum += real * dqClusterWeight; @@ -102,12 +100,11 @@ void evalSkinning(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPositio // sAccum.w indicates the amount of cauterization for this vertex. // 0 indicates no cauterization and 1 indicates full cauterization. // TODO: make this cauterization smoother or implement full dual-quaternion scale support. - const float CAUTERIZATION_THRESHOLD = 0.1; - if (sAccum.w > CAUTERIZATION_THRESHOLD) { - skinnedPosition = cAccum; - } else { - sAccum.w = 1.0; - skinnedPosition = m * (sAccum * inPosition); + { + const float CAUTERIZATION_THRESHOLD = 0.1; + float check = float(sAccum.w > CAUTERIZATION_THRESHOLD); + sAccum.w = mix(1.0, sAccum.w, check); + skinnedPosition = mix(m * (sAccum * inPosition), cAccum, check); } <@if USE_NORMAL@> diff --git a/libraries/render-utils/src/SubsurfaceScattering.slh b/libraries/render-utils/src/SubsurfaceScattering.slh index 66b3ab1ea0..b4981110f2 100644 --- a/libraries/render-utils/src/SubsurfaceScattering.slh +++ b/libraries/render-utils/src/SubsurfaceScattering.slh @@ -82,8 +82,6 @@ vec3 integrate(float cosTheta, float skinRadius) { while (a <= (_PI)) { float sampleAngle = theta + a; float diffuse = clamp(cos(sampleAngle), 0.0, 1.0); - //if (diffuse < 0.0) diffuse = 0.0; - //if (diffuse > 1.0) diffuse = 1.0; // Distance. float sampleDist = abs(2.0 * skinRadius * sin(a * 0.5)); @@ -180,7 +178,8 @@ vec3 evalSkinBRDF(vec3 lightDir, vec3 normal, vec3 midNormal, vec3 lowNormal, fl return lowNormal * 0.5 + vec3(0.5); } if (showCurvature()) { - return (curvature > 0.0 ? vec3(curvature, 0.0, 0.0) : vec3(0.0, 0.0, -curvature)); + float check = float(curvature > 0.0); + return vec3(check * curvature, 0.0, (1.0 - check) * -curvature); } vec3 bentNdotL = evalScatteringBentNdotL(normal, midNormal, lowNormal, lightDir); diff --git a/libraries/render-utils/src/deferred_light_limited.slv b/libraries/render-utils/src/deferred_light_limited.slv index 1c835aacf7..0126d54664 100644 --- a/libraries/render-utils/src/deferred_light_limited.slv +++ b/libraries/render-utils/src/deferred_light_limited.slv @@ -37,9 +37,7 @@ void main(void) { #ifdef GPU_TRANSFORM_IS_STEREO #ifdef GPU_TRANSFORM_STEREO_SPLIT_SCREEN #else - if (cam_isStereo()) { - projected.x = 0.5 * (projected.x + cam_getStereoSide()); - } + projected.x = mix(projected.x, 0.5 * (projected.x + cam_getStereoSide()), float(cam_isStereo())); #endif #endif _texCoord01 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w; @@ -66,9 +64,7 @@ void main(void) { #ifdef GPU_TRANSFORM_IS_STEREO #ifdef GPU_TRANSFORM_STEREO_SPLIT_SCREEN #else - if (cam_isStereo()) { - _texCoord01.x = 0.5 * (_texCoord01.x + cam_getStereoSide()); - } + _texCoord01.x = mix(_texCoord01.x, 0.5 * (_texCoord01.x + cam_getStereoSide()), float(cam_isStereo())); #endif #endif diff --git a/libraries/render-utils/src/deferred_light_point.slv b/libraries/render-utils/src/deferred_light_point.slv index 3e6329be83..c77ead439c 100644 --- a/libraries/render-utils/src/deferred_light_point.slv +++ b/libraries/render-utils/src/deferred_light_point.slv @@ -47,8 +47,6 @@ void main(void) { vec4 projected = gl_Position / gl_Position.w; projected.xy = (projected.xy + 1.0) * 0.5; - if (cam_isStereo()) { - projected.x = 0.5 * (projected.x + cam_getStereoSide()); - } + projected.x = mix(projected.x, 0.5 * (projected.x + cam_getStereoSide()), float(cam_isStereo())); _texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w; } diff --git a/libraries/render-utils/src/deferred_light_spot.slv b/libraries/render-utils/src/deferred_light_spot.slv index 0370acc6bc..332bb96167 100644 --- a/libraries/render-utils/src/deferred_light_spot.slv +++ b/libraries/render-utils/src/deferred_light_spot.slv @@ -60,9 +60,7 @@ void main(void) { #ifdef GPU_TRANSFORM_IS_STEREO #ifdef GPU_TRANSFORM_STEREO_SPLIT_SCREEN #else - if (cam_isStereo()) { - projected.x = 0.5 * (projected.x + cam_getStereoSide()); - } + projected.x = mix(projected.x, 0.5 * (projected.x + cam_getStereoSide()), float(cam_isStereo())); #endif #endif _texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w; diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index 15d00f713e..b1cfc26c66 100644 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -33,16 +33,15 @@ void main(void) { float shadowAttenuation = 1.0; - if (frag.mode == FRAG_MODE_UNLIT) { - discard; - } else if (frag.mode == FRAG_MODE_LIGHTMAPPED) { + if (frag.mode == FRAG_MODE_UNLIT || frag.mode == FRAG_MODE_LIGHTMAPPED) { discard; } else { vec4 midNormalCurvature = vec4(0); vec4 lowNormalCurvature = vec4(0); - if (frag.mode == FRAG_MODE_SCATTERING) { - unpackMidLowNormalCurvature(_texCoord0, midNormalCurvature, lowNormalCurvature); - } + unpackMidLowNormalCurvature(_texCoord0, midNormalCurvature, lowNormalCurvature); + float check = float(frag.mode == FRAG_MODE_SCATTERING); + midNormalCurvature = check * midNormalCurvature; + lowNormalCurvature = check * lowNormalCurvature; vec3 color = evalAmbientSphereGlobalColor( getViewInverse(), diff --git a/libraries/render-utils/src/directional_ambient_light_shadow.slf b/libraries/render-utils/src/directional_ambient_light_shadow.slf index d6cdf78f19..6b9fb80232 100644 --- a/libraries/render-utils/src/directional_ambient_light_shadow.slf +++ b/libraries/render-utils/src/directional_ambient_light_shadow.slf @@ -35,16 +35,16 @@ void main(void) { vec3 worldLightDirection = getLightDirection(shadowLight); float shadowAttenuation = evalShadowAttenuation(worldLightDirection, worldPos, -viewPos.z, frag.normal); - if (frag.mode == FRAG_MODE_UNLIT) { - discard; - } else if (frag.mode == FRAG_MODE_LIGHTMAPPED) { + if (frag.mode == FRAG_MODE_UNLIT || frag.mode == FRAG_MODE_LIGHTMAPPED) { discard; } else { vec4 midNormalCurvature = vec4(0); vec4 lowNormalCurvature = vec4(0); - if (frag.mode == FRAG_MODE_SCATTERING) { - unpackMidLowNormalCurvature(_texCoord0, midNormalCurvature, lowNormalCurvature); - } + unpackMidLowNormalCurvature(_texCoord0, midNormalCurvature, lowNormalCurvature); + float check = float(frag.mode == FRAG_MODE_SCATTERING); + midNormalCurvature = check * midNormalCurvature; + lowNormalCurvature = check * lowNormalCurvature; + vec3 color = evalAmbientSphereGlobalColor( getViewInverse(), shadowAttenuation, diff --git a/libraries/render-utils/src/directional_skybox_light.slf b/libraries/render-utils/src/directional_skybox_light.slf index b27d759dd4..b820b3d17f 100644 --- a/libraries/render-utils/src/directional_skybox_light.slf +++ b/libraries/render-utils/src/directional_skybox_light.slf @@ -31,16 +31,16 @@ void main(void) { float shadowAttenuation = 1.0; // Light mapped or not ? - if (frag.mode == FRAG_MODE_UNLIT) { - discard; - } else if (frag.mode == FRAG_MODE_LIGHTMAPPED) { + if (frag.mode == FRAG_MODE_UNLIT || frag.mode == FRAG_MODE_LIGHTMAPPED) { discard; } else { vec4 midNormalCurvature = vec4(0); vec4 lowNormalCurvature = vec4(0); - if (frag.mode == FRAG_MODE_SCATTERING) { - unpackMidLowNormalCurvature(_texCoord0, midNormalCurvature, lowNormalCurvature); - } + unpackMidLowNormalCurvature(_texCoord0, midNormalCurvature, lowNormalCurvature); + float check = float(frag.mode == FRAG_MODE_SCATTERING); + midNormalCurvature = check * midNormalCurvature; + lowNormalCurvature = check * lowNormalCurvature; + vec3 color = evalSkyboxGlobalColor( getViewInverse(), shadowAttenuation, diff --git a/libraries/render-utils/src/directional_skybox_light_shadow.slf b/libraries/render-utils/src/directional_skybox_light_shadow.slf index 292f7348e3..8716d60d54 100644 --- a/libraries/render-utils/src/directional_skybox_light_shadow.slf +++ b/libraries/render-utils/src/directional_skybox_light_shadow.slf @@ -36,16 +36,16 @@ void main(void) { float shadowAttenuation = evalShadowAttenuation(worldLightDirection, worldPos, -viewPos.z, frag.normal); // Light mapped or not ? - if (frag.mode == FRAG_MODE_UNLIT) { - discard; - } else if (frag.mode == FRAG_MODE_LIGHTMAPPED) { + if (frag.mode == FRAG_MODE_UNLIT || frag.mode == FRAG_MODE_LIGHTMAPPED) { discard; } else { vec4 midNormalCurvature = vec4(0); vec4 lowNormalCurvature = vec4(0); - if (frag.mode == FRAG_MODE_SCATTERING) { - unpackMidLowNormalCurvature(_texCoord0, midNormalCurvature, lowNormalCurvature); - } + unpackMidLowNormalCurvature(_texCoord0, midNormalCurvature, lowNormalCurvature); + float check = float(frag.mode == FRAG_MODE_SCATTERING); + midNormalCurvature = check * midNormalCurvature; + lowNormalCurvature = check * lowNormalCurvature; + vec3 color = evalSkyboxGlobalColor( getViewInverse(), shadowAttenuation, diff --git a/libraries/render-utils/src/drawWorkloadProxy.slv b/libraries/render-utils/src/drawWorkloadProxy.slv index 7a01702107..9dfcf8415c 100644 --- a/libraries/render-utils/src/drawWorkloadProxy.slv +++ b/libraries/render-utils/src/drawWorkloadProxy.slv @@ -62,7 +62,5 @@ void main(void) { varColor = vec4(REGION_COLOR[region].xyz, proxy.sphere.w); - if (region == 4) { - gl_Position = vec4(0.0); - } + gl_Position = mix(gl_Position, vec4(0.0), float(region == 4)); } diff --git a/libraries/render-utils/src/forward_model_unlit.slf b/libraries/render-utils/src/forward_model_unlit.slf index 19b40d884c..fb6c94a3f2 100644 --- a/libraries/render-utils/src/forward_model_unlit.slf +++ b/libraries/render-utils/src/forward_model_unlit.slf @@ -40,8 +40,5 @@ void main(void) { <$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>; albedo *= _color.rgb; - if (opacity != 1.0) { - discard; - } _fragColor0 = vec4(albedo * isUnlitEnabled(), 1.0); } diff --git a/libraries/render-utils/src/glowLine.slv b/libraries/render-utils/src/glowLine.slv index 167aeb8c9e..609082878b 100644 --- a/libraries/render-utils/src/glowLine.slv +++ b/libraries/render-utils/src/glowLine.slv @@ -53,13 +53,9 @@ void main(void) { // Add or subtract the orthogonal vector based on a different vertex ID // calculation - if (gl_VertexID < 2) { - distanceFromCenter = -1.0; - eye.xyz -= orthogonal; - } else { - distanceFromCenter = 1.0; - eye.xyz += orthogonal; - } + float check = float(gl_VertexID < 2); + distanceFromCenter = mix(1.0, -1.0, check); + eye.xyz += mix(orthogonal, -orthogonal, check); // Finally, put the eyespace vertex into clip space <$transformEyeToClipPos(cam, eye, gl_Position)$> diff --git a/libraries/render-utils/src/grid.slf b/libraries/render-utils/src/grid.slf index 8e9b35dace..408a9ca190 100644 --- a/libraries/render-utils/src/grid.slf +++ b/libraries/render-utils/src/grid.slf @@ -34,12 +34,10 @@ layout(location=0) out vec4 outFragColor; void main(void) { Grid grid = getGrid(); - float alpha; - if (grid.edge.z == 0.0) { - alpha = paintGrid(varTexCoord0, grid.offset.xy, grid.period.xy, grid.edge.xy); - } else { - alpha = paintGridMajorMinor(varTexCoord0, grid.offset, grid.period, grid.edge); - } + float alpha = mix(paintGridMajorMinor(varTexCoord0, grid.offset, grid.period, grid.edge), + paintGrid(varTexCoord0, grid.offset.xy, grid.period.xy, grid.edge.xy), + float(grid.edge.z == 0.0)); + if (alpha == 0.0) { discard; } diff --git a/libraries/render-utils/src/lightClusters_drawClusterContent.slf b/libraries/render-utils/src/lightClusters_drawClusterContent.slf index 27cb838566..80013bc3cc 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterContent.slf +++ b/libraries/render-utils/src/lightClusters_drawClusterContent.slf @@ -90,6 +90,6 @@ void main(void) { numLightTouching++; } - _fragColor = vec4(colorRamp(1.0 - (float(numLightTouching) / 12.0f)), (numLightTouching > 0 ? 0.5 + 0.5 * numLightsScale : 0.0)); + _fragColor = vec4(colorRamp(1.0 - (float(numLightTouching) / 12.0f)), float(numLightTouching > 0) * (0.5 + 0.5 * numLightsScale)); } diff --git a/libraries/render-utils/src/lightClusters_drawClusterContent.slv b/libraries/render-utils/src/lightClusters_drawClusterContent.slv index 1303cf3926..51718e6d8f 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterContent.slv +++ b/libraries/render-utils/src/lightClusters_drawClusterContent.slv @@ -69,5 +69,5 @@ void main(void) { TransformCamera cam = getTransformCamera(); <$transformWorldToClipPos(cam, worldPos, gl_Position)$> - varColor = vec4(colorWheel(fract(float(gpu_InstanceID()) / float(frustumGrid_numClusters()))), (numLights >0 ? 0.9 : 0.1)); + varColor = vec4(colorWheel(fract(float(gpu_InstanceID()) / float(frustumGrid_numClusters()))), mix(0.1, 0.9, float(numLights > 0))); } \ No newline at end of file diff --git a/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf b/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf index abbd86dd70..0e3f8a5ea5 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf +++ b/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf @@ -62,12 +62,10 @@ void main(void) { float relClusterId = float(clusterPos.z * summedDims.x + clusterPos.y * summedDims.y + clusterPos.x) / float(frustumGrid_numClusters()); - if (relClusterId < 0.0) { - _fragColor = vec4(0.0); - } else if (relClusterId >= 1.0) { - _fragColor = vec4(vec3(1.0), 0.2); - } else { - _fragColor = vec4(colorWheel(fract(relClusterId)), (numLights > 0 ? 0.05 + 0.95 * numLightsScale : 0.0)); - } + _fragColor = mix(mix(vec4(colorWheel(fract(relClusterId)), float(numLights > 0) * (0.05 + 0.95 * numLightsScale)), + vec4(vec3(1.0), 0.2), + float(relClusterId >= 1.0)), + vec4(0.0), + float(relClusterId < 0.0)); } diff --git a/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slv b/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slv index d35c7cb20b..a5c037cc7a 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slv +++ b/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slv @@ -62,5 +62,5 @@ void main(void) { TransformCamera cam = getTransformCamera(); <$transformWorldToClipPos(cam, worldPos, gl_Position)$> - varColor = vec4(colorWheel(fract(float(gpu_InstanceID()) / float(frustumGrid_numClusters()))), 0.9); + varColor = vec4(colorWheel(fract(float(gpu_InstanceID()) / float(frustumGrid_numClusters()))), 0.9); } \ No newline at end of file diff --git a/libraries/render-utils/src/lightClusters_drawGrid.slv b/libraries/render-utils/src/lightClusters_drawGrid.slv index c4aff45beb..8d557d01c8 100644 --- a/libraries/render-utils/src/lightClusters_drawGrid.slv +++ b/libraries/render-utils/src/lightClusters_drawGrid.slv @@ -69,5 +69,5 @@ void main(void) { TransformCamera cam = getTransformCamera(); <$transformWorldToClipPos(cam, worldPos, gl_Position)$> - varColor = vec4(colorWheel(fract(float(gpu_InstanceID()) / float(frustumGrid_numClusters()))), (numLights > 0 ? 0.9 : 0.0)); + varColor = vec4(colorWheel(fract(float(gpu_InstanceID()) / float(frustumGrid_numClusters()))), float(numLights > 0) * 0.9); } \ No newline at end of file diff --git a/libraries/render-utils/src/local_lights_drawOutline.slf b/libraries/render-utils/src/local_lights_drawOutline.slf index fc1d416f96..a2b4cc1d10 100644 --- a/libraries/render-utils/src/local_lights_drawOutline.slf +++ b/libraries/render-utils/src/local_lights_drawOutline.slf @@ -96,9 +96,8 @@ void main(void) { vec3 fragLightDir = fragLightDirLen.xyz; vec3 color = vec3(0.0); - if (evalLightPointEdge(color, light, fragLightDirLen, fragEyeDir)) { - _fragColor.rgb += color; - } + float check = float(evalLightPointEdge(color, light, fragLightDirLen, fragEyeDir)); + _fragColor.rgb += check * color; } for (int i = cluster.x; i < numLights; i++) { @@ -130,10 +129,8 @@ void main(void) { numLightTouching++; vec3 color = vec3(0.0); - - if (evalLightSpotEdge(color, light, fragLightDirLen, cosSpotAngle, fragEyeDir)) { - _fragColor.rgb += color; - } + float check = float(evalLightSpotEdge(color, light, fragLightDirLen, cosSpotAngle, fragEyeDir)); + _fragColor.rgb += check * color; } } diff --git a/libraries/render-utils/src/parabola.slv b/libraries/render-utils/src/parabola.slv index 53dfc75cfe..f220c656aa 100644 --- a/libraries/render-utils/src/parabola.slv +++ b/libraries/render-utils/src/parabola.slv @@ -48,11 +48,8 @@ void main(void) { } else { normal = vec4(normalize(cross(_parabolaData.velocity, _parabolaData.acceleration)), 0); } - if (gl_VertexID % 2 == 0) { - pos += 0.5 * _parabolaData.width * normal; - } else { - pos -= 0.5 * _parabolaData.width * normal; - } + + pos += 0.5 * _parabolaData.width * normal * mix(-1.0, 1.0, float(gl_VertexID % 2 == 0)); <$transformModelToClipPos(cam, obj, pos, gl_Position)$> } \ No newline at end of file diff --git a/libraries/render-utils/src/sdf_text3D.slf b/libraries/render-utils/src/sdf_text3D.slf index 35e670eef8..b070fc44cf 100644 --- a/libraries/render-utils/src/sdf_text3D.slf +++ b/libraries/render-utils/src/sdf_text3D.slf @@ -39,13 +39,8 @@ const float taaBias = pow(2.0, TAA_TEXTURE_LOD_BIAS); float evalSDF(vec2 texCoord) { // retrieve signed distance float sdf = textureLod(Font, texCoord, TAA_TEXTURE_LOD_BIAS).g; - if (params.outline.x > 0.0) { - if (sdf > interiorCutoff) { - sdf = 1.0 - sdf; - } else { - sdf += outlineExpansion; - } - } + sdf = mix(sdf, mix(sdf + outlineExpansion, 1.0 - sdf, float(sdf > interiorCutoff)), float(params.outline.x > 0.0)); + // Rely on TAA for anti-aliasing return step(0.5, sdf); } @@ -57,16 +52,11 @@ void main() { // Perform 4x supersampling for anisotropic filtering float a; a = evalSDF(_texCoord0); - a += evalSDF(_texCoord0+dxTexCoord); - a += evalSDF(_texCoord0+dyTexCoord); - a += evalSDF(_texCoord0+dxTexCoord+dyTexCoord); + a += evalSDF(_texCoord0 + dxTexCoord); + a += evalSDF(_texCoord0 + dyTexCoord); + a += evalSDF(_texCoord0 + dxTexCoord + dyTexCoord); a *= 0.25; - // discard if invisible - if (a < 0.01) { - discard; - } - packDeferredFragment( normalize(_normalWS), a * params.color.a, diff --git a/libraries/render-utils/src/sdf_text3D_transparent.slf b/libraries/render-utils/src/sdf_text3D_transparent.slf index 6e271e1463..ae5f10a5fd 100644 --- a/libraries/render-utils/src/sdf_text3D_transparent.slf +++ b/libraries/render-utils/src/sdf_text3D_transparent.slf @@ -30,31 +30,32 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01; #define _texCoord0 _texCoord01.xy #define _texCoord1 _texCoord01.zw -const float gamma = 2.2; -const float smoothing = 32.0; +#define TAA_TEXTURE_LOD_BIAS -3.0 + const float interiorCutoff = 0.8; const float outlineExpansion = 0.2; +const float taaBias = pow(2.0, TAA_TEXTURE_LOD_BIAS); + +float evalSDF(vec2 texCoord) { + // retrieve signed distance + float sdf = textureLod(Font, texCoord, TAA_TEXTURE_LOD_BIAS).g; + sdf = mix(sdf, mix(sdf + outlineExpansion, 1.0 - sdf, float(sdf > interiorCutoff)), float(params.outline.x > 0.0)); + + // Rely on TAA for anti-aliasing + return step(0.5, sdf); +} void main() { - // retrieve signed distance - float sdf = texture(Font, _texCoord0).g; - if (params.outline.x > 0.0) { - if (sdf > interiorCutoff) { - sdf = 1.0 - sdf; - } else { - sdf += outlineExpansion; - } - } - // perform adaptive anti-aliasing of the edges - // The larger we're rendering, the less anti-aliasing we need - float s = smoothing * length(fwidth(_texCoord0)); - float w = clamp(s, 0.0, 0.5); - float a = smoothstep(0.5 - w, 0.5 + w, sdf); - - // discard if invisible - if (a < 0.01) { - discard; - } + vec2 dxTexCoord = dFdx(_texCoord0) * 0.5 * taaBias; + vec2 dyTexCoord = dFdy(_texCoord0) * 0.5 * taaBias; + + // Perform 4x supersampling for anisotropic filtering + float a; + a = evalSDF(_texCoord0); + a += evalSDF(_texCoord0 + dxTexCoord); + a += evalSDF(_texCoord0 + dyTexCoord); + a += evalSDF(_texCoord0 + dxTexCoord + dyTexCoord); + a *= 0.25; packDeferredFragmentTranslucent( normalize(_normalWS), diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index 039dbc4278..2107ec1272 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -54,7 +54,7 @@ void main(void) { vec3 specular = DEFAULT_SPECULAR; float shininess = DEFAULT_SHININESS; float emissiveAmount = 0.0; - + #ifdef PROCEDURAL #ifdef PROCEDURAL_V1 diff --git a/libraries/render-utils/src/simple_textured.slf b/libraries/render-utils/src/simple_textured.slf index b308b57345..9494edb890 100644 --- a/libraries/render-utils/src/simple_textured.slf +++ b/libraries/render-utils/src/simple_textured.slf @@ -12,6 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include gpu/Color.slh@> <@include DeferredBufferWrite.slh@> <@include render-utils/ShaderConstants.h@> @@ -28,11 +29,13 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01; void main(void) { vec4 texel = texture(originalTexture, _texCoord0); + texel = mix(color_sRGBAToLinear(texel), texel, float(_color.a <= 0.0)); + texel.rgb *= _color.rgb; packDeferredFragment( normalize(_normalWS), 1.0, - _color.rgb * texel.rgb, + texel.rgb, DEFAULT_ROUGHNESS, DEFAULT_METALLIC, DEFAULT_EMISSIVE, diff --git a/libraries/render-utils/src/simple_textured_fade.slf b/libraries/render-utils/src/simple_textured_fade.slf index ad2b636708..f8ca72c7b5 100644 --- a/libraries/render-utils/src/simple_textured_fade.slf +++ b/libraries/render-utils/src/simple_textured_fade.slf @@ -39,27 +39,25 @@ void main(void) { <$fetchFadeObjectParamsInstanced(fadeParams)$> applyFade(fadeParams, _positionWS.xyz, fadeEmissive); - + vec4 texel = texture(originalTexture, _texCoord0); - float colorAlpha = _color.a; - if (_color.a <= 0.0) { - texel = color_sRGBAToLinear(texel); - colorAlpha = -_color.a; - } + texel = mix(color_sRGBAToLinear(texel), texel, float(_color.a <= 0.0)); + texel.rgb *= _color.rgb; + texel.a = abs(_color.a); const float ALPHA_THRESHOLD = 0.999; - if (colorAlpha * texel.a < ALPHA_THRESHOLD) { + if (texel.a < ALPHA_THRESHOLD) { packDeferredFragmentTranslucent( normalize(_normalWS), - colorAlpha * texel.a, - _color.rgb * texel.rgb + fadeEmissive, + texel.a, + texel.rgb + fadeEmissive, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); } else { packDeferredFragment( normalize(_normalWS), 1.0, - _color.rgb * texel.rgb, + texel.rgb, DEFAULT_ROUGHNESS, DEFAULT_METALLIC, DEFAULT_EMISSIVE + fadeEmissive, diff --git a/libraries/render-utils/src/simple_textured_unlit.slf b/libraries/render-utils/src/simple_textured_unlit.slf index f33cb704dc..d57b72a521 100644 --- a/libraries/render-utils/src/simple_textured_unlit.slf +++ b/libraries/render-utils/src/simple_textured_unlit.slf @@ -28,25 +28,23 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01; #define _texCoord1 _texCoord01.zw void main(void) { - vec4 texel = texture(originalTexture, _texCoord0.st); - float colorAlpha = _color.a; - if (_color.a <= 0.0) { - texel = color_sRGBAToLinear(texel); - colorAlpha = -_color.a; - } + vec4 texel = texture(originalTexture, _texCoord0); + texel = mix(color_sRGBAToLinear(texel), texel, float(_color.a <= 0.0)); + texel.rgb *= _color.rgb; + texel.a = abs(_color.a); const float ALPHA_THRESHOLD = 0.999; - if (colorAlpha * texel.a < ALPHA_THRESHOLD) { + if (texel.a < ALPHA_THRESHOLD) { packDeferredFragmentTranslucent( normalize(_normalWS), - colorAlpha * texel.a, - _color.rgb * texel.rgb, + texel.a, + texel.rgb, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); } else { packDeferredFragmentUnlit( normalize(_normalWS), 1.0, - _color.rgb * texel.rgb); + texel.rgb); } } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_textured_unlit_fade.slf b/libraries/render-utils/src/simple_textured_unlit_fade.slf index 494920b363..2c0f4b005c 100644 --- a/libraries/render-utils/src/simple_textured_unlit_fade.slf +++ b/libraries/render-utils/src/simple_textured_unlit_fade.slf @@ -40,25 +40,23 @@ void main(void) { <$fetchFadeObjectParamsInstanced(fadeParams)$> applyFade(fadeParams, _positionWS.xyz, fadeEmissive); - vec4 texel = texture(originalTexture, _texCoord0.st); - float colorAlpha = _color.a; - if (_color.a <= 0.0) { - texel = color_sRGBAToLinear(texel); - colorAlpha = -_color.a; - } + vec4 texel = texture(originalTexture, _texCoord0); + texel = mix(color_sRGBAToLinear(texel), texel, float(_color.a <= 0.0)); + texel.rgb *= _color.rgb; + texel.a = abs(_color.a); const float ALPHA_THRESHOLD = 0.999; - if (colorAlpha * texel.a < ALPHA_THRESHOLD) { + if (texel.a < ALPHA_THRESHOLD) { packDeferredFragmentTranslucent( normalize(_normalWS), - colorAlpha * texel.a, - _color.rgb * texel.rgb+fadeEmissive, + texel.a, + texel.rgb + fadeEmissive, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); } else { packDeferredFragmentUnlit( normalize(_normalWS), 1.0, - _color.rgb * texel.rgb+fadeEmissive); + texel.rgb + fadeEmissive); } } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_transparent_textured.slf b/libraries/render-utils/src/simple_transparent_textured.slf index ef83914096..63214bd76b 100644 --- a/libraries/render-utils/src/simple_transparent_textured.slf +++ b/libraries/render-utils/src/simple_transparent_textured.slf @@ -12,6 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include gpu/Color.slh@> <@include DeferredBufferWrite.slh@> <@include render-utils/ShaderConstants.h@> @@ -28,12 +29,14 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01; void main(void) { vec4 texel = texture(originalTexture, _texCoord0); - float colorAlpha = _color.a * texel.a; + texel = mix(color_sRGBAToLinear(texel), texel, float(_color.a <= 0.0)); + texel.rgb *= _color.rgb; + texel.a *= abs(_color.a); packDeferredFragmentTranslucent( normalize(_normalWS), - colorAlpha, - _color.rgb * texel.rgb, + texel.a, + texel.rgb, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_transparent_textured_fade.slf b/libraries/render-utils/src/simple_transparent_textured_fade.slf index 5fac67e1d2..75a88dc581 100644 --- a/libraries/render-utils/src/simple_transparent_textured_fade.slf +++ b/libraries/render-utils/src/simple_transparent_textured_fade.slf @@ -46,14 +46,10 @@ void main(void) { <$fetchFadeObjectParamsInstanced(fadeParams)$> applyFade(fadeParams, _positionWS.xyz, fadeEmissive); - vec4 texel = texture(originalTexture, _texCoord0.st); - float opacity = _color.a; - if (_color.a <= 0.0) { - texel = color_sRGBAToLinear(texel); - opacity = -_color.a; - } - opacity *= texel.a; - vec3 albedo = _color.rgb * texel.rgb; + vec4 texel = texture(originalTexture, _texCoord0); + texel = mix(color_sRGBAToLinear(texel), texel, float(_color.a <= 0.0)); + texel.rgb *= _color.rgb; + texel.a *= abs(_color.a); vec3 fragPosition = _positionES.xyz; vec3 fragNormal = normalize(_normalWS); @@ -66,12 +62,11 @@ void main(void) { 1.0, fragPosition, fragNormal, - albedo, + texel.rgb, DEFAULT_FRESNEL, 0.0f, fadeEmissive, DEFAULT_ROUGHNESS, - opacity), - opacity); - + texel.a), + texel.a); } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_transparent_textured_unlit.slf b/libraries/render-utils/src/simple_transparent_textured_unlit.slf index bf3dbbdf88..3f4abfc730 100644 --- a/libraries/render-utils/src/simple_transparent_textured_unlit.slf +++ b/libraries/render-utils/src/simple_transparent_textured_unlit.slf @@ -27,11 +27,10 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01; layout(location=0) out vec4 _fragColor0; void main(void) { - vec4 texel = texture(originalTexture, _texCoord0.st); - float colorAlpha = _color.a; - if (_color.a <= 0.0) { - texel = color_sRGBAToLinear(texel); - colorAlpha = -_color.a; - } - _fragColor0 = vec4(_color.rgb * texel.rgb, colorAlpha * texel.a); + vec4 texel = texture(originalTexture, _texCoord0); + texel = mix(color_sRGBAToLinear(texel), texel, float(_color.a <= 0.0)); + texel.rgb *= _color.rgb; + texel.a *= abs(_color.a); + + _fragColor0 = texel; } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_transparent_textured_unlit_fade.slf b/libraries/render-utils/src/simple_transparent_textured_unlit_fade.slf index 943f361ead..e46426ec7a 100644 --- a/libraries/render-utils/src/simple_transparent_textured_unlit_fade.slf +++ b/libraries/render-utils/src/simple_transparent_textured_unlit_fade.slf @@ -39,11 +39,10 @@ void main(void) { <$fetchFadeObjectParamsInstanced(fadeParams)$> applyFade(fadeParams, _positionWS.xyz, fadeEmissive); - vec4 texel = texture(originalTexture, _texCoord0.st); - float colorAlpha = _color.a; - if (_color.a <= 0.0) { - texel = color_sRGBAToLinear(texel); - colorAlpha = -_color.a; - } - _fragColor0 = vec4(_color.rgb * texel.rgb + fadeEmissive, colorAlpha * texel.a); + vec4 texel = texture(originalTexture, _texCoord0); + texel = mix(color_sRGBAToLinear(texel), texel, float(_color.a <= 0.0)); + texel.rgb *= _color.rgb; + texel.a *= abs(_color.a); + + _fragColor0 = vec4(texel.rgb + fadeEmissive, texel.a); } \ No newline at end of file diff --git a/libraries/render-utils/src/ssao.slh b/libraries/render-utils/src/ssao.slh index f0d522a41c..0f0fb65705 100644 --- a/libraries/render-utils/src/ssao.slh +++ b/libraries/render-utils/src/ssao.slh @@ -183,43 +183,24 @@ vec3 getTapLocationClamped(int sampleNumber, float spinAngle, float outerRadius, } bool redoTap = false; - if ((tapPos.x < 0.5)) { - tapPos.x = -tapPos.x; - redoTap = true; - } else if ((tapPos.x > imageSize.x - 0.5)) { - tapPos.x -= (imageSize.x - tapPos.x); - redoTap = true; + { + float check1 = float(tapPos.x < 0.5); + float check2 = (1.0 - check1) * float(tapPos.x > imageSize.x - 0.5); + tapPos.x = mix(tapPos.x, -tapPos.x, check1) - check2 * (imageSize.x - tapPos.x); + redoTap = (check1 > 0.0 || check2 > 0.0); } - if ((tapPos.y < 0.5)) { - tapPos.y = -tapPos.y; - redoTap = true; - } else if ((tapPos.y > imageSize.y - 0.5)) { - tapPos.y -= (imageSize.y - tapPos.y); - redoTap = true; - } -/* - if ((tapPos.x < 0.5)) { - tapPos.x = 0.5; - redoTap = true; - } else if ((tapPos.x > imageSize.x - 0.5)) { - tapPos.x = imageSize.x - 0.5; - redoTap = true; + { + float check1 = float(tapPos.y < 0.5); + float check2 = (1.0 - check1) * float(tapPos.y > imageSize.y - 0.5); + tapPos.y = mix(tapPos.y, -tapPos.y, check1) - check2 * (imageSize.y - tapPos.y); + redoTap = (check1 > 0.0 || check2 > 0.0); } - if ((tapPos.y < 0.5)) { - tapPos.y = 0.5; - redoTap = true; - } else if ((tapPos.y > imageSize.y - 0.5)) { - tapPos.y = imageSize.y - 0.5; - redoTap = true; - } -*/ - - if (redoTap) { - tap.xy = tapPos - pixelPos; - tap.z = length(tap.xy); - tap.z = 0.0; + { + float check = float(redoTap); + tap.xy = mix(tap.xy, tapPos - pixelPos, check); + tap.z = (1.0 - check) * tap.z; } return tap; diff --git a/libraries/render-utils/src/ssao_debugOcclusion.slf b/libraries/render-utils/src/ssao_debugOcclusion.slf index e15e52f448..43c3d15ece 100644 --- a/libraries/render-utils/src/ssao_debugOcclusion.slf +++ b/libraries/render-utils/src/ssao_debugOcclusion.slf @@ -40,9 +40,9 @@ void main(void) { vec2 imageSize = getSideImageSize(getResolutionLevel()); // In debug adjust the correct frag pixel based on base resolution - vec2 fragCoord = gl_FragCoord.xy; + vec2 fragCoord = gl_FragCoord.xy; if (getResolutionLevel() > 0) { - fragCoord /= float (1 << getResolutionLevel()); + fragCoord /= float(1 << getResolutionLevel()); } // Pixel Debugged @@ -90,10 +90,11 @@ void main(void) { // The occluding point in camera space vec2 fragToTap = vec2(ssC) + tap.xy - fragCoord.xy; - if (dot(fragToTap,fragToTap) < keepTapRadius) { - keep = true; - keepedMip = evalMipFromRadius(tap.z * float(doFetchMips())); - } + { + bool check = dot(fragToTap,fragToTap) < keepTapRadius; + keep = keep || check; + keepedMip = int(mix(keepedMip, evalMipFromRadius(tap.z * float(doFetchMips())), int(check))); + } vec3 tapUVZ = fetchTap(side, ssC, tap, imageSize); @@ -108,12 +109,8 @@ void main(void) { outFragColor = vec4(packOcclusionDepth(A, CSZToDephtKey(Cp.z)), 1.0); @@ -124,9 +121,5 @@ void main(void) { return; } - if (!keep) { - outFragColor = vec4(0.1); - } else { - outFragColor.rgb = colorWheel(float(keepedMip)/float(MAX_MIP_LEVEL)); - } + outFragColor = mix(vec4(0.1), vec4(colorWheel(float(keepedMip) / float(MAX_MIP_LEVEL)), outFragColor.a), float(keep)); } diff --git a/libraries/render-utils/src/ssao_makeOcclusion.slf b/libraries/render-utils/src/ssao_makeOcclusion.slf index 3934b9eddc..f437c94814 100644 --- a/libraries/render-utils/src/ssao_makeOcclusion.slf +++ b/libraries/render-utils/src/ssao_makeOcclusion.slf @@ -68,13 +68,8 @@ void main(void) { // KEEP IT for Debugging // Bilateral box-filter over a quad for free, respecting depth edges // (the difference that this makes is subtle) - if (abs(dFdx(Cp.z)) < 0.02) { - A -= dFdx(A) * (float(ssC.x & 1) - 0.5); - } - if (abs(dFdy(Cp.z)) < 0.02) { - A -= dFdy(A) * (float(ssC.y & 1) - 0.5); - } - + A -= float(abs(dFdx(Cp.z)) < 0.02) * dFdx(A) * (float(ssC.x & 1) - 0.5); + A -= float(abs(dFdy(Cp.z)) < 0.02) * dFdy(A) * (float(ssC.y & 1) - 0.5); outFragColor = vec4(packOcclusionDepth(A, CSZToDephtKey(Cp.z)), 1.0); diff --git a/libraries/render-utils/src/stencil_drawMask.slf b/libraries/render-utils/src/stencil_drawMask.slf index 5ba09a8264..2ae5853960 100644 --- a/libraries/render-utils/src/stencil_drawMask.slf +++ b/libraries/render-utils/src/stencil_drawMask.slf @@ -18,6 +18,9 @@ float aspectRatio = 0.95; void main(void) { vec2 pos = varTexCoord0 * 2.0 - vec2(1.0); - pos.x = aspectRatio * (pos.x * (pos.x > 0.0 ? 2.0 : -2.0) - 1.0); - if (1.0 - dot(pos.xy, pos.xy) > 0.0 ) discard; + pos.x = aspectRatio * (pos.x * mix(-2.0, 2.0, float(pos.x > 0.0)) - 1.0); + + if (1.0 - dot(pos.xy, pos.xy) > 0.0) { + discard; + } } diff --git a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf index 877c31c23d..ac5907803c 100644 --- a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf +++ b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf @@ -93,14 +93,14 @@ vec3 drawScatteringTableUV(vec2 cursor, vec2 texcoord) { vec3 color = vec3(0.0); bool keep = false; for (int c = 0; c < 3; c++) { - if (distance[c] > threshold) { - keep = true; - color[c] += 1.0; - } + bool check = distance[c] > threshold; + keep = keep || check; + color[c] += float(check); } - if (!keep) - discard; + if (!keep) { + discard; + } return color; } diff --git a/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf b/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf index 363fd0d4f8..433b3e97dc 100644 --- a/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf +++ b/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf @@ -67,11 +67,7 @@ vec3 getRawNormal(vec2 texcoord) { vec3 getWorldNormal(vec2 texcoord) { vec3 rawNormal = getRawNormal(texcoord); - if (isFullResolution()) { - return unpackNormal(rawNormal); - } else { - return normalize((rawNormal - vec3(0.5)) * 2.0); - } + return mix(normalize((rawNormal - vec3(0.5)) * 2.0), unpackNormal(rawNormal), float(isFullResolution())); } vec3 getWorldNormalDiff(vec2 texcoord, vec2 delta) { @@ -93,7 +89,7 @@ void main(void) { vec2 texcoordPos; ivec4 stereoSide; ivec2 framePixelPos = getPixelPosTexcoordPosAndSide(gl_FragCoord.xy, pixelPos, texcoordPos, stereoSide); - vec2 stereoSideClip = vec2(stereoSide.x, (isStereo() ? 0.5 : 1.0)); + vec2 stereoSideClip = vec2(stereoSide.x, mix(1.0, 0.5, float(isStereo()))); // Texcoord to fetch in the deferred texture are the exact UVs comming from vertex shader // sideToFrameTexcoord(stereoSideClip, texcoordPos); @@ -128,8 +124,8 @@ void main(void) { // Calculate dF/du and dF/dv vec2 viewportScale = perspectiveScale * getInvWidthHeight(); - vec2 du = vec2( viewportScale.x * (float(stereoSide.w) > 0.0 ? 0.5 : 1.0), 0.0f ); - vec2 dv = vec2( 0.0f, viewportScale.y ); + vec2 du = vec2(viewportScale.x * mix(1.0, 0.5, float(float(stereoSide.w) > 0.0)), 0.0); + vec2 dv = vec2( 0.0f, viewportScale.y); vec4 dFdu = vec4(getWorldNormalDiff(frameTexcoordPos, du), getEyeDepthDiff(frameTexcoordPos, du)); vec4 dFdv = vec4(getWorldNormalDiff(frameTexcoordPos, dv), getEyeDepthDiff(frameTexcoordPos, dv)); diff --git a/libraries/render-utils/src/taa.slf b/libraries/render-utils/src/taa.slf index a2b58d3050..25320179f5 100644 --- a/libraries/render-utils/src/taa.slf +++ b/libraries/render-utils/src/taa.slf @@ -35,17 +35,11 @@ void main() { vec2 prevFragUV = taa_fetchSourceAndHistory(fragUV, fragVel, sourceColor, historyColor); vec3 nextColor = sourceColor; - - if (taa_constrainColor()) { - // clamp history to neighbourhood of current sample - historyColor = taa_evalConstrainColor(sourceColor, fragUV, fragVel, historyColor); - } - - if (taa_feedbackColor()) { - nextColor = taa_evalFeedbackColor(sourceColor, historyColor, params.blend); - } else { - nextColor = mix(historyColor, sourceColor, params.blend); - } + + // clamp history to neighbourhood of current sample + historyColor = mix(historyColor, taa_evalConstrainColor(sourceColor, fragUV, fragVel, historyColor), float(taa_constrainColor())); + + nextColor = mix(mix(historyColor, sourceColor, params.blend), taa_evalFeedbackColor(sourceColor, historyColor, params.blend), float(taa_feedbackColor())); outFragColor = vec4(taa_resolveColor(nextColor), 1.0); } diff --git a/libraries/render-utils/src/taa.slh b/libraries/render-utils/src/taa.slh index 784c0824d5..827bcec644 100644 --- a/libraries/render-utils/src/taa.slh +++ b/libraries/render-utils/src/taa.slh @@ -121,21 +121,17 @@ float taa_fetchDepth(vec2 uv) { } -#define ZCMP_GT(a, b) (a > b) +#define ZCMP_GT(a, b) float(a > b) vec2 taa_getImageSize() { vec2 imageSize = getWidthHeight(0); - if (isStereo()) { - imageSize.x *= 2.0; - } + imageSize.x *= mix(1.0, 2.0, float(isStereo())); return imageSize; } vec2 taa_getTexelSize() { vec2 texelSize = getInvWidthHeight(); - if (isStereo()) { - texelSize.x *= 0.5; - } + texelSize.x *= mix(1.0, 0.5, float(isStereo())); return texelSize; } @@ -158,16 +154,16 @@ vec3 taa_findClosestFragment3x3(vec2 uv) vec3 dbr = vec3( 1, 1, taa_fetchDepth(uv + dv + du)); vec3 dmin = dtl; - if (ZCMP_GT(dmin.z, dtc.z)) dmin = dtc; - if (ZCMP_GT(dmin.z, dtr.z)) dmin = dtr; + dmin = mix(dmin, dtc, ZCMP_GT(dmin.z, dtc.z)); + dmin = mix(dmin, dtr, ZCMP_GT(dmin.z, dtr.z)); - if (ZCMP_GT(dmin.z, dml.z)) dmin = dml; - if (ZCMP_GT(dmin.z, dmc.z)) dmin = dmc; - if (ZCMP_GT(dmin.z, dmr.z)) dmin = dmr; + dmin = mix(dmin, dml, ZCMP_GT(dmin.z, dml.z)); + dmin = mix(dmin, dmc, ZCMP_GT(dmin.z, dmc.z)); + dmin = mix(dmin, dmr, ZCMP_GT(dmin.z, dmr.z)); - if (ZCMP_GT(dmin.z, dbl.z)) dmin = dbl; - if (ZCMP_GT(dmin.z, dbc.z)) dmin = dbc; - if (ZCMP_GT(dmin.z, dbr.z)) dmin = dbr; + dmin = mix(dmin, dbl, ZCMP_GT(dmin.z, dbl.z)); + dmin = mix(dmin, dbc, ZCMP_GT(dmin.z, dbc.z)); + dmin = mix(dmin, dbr, ZCMP_GT(dmin.z, dbr.z)); return vec3(uv + dd.xy * dmin.xy, dmin.z); } @@ -189,49 +185,46 @@ vec2 taa_fetchVelocityMapBest(vec2 uv) { vec2 dbc = taa_fetchVelocityMap(uv + dv); vec2 dbr = taa_fetchVelocityMap(uv + dv + du); - vec3 best = vec3(dtl, dot(dtl,dtl)); + vec3 best = vec3(dtl, dot(dtl, dtl)); - float testSpeed = dot(dtc,dtc); - if (testSpeed > best.z) { best = vec3(dtc, testSpeed); } - testSpeed = dot(dtr,dtr); - if (testSpeed > best.z) { best = vec3(dtr, testSpeed); } + float testSpeed = dot(dtc, dtc); + mix(best, vec3(dtc, testSpeed), float(testSpeed > best.z)); + testSpeed = dot(dtr, dtr); + mix(best, vec3(dtr, testSpeed), float(testSpeed > best.z)); - testSpeed = dot(dml,dml); - if (testSpeed > best.z) { best = vec3(dml, testSpeed); } - testSpeed = dot(dmc,dmc); - if (testSpeed > best.z) { best = vec3(dmc, testSpeed); } - testSpeed = dot(dmr,dmr); - if (testSpeed > best.z) { best = vec3(dmr, testSpeed); } + testSpeed = dot(dml, dml); + mix(best, vec3(dml, testSpeed), float(testSpeed > best.z)); + testSpeed = dot(dmc, dmc); + mix(best, vec3(dmc, testSpeed), float(testSpeed > best.z)); + testSpeed = dot(dmr, dmr); + mix(best, vec3(dmr, testSpeed), float(testSpeed > best.z)); - testSpeed = dot(dbl,dbl); - if (testSpeed > best.z) { best = vec3(dbl, testSpeed); } - testSpeed = dot(dbc,dbc); - if (testSpeed > best.z) { best = vec3(dbc, testSpeed); } - testSpeed = dot(dbr,dbr); - if (testSpeed > best.z) { best = vec3(dbr, testSpeed); } + testSpeed = dot(dbl, dbl); + mix(best, vec3(dbl, testSpeed), float(testSpeed > best.z)); + testSpeed = dot(dbc, dbc); + mix(best, vec3(dbc, testSpeed), float(testSpeed > best.z)); + testSpeed = dot(dbr, dbr); + mix(best, vec3(dbr, testSpeed), float(testSpeed > best.z)); return best.xy; } vec2 taa_fromFragUVToEyeUVAndSide(vec2 fragUV, out int stereoSide) { vec2 eyeUV = fragUV; - stereoSide = 0; - if (isStereo()) { - if (eyeUV.x > 0.5) { - eyeUV.x -= 0.5; - stereoSide = 1; - } - eyeUV.x *= 2.0; - } + + float check = float(isStereo()); + float check2 = float(eyeUV.x > 0.5); + eyeUV.x -= check * check2 * 0.5; + stereoSide = int(check * check2); + eyeUV.x *= mix(1.0, 2.0, check); return eyeUV; } vec2 taa_fromEyeUVToFragUV(vec2 eyeUV, int stereoSide) { vec2 fragUV = eyeUV; - if (isStereo()) { - fragUV.x *= 0.5; - fragUV.x += float(stereoSide)*0.5; - } + float check = float(isStereo()); + fragUV.x *= mix(1.0, 0.5, check); + fragUV.x += check * float(stereoSide) * 0.5; return fragUV; } @@ -247,10 +240,8 @@ vec2 taa_fetchSourceAndHistory(vec2 fragUV, vec2 fragVelocity, out vec3 sourceCo vec2 prevFragUV = taa_computePrevFragAndEyeUV(fragUV, fragVelocity, prevEyeUV); sourceColor = taa_fetchSourceMap(fragUV).xyz; - historyColor = sourceColor; - if (!(any(lessThan(prevEyeUV, vec2(0.0))) || any(greaterThan(prevEyeUV, vec2(1.0))))) { - historyColor = taa_fetchHistoryMap(prevFragUV).xyz; - } + historyColor = mix(sourceColor, taa_fetchHistoryMap(prevFragUV).xyz, float(!(any(lessThan(prevEyeUV, vec2(0.0))) || any(greaterThan(prevEyeUV, vec2(1.0)))))); + return prevFragUV; } @@ -405,10 +396,11 @@ vec3 taa_clampColor(vec3 colorMin, vec3 colorMax, vec3 colorSource, vec3 color) vec3 a_unit = abs(v_unit); float ma_unit = max(a_unit.x, max(a_unit.y, a_unit.z)); - if (ma_unit > 1.0) + if (ma_unit > 1.0) { return p_clip + v_clip / ma_unit; - else - return q;// point inside aabb + } else { + return q;// point inside aabb + } } vec3 taa_evalConstrainColor(vec3 sourceColor, vec2 sourceUV, vec2 sourceVel, vec3 candidateColor) { @@ -514,10 +506,6 @@ vec3 taa_evalFXAA(vec2 fragUV) { // compare luma of new samples to the luma range of the original neighborhood // if the new samples exceed this range, just use the first two samples instead of all four - if (lumaB < lumaMin || lumaB > lumaMax) { - return rgbA; - } else { - return rgbB; - } + return mix(rgbB, rgbA, float(lumaB < lumaMin || lumaB > lumaMax)); } diff --git a/libraries/render-utils/src/taa_blend.slf b/libraries/render-utils/src/taa_blend.slf index 50575a6a07..0999b2482f 100644 --- a/libraries/render-utils/src/taa_blend.slf +++ b/libraries/render-utils/src/taa_blend.slf @@ -83,32 +83,21 @@ void main(void) { if ((prevOrbPosToPixLength < tenPercentHeight) && (cursorVelocityLength > 0.5)) { vec2 prevOrbPosToPix_uv = cursorPrevUV + prevOrbPosToPix * texelSize / taa_getDebugOrbZoom(); vec3 preOrbColor = vec3(0.0); - if (!(any(lessThan(prevOrbPosToPix_uv, vec2(0.0))) || any(greaterThan(prevOrbPosToPix_uv, vec2(1.0))))) { - preOrbColor = texture(historyMap, prevOrbPosToPix_uv).xyz; - } - if (prevOrbPosToPixLength < orbPixThreshold) { - preOrbColor = vec3(1.0, 0.0, 1.0); - } + + preOrbColor = mix(preOrbColor, texture(historyMap, prevOrbPosToPix_uv).xyz, float(!(any(lessThan(prevOrbPosToPix_uv, vec2(0.0))) || any(greaterThan(prevOrbPosToPix_uv, vec2(1.0)))))); + preOrbColor = mix(preOrbColor, vec3(1.0, 0.0, 1.0), float(prevOrbPosToPixLength < orbPixThreshold)); float distanceToNext = length(imageSize * (cursorUV - prevOrbPosToPix_uv)); - if (distanceToNext < orbPixThreshold) { - preOrbColor = vec3(1.0, 0.5, 0.0); - } + preOrbColor = mix(preOrbColor, vec3(1.0, 0.5, 0.0), float(distanceToNext < orbPixThreshold)); outFragColor = vec4(preOrbColor, 1.0); return; } if (nextOrbPosToPixLength < tenPercentHeight) { vec2 nextOrbPosToPix_uv = cursorUV + nextOrbPosToPix * texelSize / taa_getDebugOrbZoom(); vec3 nextOrbColor = vec3(0.0); - if (!(any(lessThan(nextOrbPosToPix_uv, vec2(0.0))) || any(greaterThan(nextOrbPosToPix_uv, vec2(1.0))))) { - nextOrbColor = texture(nextMap, nextOrbPosToPix_uv).xyz; - } + nextOrbColor = mix(nextOrbColor, texture(nextMap, nextOrbPosToPix_uv).xyz, float(!(any(lessThan(nextOrbPosToPix_uv, vec2(0.0))) || any(greaterThan(nextOrbPosToPix_uv, vec2(1.0)))))); float distanceToPrev = length(imageSize * (cursorPrevUV - nextOrbPosToPix_uv)); - if (distanceToPrev < orbPixThreshold) { - nextOrbColor = vec3(1.0, 0.0, 1.0); - } - if (nextOrbPosToPixLength < orbPixThreshold) { - nextOrbColor = vec3(1.0, 0.5, 0.0); - } + nextOrbColor = mix(nextOrbColor, vec3(1.0, 0.0, 1.0), float(distanceToPrev < orbPixThreshold)); + nextOrbColor = mix(nextOrbColor, vec3(1.0, 0.5, 0.0), float(nextOrbPosToPixLength < orbPixThreshold)); outFragColor = vec4(nextOrbColor, 1.0); return; @@ -141,16 +130,9 @@ void main(void) { outFragColor = vec4(nextColor, 1.0); vec3 prevColor = nextColor; + prevColor = mix(prevColor, texture(historyMap, prevTexCoord).xyz, float(!(any(lessThan(prevTexCoord, vec2(0.0))) || any(greaterThan(prevTexCoord, vec2(1.0)))))); - if (!(any(lessThan(prevTexCoord, vec2(0.0))) || any(greaterThan(prevTexCoord, vec2(1.0))))) { - prevColor = texture(historyMap, prevTexCoord).xyz; - } + outFragColor.xyz = mix(prevColor, vec3(1, 0, 1), clamp(distance(prevColor, nextColor) - 0.01, 0.0, 1.0)); - outFragColor.xyz = mix(prevColor, vec3(1,0,1), clamp(distance(prevColor, nextColor) - 0.01, 0.0, 1.0)); - - if (pixVelocityLength > params.debugShowVelocityThreshold) { - vec3 speedColor = taa_getVelocityColorAboveThreshold(pixVelocityLength); - - outFragColor = vec4(0.0, 1.0, 1.0, 1.0); - } + outFragColor = mix(outFragColor, vec4(0.0, 1.0, 1.0, 1.0), float(pixVelocityLength > params.debugShowVelocityThreshold)); } diff --git a/libraries/render-utils/src/zone_drawAmbient.slf b/libraries/render-utils/src/zone_drawAmbient.slf index f20d83e913..d780fd0de2 100644 --- a/libraries/render-utils/src/zone_drawAmbient.slf +++ b/libraries/render-utils/src/zone_drawAmbient.slf @@ -44,7 +44,7 @@ void main(void) { // vec3 ambient = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), fragNormal).xyz; // _fragColor = vec4( 0.5 * (fragNormal + vec3(1.0)), 1.0); - vec3 color = (sphereUV.x > 0.0 ? ambientMap : ambientSH); + vec3 color = mix(ambientSH, ambientMap, float(sphereUV.x > 0.0)); color = color * 1.0 - base.w + base.xyz * base.w; const float INV_GAMMA_22 = 1.0 / 2.2; diff --git a/libraries/render-utils/src/zone_drawSkybox.slf b/libraries/render-utils/src/zone_drawSkybox.slf index f8d1326b3a..743b48d0bf 100644 --- a/libraries/render-utils/src/zone_drawSkybox.slf +++ b/libraries/render-utils/src/zone_drawSkybox.slf @@ -35,16 +35,11 @@ void main(void) { vec3 color = skybox.color.rgb; // blend is only set if there is a cubemap - if (skybox.color.a > 0.0) { - color = texture(skyboxMap, direction).rgb; - if (skybox.color.a < 1.0) { - color *= skybox.color.rgb; - } - } + float check = float(skybox.color.a > 0.0); + color = mix(color, texture(skyboxMap, direction).rgb, check); + color *= mix(vec3(1.0), skybox.color.rgb, check * float(skybox.color.a < 1.0)); color = color * 1.0 - base.w + base.xyz * base.w; const float INV_GAMMA_22 = 1.0 / 2.2; _fragColor = vec4(pow(color, vec3(INV_GAMMA_22)), 1.0); } - - diff --git a/libraries/render/src/render/BlurTask.slh b/libraries/render/src/render/BlurTask.slh index 1133435b4d..e0ded6d8c3 100644 --- a/libraries/render/src/render/BlurTask.slh +++ b/libraries/render/src/render/BlurTask.slh @@ -98,9 +98,10 @@ vec4 pixelShaderGaussian(vec2 texcoord, vec2 direction, vec2 pixelStep) { totalWeight += weight; } } - - float check = float(totalWeight > 0.0); - srcBlurred *= check / totalWeight + (1.0 - check); + + if (totalWeight > 0.0) { + srcBlurred /= totalWeight; + } srcBlurred.a = getOutputAlpha(); return srcBlurred; @@ -159,9 +160,10 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep totalWeight += weight; } } - - float check = float(totalWeight > 0.0); - srcBlurred *= check / totalWeight + (1.0 - check); + + if (totalWeight > 0.0) { + srcBlurred /= totalWeight; + } return srcBlurred; } diff --git a/libraries/render/src/render/drawCellBounds.slv b/libraries/render/src/render/drawCellBounds.slv index 24cc6254fd..4b5356741b 100644 --- a/libraries/render/src/render/drawCellBounds.slv +++ b/libraries/render/src/render/drawCellBounds.slv @@ -51,7 +51,7 @@ void main(void) { vec4 pos = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]]; int cellIsEmpty = sign(inCellLocation.w); - ivec4 cellLocation = ivec4(inCellLocation.xyz, (inCellLocation.w < 0 ? -inCellLocation.w : inCellLocation.w)); + ivec4 cellLocation = ivec4(inCellLocation.xyz, cellIsEmpty * inCellLocation.w); vec4 cellBound = evalBound(cellLocation); pos.xyz = cellBound.xyz + vec3(cellBound.w) * pos.xyz; diff --git a/libraries/render/src/render/drawItemBounds.slf b/libraries/render/src/render/drawItemBounds.slf index 90faaff05c..ab78f93064 100644 --- a/libraries/render/src/render/drawItemBounds.slf +++ b/libraries/render/src/render/drawItemBounds.slf @@ -18,11 +18,7 @@ layout(location=0) out vec4 outFragColor; void main(void) { float var = step(fract(varTexcoord.x * varTexcoord.y * 1.0), 0.5); - if (varColor.a == 0.0) { - outFragColor = vec4(mix(vec3(0.0), varColor.xyz, var), mix(0.0, 1.0, var)); - - } else { - outFragColor = vec4(mix(vec3(1.0), varColor.xyz, var), varColor.a); - } - + outFragColor = mix(vec4(mix(vec3(1.0), varColor.xyz, var), varColor.a), + vec4(mix(vec3(0.0), varColor.xyz, var), mix(0.0, 1.0, var)), + float(varColor.a == 0.0)); } diff --git a/libraries/render/src/render/drawItemBounds.slv b/libraries/render/src/render/drawItemBounds.slv index 0a9615c9c2..808a23599b 100644 --- a/libraries/render/src/render/drawItemBounds.slv +++ b/libraries/render/src/render/drawItemBounds.slv @@ -98,11 +98,6 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, pos, gl_Position)$> - if (params.color.w < 0.0) { - varColor = vec4(colorWheel(float(boundID)/(-params.color.w)), 1.0); - } else { - varColor = vec4(colorWheel(float(params.color.w)), 1.0); - } + varColor = mix(vec4(colorWheel(float(params.color.w)), 1.0), vec4(colorWheel(float(boundID)/(-params.color.w)), 1.0), float(params.color.w < 0.0)); varTexcoord = vec2(cubeVec.w, length(boundDim)); - } \ No newline at end of file diff --git a/libraries/render/src/render/drawItemStatus.slf b/libraries/render/src/render/drawItemStatus.slf index e88cf4c920..ca7f2273cd 100644 --- a/libraries/render/src/render/drawItemStatus.slf +++ b/libraries/render/src/render/drawItemStatus.slf @@ -22,10 +22,9 @@ vec2 getIconTexcoord(float icon, vec2 uv) { } void main(void) { - if (varTexcoord.z < 254.5) { - outFragColor = texture(_icons, getIconTexcoord(varTexcoord.z, varTexcoord.xy)) * varColor; - } else { - vec2 centerDir = varTexcoord.xy * 2.0f - 1.0f; - outFragColor = vec4(varColor.xyz, 1.0 - step(1.0f, dot(centerDir.xy, centerDir.xy))); - } + vec2 centerDir = varTexcoord.xy * 2.0f - 1.0f; + + outFragColor = mix(vec4(varColor.xyz, 1.0 - step(1.0f, dot(centerDir.xy, centerDir.xy))), + texture(_icons, getIconTexcoord(varTexcoord.z, varTexcoord.xy)) * varColor, + float(varTexcoord.z < 254.5)); } From e534e09801ec664784959711b73779f1d4b53311 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Mon, 29 Oct 2018 17:38:28 -0700 Subject: [PATCH 014/109] Update LightClusterGrid_shared.slh --- .../render-utils/src/DeferredBufferRead.slh | 4 ++-- libraries/render-utils/src/Haze.slf | 2 +- libraries/render-utils/src/LightClusterGrid.slh | 2 +- .../render-utils/src/LightClusterGrid_shared.slh | 10 ++++------ libraries/render-utils/src/LightPoint.slh | 10 ++++++---- libraries/render-utils/src/LightSpot.slh | 16 +++++++++------- libraries/render-utils/src/glowLine.slv | 5 ++--- .../src/lightClusters_drawClusterContent.slv | 2 +- .../render-utils/src/ssao_debugOcclusion.slf | 3 ++- .../src/surfaceGeometry_makeCurvature.slf | 4 ++-- libraries/render-utils/src/taa.slh | 8 ++++---- libraries/render/src/render/drawItemBounds.slf | 2 +- 12 files changed, 35 insertions(+), 33 deletions(-) diff --git a/libraries/render-utils/src/DeferredBufferRead.slh b/libraries/render-utils/src/DeferredBufferRead.slh index a6a6a6b1ac..868b93ff91 100644 --- a/libraries/render-utils/src/DeferredBufferRead.slh +++ b/libraries/render-utils/src/DeferredBufferRead.slh @@ -121,7 +121,7 @@ vec4 unpackDeferredPosition(float depthValue, vec2 texcoord) { float check2 = check * float(texcoord.x > 0.5); texcoord.x -= check2 * 0.5; int side = int(check2); - texcoord.x *= mix(1.0, 2.0, check); + texcoord.x *= 1.0 + check; return vec4(evalEyePositionFromZdb(side, depthValue, texcoord), 1.0); } @@ -139,7 +139,7 @@ vec4 unpackDeferredPositionFromZeye(vec2 texcoord) { float check2 = check * float(texcoord.x > 0.5); texcoord.x -= check2 * 0.5; int side = int(check2); - texcoord.x *= mix(1.0, 2.0, check); + texcoord.x *= 1.0 + check; return vec4(evalEyePositionFromZeye(side, Zeye, texcoord), 1.0); } diff --git a/libraries/render-utils/src/Haze.slf b/libraries/render-utils/src/Haze.slf index b64d4172c6..170e69eb2d 100644 --- a/libraries/render-utils/src/Haze.slf +++ b/libraries/render-utils/src/Haze.slf @@ -30,7 +30,7 @@ vec4 unpackPositionFromZeye(vec2 texcoord) { float check2 = check * float(texcoord.x > 0.5); texcoord.x -= check2 * 0.5; int side = int(check2); - texcoord.x *= mix(1.0, 2.0, check); + texcoord.x *= 1.0 + check; return vec4(evalEyePositionFromZeye(side, Zeye, texcoord), 1.0); } diff --git a/libraries/render-utils/src/LightClusterGrid.slh b/libraries/render-utils/src/LightClusterGrid.slh index df8ba001f5..cd944489ec 100644 --- a/libraries/render-utils/src/LightClusterGrid.slh +++ b/libraries/render-utils/src/LightClusterGrid.slh @@ -83,7 +83,7 @@ int clusterGrid_getClusterLightId(int index, int offset) { return element; */ int element = _clusterGridContent[GRID_FETCH_BUFFER((elementIndex >> 1))]; - return int(mix(element, element >> 16, int((elementIndex & 0x00000001) == 1))) & 0x0000FFFF; + return (element >> (16 * int((elementIndex & 0x00000001) == 1))) & 0x0000FFFF; } diff --git a/libraries/render-utils/src/LightClusterGrid_shared.slh b/libraries/render-utils/src/LightClusterGrid_shared.slh index 476ca6284f..cf58ce56ff 100644 --- a/libraries/render-utils/src/LightClusterGrid_shared.slh +++ b/libraries/render-utils/src/LightClusterGrid_shared.slh @@ -7,11 +7,9 @@ #ifdef __cplusplus # define _MIN glm::min -# define _MIX(x, y, a) glm::mix((float)x, (float)y, (float)a) -# define _ABS(x) (int)fabsf() +# define _ABS(x) (int)fabsf(x) #else # define _MIN min -# define _MIX mix # define _ABS abs #endif @@ -151,7 +149,7 @@ ivec3 frustumGrid_eyeToClusterPos(vec3 eyePos) { int frustumGrid_eyeToClusterDirH(vec3 eyeDir) { if (eyeDir.z >= 0.0f) { - return int(_MIX(-1, frustumGrid.dims.x, int(eyeDir.x > 0.0f))); + return int(eyeDir.x > 0.0f) * (frustumGrid.dims.x + 1) - 1; } float eyeDepth = -eyeDir.z; @@ -165,7 +163,7 @@ int frustumGrid_eyeToClusterDirH(vec3 eyeDir) { int frustumGrid_eyeToClusterDirV(vec3 eyeDir) { if (eyeDir.z >= 0.0f) { - return int(_MIX(-1, frustumGrid.dims.y, int(eyeDir.y > 0.0f))); + return int(eyeDir.y > 0.0f) * (frustumGrid.dims.y + 1) - 1; } float eyeDepth = -eyeDir.z; @@ -193,4 +191,4 @@ vec4 frustumGrid_worldToEye(vec4 worldPos) { // <@if 1@> // Trigger Scribe include - // <@endif@> End C++ compatible \ No newline at end of file + // <@endif@> End C++ compatible diff --git a/libraries/render-utils/src/LightPoint.slh b/libraries/render-utils/src/LightPoint.slh index 7c59cf85ef..6100627105 100644 --- a/libraries/render-utils/src/LightPoint.slh +++ b/libraries/render-utils/src/LightPoint.slh @@ -40,10 +40,12 @@ void evalLightingPoint(out vec3 diffuse, out vec3 specular, Light light, diffuse *= lightEnergy * isDiffuseEnabled(); specular *= lightEnergy * isSpecularEnabled(); - // Show edges - float edge = abs(2.0 * ((lightVolume_getRadius(light.volume) - fragLightDistance) / (0.1)) - 1.0); - float edgeCoord = exp2(-8.0 * edge * edge); - diffuse = mix(diffuse, vec3(edgeCoord * edgeCoord * getLightColor(light)), float(isShowLightContour() > 0.0 && edge < 1.0)); + if (isShowLightContour() > 0.0) { + // Show edges + float edge = abs(2.0 * ((lightVolume_getRadius(light.volume) - fragLightDistance) / (0.1)) - 1.0); + float edgeCoord = exp2(-8.0 * edge * edge); + diffuse = mix(diffuse, vec3(edgeCoord * edgeCoord * getLightColor(light)), float(edge < 1.0)); + } } <@endfunc@> diff --git a/libraries/render-utils/src/LightSpot.slh b/libraries/render-utils/src/LightSpot.slh index 799021c459..7fea9856d8 100644 --- a/libraries/render-utils/src/LightSpot.slh +++ b/libraries/render-utils/src/LightSpot.slh @@ -41,13 +41,15 @@ void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light, diffuse *= lightEnergy * isDiffuseEnabled(); specular *= lightEnergy * isSpecularEnabled(); - // Show edges - float edgeDistR = (lightVolume_getRadius(light.volume) - fragLightDistance); - float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -lightVolume_getSpotOutsideNormal2(light.volume)); - float edgeDist = min(edgeDistR, edgeDistS); - float edge = abs(2.0 * (edgeDist * 10.0) - 1.0); - float edgeCoord = exp2(-8.0 * edge * edge); - diffuse = mix(diffuse, vec3(edgeCoord * edgeCoord * getLightColor(light)), float(isShowLightContour() > 0.0 && edge < 1.0)); + if (isShowLightContour() > 0.0) { + // Show edges + float edgeDistR = (lightVolume_getRadius(light.volume) - fragLightDistance); + float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -lightVolume_getSpotOutsideNormal2(light.volume)); + float edgeDist = min(edgeDistR, edgeDistS); + float edge = abs(2.0 * (edgeDist * 10.0) - 1.0); + float edgeCoord = exp2(-8.0 * edge * edge); + diffuse = mix(diffuse, vec3(edgeCoord * edgeCoord * getLightColor(light)), float(edge < 1.0)); + } } <@endfunc@> diff --git a/libraries/render-utils/src/glowLine.slv b/libraries/render-utils/src/glowLine.slv index 609082878b..ecb1152d52 100644 --- a/libraries/render-utils/src/glowLine.slv +++ b/libraries/render-utils/src/glowLine.slv @@ -53,9 +53,8 @@ void main(void) { // Add or subtract the orthogonal vector based on a different vertex ID // calculation - float check = float(gl_VertexID < 2); - distanceFromCenter = mix(1.0, -1.0, check); - eye.xyz += mix(orthogonal, -orthogonal, check); + distanceFromCenter = mix(1.0, -1.0, float(gl_VertexID < 2)); + eye.xyz += distanceFromCenter * orthogonal; // Finally, put the eyespace vertex into clip space <$transformEyeToClipPos(cam, eye, gl_Position)$> diff --git a/libraries/render-utils/src/lightClusters_drawClusterContent.slv b/libraries/render-utils/src/lightClusters_drawClusterContent.slv index 51718e6d8f..c30252da41 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterContent.slv +++ b/libraries/render-utils/src/lightClusters_drawClusterContent.slv @@ -69,5 +69,5 @@ void main(void) { TransformCamera cam = getTransformCamera(); <$transformWorldToClipPos(cam, worldPos, gl_Position)$> - varColor = vec4(colorWheel(fract(float(gpu_InstanceID()) / float(frustumGrid_numClusters()))), mix(0.1, 0.9, float(numLights > 0))); + varColor = vec4(colorWheel(fract(float(gpu_InstanceID()) / float(frustumGrid_numClusters()))), 0.1 + 0.8 * float(numLights > 0)); } \ No newline at end of file diff --git a/libraries/render-utils/src/ssao_debugOcclusion.slf b/libraries/render-utils/src/ssao_debugOcclusion.slf index 43c3d15ece..612e5b862b 100644 --- a/libraries/render-utils/src/ssao_debugOcclusion.slf +++ b/libraries/render-utils/src/ssao_debugOcclusion.slf @@ -93,7 +93,8 @@ void main(void) { { bool check = dot(fragToTap,fragToTap) < keepTapRadius; keep = keep || check; - keepedMip = int(mix(keepedMip, evalMipFromRadius(tap.z * float(doFetchMips())), int(check))); + int checki = int(check); + keepedMip = checki * evalMipFromRadius(tap.z * float(doFetchMips())) + (1 - checki) * keepedMip; } vec3 tapUVZ = fetchTap(side, ssC, tap, imageSize); diff --git a/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf b/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf index 433b3e97dc..dd9b98b5e5 100644 --- a/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf +++ b/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf @@ -89,7 +89,7 @@ void main(void) { vec2 texcoordPos; ivec4 stereoSide; ivec2 framePixelPos = getPixelPosTexcoordPosAndSide(gl_FragCoord.xy, pixelPos, texcoordPos, stereoSide); - vec2 stereoSideClip = vec2(stereoSide.x, mix(1.0, 0.5, float(isStereo()))); + vec2 stereoSideClip = vec2(stereoSide.x, 1.0 - 0.5 * float(isStereo())); // Texcoord to fetch in the deferred texture are the exact UVs comming from vertex shader // sideToFrameTexcoord(stereoSideClip, texcoordPos); @@ -124,7 +124,7 @@ void main(void) { // Calculate dF/du and dF/dv vec2 viewportScale = perspectiveScale * getInvWidthHeight(); - vec2 du = vec2(viewportScale.x * mix(1.0, 0.5, float(float(stereoSide.w) > 0.0)), 0.0); + vec2 du = vec2(viewportScale.x * (1.0 - 0.5 * float(stereoSide.w > 0)), 0.0); vec2 dv = vec2( 0.0f, viewportScale.y); vec4 dFdu = vec4(getWorldNormalDiff(frameTexcoordPos, du), getEyeDepthDiff(frameTexcoordPos, du)); diff --git a/libraries/render-utils/src/taa.slh b/libraries/render-utils/src/taa.slh index 827bcec644..ed9162516e 100644 --- a/libraries/render-utils/src/taa.slh +++ b/libraries/render-utils/src/taa.slh @@ -125,13 +125,13 @@ float taa_fetchDepth(vec2 uv) { vec2 taa_getImageSize() { vec2 imageSize = getWidthHeight(0); - imageSize.x *= mix(1.0, 2.0, float(isStereo())); + imageSize.x *= 1.0 + float(isStereo()); return imageSize; } vec2 taa_getTexelSize() { vec2 texelSize = getInvWidthHeight(); - texelSize.x *= mix(1.0, 0.5, float(isStereo())); + texelSize.x *= 1.0 - 0.5 * float(isStereo()); return texelSize; } @@ -216,14 +216,14 @@ vec2 taa_fromFragUVToEyeUVAndSide(vec2 fragUV, out int stereoSide) { float check2 = float(eyeUV.x > 0.5); eyeUV.x -= check * check2 * 0.5; stereoSide = int(check * check2); - eyeUV.x *= mix(1.0, 2.0, check); + eyeUV.x *= 1.0 + check; return eyeUV; } vec2 taa_fromEyeUVToFragUV(vec2 eyeUV, int stereoSide) { vec2 fragUV = eyeUV; float check = float(isStereo()); - fragUV.x *= mix(1.0, 0.5, check); + fragUV.x *= 1.0 - 0.5 * check; fragUV.x += check * float(stereoSide) * 0.5; return fragUV; } diff --git a/libraries/render/src/render/drawItemBounds.slf b/libraries/render/src/render/drawItemBounds.slf index ab78f93064..0fed67beb6 100644 --- a/libraries/render/src/render/drawItemBounds.slf +++ b/libraries/render/src/render/drawItemBounds.slf @@ -19,6 +19,6 @@ void main(void) { float var = step(fract(varTexcoord.x * varTexcoord.y * 1.0), 0.5); outFragColor = mix(vec4(mix(vec3(1.0), varColor.xyz, var), varColor.a), - vec4(mix(vec3(0.0), varColor.xyz, var), mix(0.0, 1.0, var)), + vec4(mix(vec3(0.0), varColor.xyz, var), var), float(varColor.a == 0.0)); } From ebfae17a40eb297d63d344b431954a882f53611c Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Fri, 2 Nov 2018 13:28:33 -0700 Subject: [PATCH 015/109] "Works" on Mac --- interface/src/Application.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 30b5e3ed5f..438d200de2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3636,12 +3636,6 @@ void Application::onPresent(quint32 frameCount) { if (_renderEventHandler && !isAboutToQuit() && _pendingRenderEvent.compare_exchange_strong(expected, true)) { postEvent(_renderEventHandler, new QEvent((QEvent::Type)ApplicationEvent::Render)); } - - // This is done here so it won't be during a resize/move event - if (_setGeometryRequested) { - _setGeometryRequested = false; - _window->setGeometry(requestedGeometry); - } } static inline bool isKeyEvent(QEvent::Type type) { @@ -4809,6 +4803,12 @@ void Application::idle() { _idleLoopStdev.reset(); } } + + // This is done here so it won't be during a resize/move event + if (_setGeometryRequested) { + _setGeometryRequested = false; + _window->setGeometry(requestedGeometry); + } _overlayConductor.update(secondsSinceLastUpdate); From 83cc90ace07f4b48132371b7806b8e35bca342e0 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 5 Nov 2018 16:40:10 -0800 Subject: [PATCH 016/109] Re-name GLTFReader to GLTFSerializer and do the same for other model readers --- interface/src/ModelPropertiesDialog.h | 2 +- interface/src/raypick/CollisionPick.cpp | 6 +- libraries/animation/src/AnimSkeleton.h | 2 +- libraries/animation/src/AnimationCache.h | 2 +- libraries/animation/src/AnimationObject.h | 2 +- libraries/baking/src/FBXBaker.cpp | 12 +-- libraries/baking/src/ModelBaker.cpp | 2 +- libraries/baking/src/OBJBaker.cpp | 10 +- .../src/RenderableModelEntityItem.cpp | 8 +- libraries/fbx/src/FBX.h | 2 +- .../src/{FBXReader.cpp => FBXSerializer.cpp} | 44 ++++----- .../fbx/src/{FBXReader.h => FBXSerializer.h} | 10 +- ...aterial.cpp => FBXSerializer_Material.cpp} | 8 +- ...Reader_Mesh.cpp => FBXSerializer_Mesh.cpp} | 16 +-- ...Reader_Node.cpp => FBXSerializer_Node.cpp} | 24 ++--- .../{GLTFReader.cpp => GLTFSerializer.cpp} | 98 +++++++++---------- .../src/{GLTFReader.h => GLTFSerializer.h} | 14 +-- .../src/{OBJReader.cpp => OBJSerializer.cpp} | 68 ++++++------- .../fbx/src/{OBJReader.h => OBJSerializer.h} | 4 +- .../src/model-networking/ModelCache.cpp | 12 +-- .../src/model-networking/ModelCache.h | 2 +- tests-manual/gpu/src/TestFbx.cpp | 2 +- tools/skeleton-dump/src/SkeletonDumpApp.cpp | 2 +- tools/vhacd-util/src/VHACDUtil.cpp | 4 +- tools/vhacd-util/src/VHACDUtil.h | 4 +- tools/vhacd-util/src/VHACDUtilApp.h | 2 +- 26 files changed, 181 insertions(+), 181 deletions(-) rename libraries/fbx/src/{FBXReader.cpp => FBXSerializer.cpp} (98%) rename libraries/fbx/src/{FBXReader.h => FBXSerializer.h} (97%) rename libraries/fbx/src/{FBXReader_Material.cpp => FBXSerializer_Material.cpp} (98%) rename libraries/fbx/src/{FBXReader_Mesh.cpp => FBXSerializer_Mesh.cpp} (98%) rename libraries/fbx/src/{FBXReader_Node.cpp => FBXSerializer_Node.cpp} (94%) rename libraries/fbx/src/{GLTFReader.cpp => GLTFSerializer.cpp} (94%) rename libraries/fbx/src/{GLTFReader.h => GLTFSerializer.h} (99%) rename libraries/fbx/src/{OBJReader.cpp => OBJSerializer.cpp} (92%) rename libraries/fbx/src/{OBJReader.h => OBJSerializer.h} (97%) diff --git a/interface/src/ModelPropertiesDialog.h b/interface/src/ModelPropertiesDialog.h index 0bf8075197..7068d5cb76 100644 --- a/interface/src/ModelPropertiesDialog.h +++ b/interface/src/ModelPropertiesDialog.h @@ -14,7 +14,7 @@ #include -#include +#include #include #include "ui/ModelsBrowser.h" diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index 2b75946e28..ff453d99a5 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -149,7 +149,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha uint32_t numIndices = (uint32_t)meshPart.triangleIndices.size(); // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up //assert(numIndices % TRIANGLE_STRIDE == 0); - numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader + numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXSerializer for (uint32_t j = 0; j < numIndices; j += TRIANGLE_STRIDE) { glm::vec3 p0 = mesh.vertices[meshPart.triangleIndices[j]]; @@ -170,7 +170,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha numIndices = (uint32_t)meshPart.quadIndices.size(); // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up //assert(numIndices % QUAD_STRIDE == 0); - numIndices -= numIndices % QUAD_STRIDE; // WORKAROUND lack of sanity checking in FBXReader + numIndices -= numIndices % QUAD_STRIDE; // WORKAROUND lack of sanity checking in FBXSerializer for (uint32_t j = 0; j < numIndices; j += QUAD_STRIDE) { glm::vec3 p0 = mesh.vertices[meshPart.quadIndices[j]]; @@ -305,7 +305,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha auto numIndices = meshPart.triangleIndices.count(); // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up //assert(numIndices% TRIANGLE_STRIDE == 0); - numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader + numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXSerializer auto indexItr = meshPart.triangleIndices.cbegin(); while (indexItr != meshPart.triangleIndices.cend()) { diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 3a384388d0..d72533cbdb 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -15,7 +15,7 @@ #include #include -#include +#include #include "AnimPose.h" class AnimSkeleton { diff --git a/libraries/animation/src/AnimationCache.h b/libraries/animation/src/AnimationCache.h index 4423e8f18d..d4574d9d3b 100644 --- a/libraries/animation/src/AnimationCache.h +++ b/libraries/animation/src/AnimationCache.h @@ -17,7 +17,7 @@ #include #include -#include +#include #include class Animation; diff --git a/libraries/animation/src/AnimationObject.h b/libraries/animation/src/AnimationObject.h index 83880ed2ab..fc3a351832 100644 --- a/libraries/animation/src/AnimationObject.h +++ b/libraries/animation/src/AnimationObject.h @@ -15,7 +15,7 @@ #include #include -#include +#include class QScriptEngine; diff --git a/libraries/baking/src/FBXBaker.cpp b/libraries/baking/src/FBXBaker.cpp index cef6c9b900..6349b06c49 100644 --- a/libraries/baking/src/FBXBaker.cpp +++ b/libraries/baking/src/FBXBaker.cpp @@ -27,7 +27,7 @@ #include -#include +#include #include #include "ModelBakingLoggingCategory.h" @@ -187,10 +187,10 @@ void FBXBaker::importScene() { return; } - FBXReader reader; + FBXSerializer serializer; qCDebug(model_baking) << "Parsing" << _modelURL; - _rootNode = reader._rootNode = reader.parseFBX(&fbxFile); + _rootNode = serializer._rootNode = serializer.parseFBX(&fbxFile); #ifdef HIFI_DUMP_FBX { @@ -206,8 +206,8 @@ void FBXBaker::importScene() { } #endif - _hfmModel = reader.extractHFMModel({}, _modelURL.toString()); - _textureContentMap = reader._textureContent; + _hfmModel = serializer.extractHFMModel({}, _modelURL.toString()); + _textureContentMap = serializer._textureContent; } void FBXBaker::rewriteAndBakeSceneModels() { @@ -232,7 +232,7 @@ void FBXBaker::rewriteAndBakeSceneModels() { if (objectChild.name == "Geometry") { // TODO Pull this out of _hfmModel instead so we don't have to reprocess it - auto extractedMesh = FBXReader::extractMesh(objectChild, meshIndex, false); + auto extractedMesh = FBXSerializer::extractMesh(objectChild, meshIndex, false); // Callback to get MaterialID GetMaterialIDCallback materialIDcallback = [&extractedMesh](int partIndex) { diff --git a/libraries/baking/src/ModelBaker.cpp b/libraries/baking/src/ModelBaker.cpp index ca352cebae..646f1bc010 100644 --- a/libraries/baking/src/ModelBaker.cpp +++ b/libraries/baking/src/ModelBaker.cpp @@ -13,7 +13,7 @@ #include -#include +#include #include #ifdef _WIN32 diff --git a/libraries/baking/src/OBJBaker.cpp b/libraries/baking/src/OBJBaker.cpp index d9f56b393e..389e708c12 100644 --- a/libraries/baking/src/OBJBaker.cpp +++ b/libraries/baking/src/OBJBaker.cpp @@ -14,7 +14,7 @@ #include #include -#include "OBJReader.h" +#include "OBJSerializer.h" #include "FBXWriter.h" const double UNIT_SCALE_FACTOR = 100.0; @@ -143,9 +143,9 @@ void OBJBaker::bakeOBJ() { QByteArray objData = objFile.readAll(); - bool combineParts = true; // set true so that OBJReader reads material info from material library - OBJReader reader; - auto geometry = reader.readOBJ(objData, QVariantHash(), combineParts, _modelURL); + bool combineParts = true; // set true so that OBJSerializer reads material info from material library + OBJSerializer serializer; + auto geometry = serializer.readOBJ(objData, QVariantHash(), combineParts, _modelURL); // Write OBJ Data as FBX tree nodes createFBXNodeTree(_rootNode, *geometry); @@ -219,7 +219,7 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, HFMModel& hfmModel) { FBXNode materialNode; materialNode.name = MATERIAL_NODE_NAME; if (hfmModel.materials.size() == 1) { - // case when no material information is provided, OBJReader considers it as a single default material + // case when no material information is provided, OBJSerializer considers it as a single default material for (auto& materialID : hfmModel.materials.keys()) { setMaterialNodeProperties(materialNode, materialID, hfmModel); } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 9a68f81b66..2b1d70f4d0 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -421,7 +421,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { uint32_t numIndices = (uint32_t)meshPart.triangleIndices.size(); // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up //assert(numIndices % TRIANGLE_STRIDE == 0); - numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader + numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXSerializer for (uint32_t j = 0; j < numIndices; j += TRIANGLE_STRIDE) { glm::vec3 p0 = mesh.vertices[meshPart.triangleIndices[j]]; @@ -442,7 +442,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { numIndices = (uint32_t)meshPart.quadIndices.size(); // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up //assert(numIndices % QUAD_STRIDE == 0); - numIndices -= numIndices % QUAD_STRIDE; // WORKAROUND lack of sanity checking in FBXReader + numIndices -= numIndices % QUAD_STRIDE; // WORKAROUND lack of sanity checking in FBXSerializer for (uint32_t j = 0; j < numIndices; j += QUAD_STRIDE) { glm::vec3 p0 = mesh.vertices[meshPart.quadIndices[j]]; @@ -595,7 +595,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { if (partItr->_topology == graphics::Mesh::TRIANGLES) { // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up //assert(numIndices % TRIANGLE_STRIDE == 0); - numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader + numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXSerializer auto indexItr = indices.cbegin() + partItr->_startIndex; auto indexEnd = indexItr + numIndices; @@ -652,7 +652,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { if (partItr->_topology == graphics::Mesh::TRIANGLES) { // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up //assert(numIndices% TRIANGLE_STRIDE == 0); - numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader + numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXSerializer auto indexItr = indices.cbegin() + partItr->_startIndex; auto indexEnd = indexItr + numIndices; diff --git a/libraries/fbx/src/FBX.h b/libraries/fbx/src/FBX.h index 90de82e310..157ca5b282 100644 --- a/libraries/fbx/src/FBX.h +++ b/libraries/fbx/src/FBX.h @@ -33,7 +33,7 @@ using NormalType = glm::vec3; #define FBX_NORMAL_ELEMENT gpu::Element::VEC3F_XYZ #endif -// See comment in FBXReader::parseFBX(). +// See comment in FBXSerializer::parseFBX(). static const int FBX_HEADER_BYTES_BEFORE_VERSION = 23; static const QByteArray FBX_BINARY_PROLOG("Kaydara FBX Binary "); static const QByteArray FBX_BINARY_PROLOG2("\0\x1a\0", 3); diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXSerializer.cpp similarity index 98% rename from libraries/fbx/src/FBXReader.cpp rename to libraries/fbx/src/FBXSerializer.cpp index cea3d079bc..fb7d95cf37 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1,5 +1,5 @@ // -// FBXReader.cpp +// FBXSerializer.cpp // interface/src/renderer // // Created by Andrzej Kapolka on 9/18/13. @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "FBXReader.h" +#include "FBXSerializer.h" #include #include @@ -36,7 +36,7 @@ #include // TOOL: Uncomment the following line to enable the filtering of all the unkwnon fields of a node so we can break point easily while loading a model with problems... -//#define DEBUG_FBXREADER +//#define DEBUG_FBXSERIALIZER using namespace std; @@ -254,13 +254,13 @@ HFMBlendshape extractBlendshape(const FBXNode& object) { HFMBlendshape blendshape; foreach (const FBXNode& data, object.children) { if (data.name == "Indexes") { - blendshape.indices = FBXReader::getIntVector(data); + blendshape.indices = FBXSerializer::getIntVector(data); } else if (data.name == "Vertices") { - blendshape.vertices = FBXReader::createVec3Vector(FBXReader::getDoubleVector(data)); + blendshape.vertices = FBXSerializer::createVec3Vector(FBXSerializer::getDoubleVector(data)); } else if (data.name == "Normals") { - blendshape.normals = FBXReader::createVec3Vector(FBXReader::getDoubleVector(data)); + blendshape.normals = FBXSerializer::createVec3Vector(FBXSerializer::getDoubleVector(data)); } } return blendshape; @@ -384,7 +384,7 @@ HFMLight extractLight(const FBXNode& object) { if (propname == "Intensity") { light.intensity = 0.01f * property.properties.at(valIndex).value(); } else if (propname == "Color") { - light.color = FBXReader::getVec3(property.properties, valIndex); + light.color = FBXSerializer::getVec3(property.properties, valIndex); } } } @@ -392,7 +392,7 @@ HFMLight extractLight(const FBXNode& object) { || subobject.name == "TypeFlags") { } } -#if defined(DEBUG_FBXREADER) +#if defined(DEBUG_FBXSERIALIZER) QString type = object.properties.at(0).toString(); type = object.properties.at(1).toString(); @@ -417,7 +417,7 @@ QByteArray fileOnUrl(const QByteArray& filepath, const QString& url) { return filepath.mid(filepath.lastIndexOf('/') + 1); } -HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& url) { +HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QString& url) { const FBXNode& node = _rootNode; QMap meshes; QHash modelIDsToNames; @@ -488,7 +488,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& } } QMultiHash blendshapeChannelIndices; -#if defined(DEBUG_FBXREADER) +#if defined(DEBUG_FBXSERIALIZER) int unknown = 0; #endif HFMModel* hfmModelPtr = new HFMModel; @@ -736,7 +736,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& extractBlendshape(subobject) }; blendshapes.append(blendshape); } -#if defined(DEBUG_FBXREADER) +#if defined(DEBUG_FBXSERIALIZER) else if (subobject.name == "TypeFlags") { QString attributetype = subobject.properties.at(0).toString(); if (!attributetype.empty()) { @@ -862,7 +862,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& tex.scaling.z = 1.0f; } } -#if defined(DEBUG_FBXREADER) +#if defined(DEBUG_FBXSERIALIZER) else { QString propName = v; unknown++; @@ -871,7 +871,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& } } } -#if defined(DEBUG_FBXREADER) +#if defined(DEBUG_FBXSERIALIZER) else { if (subobject.name == "Type") { } else if (subobject.name == "Version") { @@ -1044,7 +1044,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& } } } -#if defined(DEBUG_FBXREADER) +#if defined(DEBUG_FBXSERIALIZER) else { QString propname = subobject.name.data(); int unknown = 0; @@ -1061,7 +1061,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& } else if (object.name == "NodeAttribute") { -#if defined(DEBUG_FBXREADER) +#if defined(DEBUG_FBXSERIALIZER) std::vector properties; foreach(const QVariant& v, object.properties) { properties.push_back(v.toString()); @@ -1124,7 +1124,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& animationCurves.insert(getID(object.properties), curve); } -#if defined(DEBUG_FBXREADER) +#if defined(DEBUG_FBXSERIALIZER) else { QString objectname = object.name.data(); if ( objectname == "Pose" @@ -1215,7 +1215,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& } } } -#if defined(DEBUG_FBXREADER) +#if defined(DEBUG_FBXSERIALIZER) else { QString objectname = child.name.data(); if ( objectname == "Pose" @@ -1803,12 +1803,12 @@ HFMModel* readFBX(const QByteArray& data, const QVariantHash& mapping, const QSt } HFMModel* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { - FBXReader reader; - reader._rootNode = FBXReader::parseFBX(device); - reader._loadLightmaps = loadLightmaps; - reader._lightmapLevel = lightmapLevel; + FBXSerializer serializer; + serializer._rootNode = FBXSerializer::parseFBX(device); + serializer._loadLightmaps = loadLightmaps; + serializer._lightmapLevel = lightmapLevel; qCDebug(modelformat) << "Reading FBX: " << url; - return reader.extractHFMModel(mapping, url); + return serializer.extractHFMModel(mapping, url); } diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXSerializer.h similarity index 97% rename from libraries/fbx/src/FBXReader.h rename to libraries/fbx/src/FBXSerializer.h index c74b4dc8ac..9809b257e8 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXSerializer.h @@ -1,5 +1,5 @@ // -// FBXReader.h +// FBXSerializer.h // interface/src/renderer // // Created by Andrzej Kapolka on 9/18/13. @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_FBXReader_h -#define hifi_FBXReader_h +#ifndef hifi_FBXSerializer_h +#define hifi_FBXSerializer_h #include #include @@ -102,7 +102,7 @@ public: class ExtractedMesh; -class FBXReader { +class FBXSerializer { public: HFMModel* _hfmModel; @@ -166,4 +166,4 @@ public: static QVector getDoubleVector(const FBXNode& node); }; -#endif // hifi_FBXReader_h +#endif // hifi_FBXSerializer_h diff --git a/libraries/fbx/src/FBXReader_Material.cpp b/libraries/fbx/src/FBXSerializer_Material.cpp similarity index 98% rename from libraries/fbx/src/FBXReader_Material.cpp rename to libraries/fbx/src/FBXSerializer_Material.cpp index 2ec8cfde75..7713b36e57 100644 --- a/libraries/fbx/src/FBXReader_Material.cpp +++ b/libraries/fbx/src/FBXSerializer_Material.cpp @@ -1,5 +1,5 @@ // -// FBXReader_Material.cpp +// FBXSerializer_Material.cpp // interface/src/fbx // // Created by Sam Gateau on 8/27/2015. @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "FBXReader.h" +#include "FBXSerializer.h" #include #include @@ -27,7 +27,7 @@ #include -HFMTexture FBXReader::getTexture(const QString& textureID) { +HFMTexture FBXSerializer::getTexture(const QString& textureID) { HFMTexture texture; const QByteArray& filepath = _textureFilepaths.value(textureID); texture.content = _textureContent.value(filepath); @@ -69,7 +69,7 @@ HFMTexture FBXReader::getTexture(const QString& textureID) { return texture; } -void FBXReader::consolidateHFMMaterials(const QVariantHash& mapping) { +void FBXSerializer::consolidateHFMMaterials(const QVariantHash& mapping) { QString materialMapString = mapping.value("materialMap").toString(); QJsonDocument materialMapDocument = QJsonDocument::fromJson(materialMapString.toUtf8()); diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXSerializer_Mesh.cpp similarity index 98% rename from libraries/fbx/src/FBXReader_Mesh.cpp rename to libraries/fbx/src/FBXSerializer_Mesh.cpp index 527e3aef75..38533dbc42 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXSerializer_Mesh.cpp @@ -1,5 +1,5 @@ // -// FBXReader_Mesh.cpp +// FBXSerializer_Mesh.cpp // interface/src/fbx // // Created by Sam Gateau on 8/27/2015. @@ -33,7 +33,7 @@ #include #include -#include "FBXReader.h" +#include "FBXSerializer.h" #include @@ -191,7 +191,7 @@ void appendIndex(MeshData& data, QVector& indices, int index, bool deduplic } } -ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIndex, bool deduplicate) { +ExtractedMesh FBXSerializer::extractMesh(const FBXNode& object, unsigned int& meshIndex, bool deduplicate) { MeshData data; data.extracted.mesh.meshIndex = meshIndex++; @@ -254,7 +254,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn data.colorsByVertex = true; } -#if defined(FBXREADER_KILL_BLACK_COLOR_ATTRIBUTE) +#if defined(FBXSERIALIZER_KILL_BLACK_COLOR_ATTRIBUTE) // Potential feature where we decide to kill the color attribute is to dark? // Tested with the model: // https://hifi-public.s3.amazonaws.com/ryan/gardenLight2.fbx @@ -281,7 +281,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn } else if (subdata.name == "Name") { attrib.name = subdata.properties.at(0).toString(); } -#if defined(DEBUG_FBXREADER) +#if defined(DEBUG_FBXSERIALIZER) else { int unknown = 0; QString subname = subdata.name.data(); @@ -307,7 +307,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn } else if (subdata.name == "Name") { attrib.name = subdata.properties.at(0).toString(); } -#if defined(DEBUG_FBXREADER) +#if defined(DEBUG_FBXSERIALIZER) else { int unknown = 0; QString subname = subdata.name.data(); @@ -557,7 +557,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn return data.extracted; } -glm::vec3 FBXReader::normalizeDirForPacking(const glm::vec3& dir) { +glm::vec3 FBXSerializer::normalizeDirForPacking(const glm::vec3& dir) { auto maxCoord = glm::max(fabsf(dir.x), glm::max(fabsf(dir.y), fabsf(dir.z))); if (maxCoord > 1e-6f) { return dir / maxCoord; @@ -565,7 +565,7 @@ glm::vec3 FBXReader::normalizeDirForPacking(const glm::vec3& dir) { return dir; } -void FBXReader::buildModelMesh(HFMMesh& extractedMesh, const QString& url) { +void FBXSerializer::buildModelMesh(HFMMesh& extractedMesh, const QString& url) { unsigned int totalSourceIndices = 0; foreach(const HFMMeshPart& part, extractedMesh.parts) { totalSourceIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size()); diff --git a/libraries/fbx/src/FBXReader_Node.cpp b/libraries/fbx/src/FBXSerializer_Node.cpp similarity index 94% rename from libraries/fbx/src/FBXReader_Node.cpp rename to libraries/fbx/src/FBXSerializer_Node.cpp index cd717998dd..c982dfc7cb 100644 --- a/libraries/fbx/src/FBXReader_Node.cpp +++ b/libraries/fbx/src/FBXSerializer_Node.cpp @@ -1,5 +1,5 @@ // -// FBXReader_Node.cpp +// FBXSerializer_Node.cpp // interface/src/fbx // // Created by Sam Gateau on 8/27/2015. @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "FBXReader.h" +#include "FBXSerializer.h" #include #include @@ -345,7 +345,7 @@ FBXNode parseTextFBXNode(Tokenizer& tokenizer) { return node; } -FBXNode FBXReader::parseFBX(QIODevice* device) { +FBXNode FBXSerializer::parseFBX(QIODevice* device) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xff0000ff, device); // verify the prolog if (device->peek(FBX_BINARY_PROLOG.size()) != FBX_BINARY_PROLOG) { @@ -398,12 +398,12 @@ FBXNode FBXReader::parseFBX(QIODevice* device) { } -glm::vec3 FBXReader::getVec3(const QVariantList& properties, int index) { +glm::vec3 FBXSerializer::getVec3(const QVariantList& properties, int index) { return glm::vec3(properties.at(index).value(), properties.at(index + 1).value(), properties.at(index + 2).value()); } -QVector FBXReader::createVec4Vector(const QVector& doubleVector) { +QVector FBXSerializer::createVec4Vector(const QVector& doubleVector) { QVector values; for (const double* it = doubleVector.constData(), *end = it + ((doubleVector.size() / 4) * 4); it != end; ) { float x = *it++; @@ -416,7 +416,7 @@ QVector FBXReader::createVec4Vector(const QVector& doubleVect } -QVector FBXReader::createVec4VectorRGBA(const QVector& doubleVector, glm::vec4& average) { +QVector FBXSerializer::createVec4VectorRGBA(const QVector& doubleVector, glm::vec4& average) { QVector values; for (const double* it = doubleVector.constData(), *end = it + ((doubleVector.size() / 4) * 4); it != end; ) { float x = *it++; @@ -433,7 +433,7 @@ QVector FBXReader::createVec4VectorRGBA(const QVector& double return values; } -QVector FBXReader::createVec3Vector(const QVector& doubleVector) { +QVector FBXSerializer::createVec3Vector(const QVector& doubleVector) { QVector values; for (const double* it = doubleVector.constData(), *end = it + ((doubleVector.size() / 3) * 3); it != end; ) { float x = *it++; @@ -444,7 +444,7 @@ QVector FBXReader::createVec3Vector(const QVector& doubleVect return values; } -QVector FBXReader::createVec2Vector(const QVector& doubleVector) { +QVector FBXSerializer::createVec2Vector(const QVector& doubleVector) { QVector values; for (const double* it = doubleVector.constData(), *end = it + ((doubleVector.size() / 2) * 2); it != end; ) { float s = *it++; @@ -454,14 +454,14 @@ QVector FBXReader::createVec2Vector(const QVector& doubleVect return values; } -glm::mat4 FBXReader::createMat4(const QVector& doubleVector) { +glm::mat4 FBXSerializer::createMat4(const QVector& doubleVector) { return glm::mat4(doubleVector.at(0), doubleVector.at(1), doubleVector.at(2), doubleVector.at(3), doubleVector.at(4), doubleVector.at(5), doubleVector.at(6), doubleVector.at(7), doubleVector.at(8), doubleVector.at(9), doubleVector.at(10), doubleVector.at(11), doubleVector.at(12), doubleVector.at(13), doubleVector.at(14), doubleVector.at(15)); } -QVector FBXReader::getIntVector(const FBXNode& node) { +QVector FBXSerializer::getIntVector(const FBXNode& node) { foreach (const FBXNode& child, node.children) { if (child.name == "a") { return getIntVector(child); @@ -480,7 +480,7 @@ QVector FBXReader::getIntVector(const FBXNode& node) { return vector; } -QVector FBXReader::getFloatVector(const FBXNode& node) { +QVector FBXSerializer::getFloatVector(const FBXNode& node) { foreach (const FBXNode& child, node.children) { if (child.name == "a") { return getFloatVector(child); @@ -499,7 +499,7 @@ QVector FBXReader::getFloatVector(const FBXNode& node) { return vector; } -QVector FBXReader::getDoubleVector(const FBXNode& node) { +QVector FBXSerializer::getDoubleVector(const FBXNode& node) { foreach (const FBXNode& child, node.children) { if (child.name == "a") { return getDoubleVector(child); diff --git a/libraries/fbx/src/GLTFReader.cpp b/libraries/fbx/src/GLTFSerializer.cpp similarity index 94% rename from libraries/fbx/src/GLTFReader.cpp rename to libraries/fbx/src/GLTFSerializer.cpp index 9cd43ddf08..5e60cfffe7 100644 --- a/libraries/fbx/src/GLTFReader.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -1,5 +1,5 @@ // -// GLTFReader.cpp +// GLTFSerializer.cpp // libraries/fbx/src // // Created by Luis Cuenca on 8/30/17. @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "GLTFReader.h" +#include "GLTFSerializer.h" #include #include @@ -33,14 +33,14 @@ #include #include -#include "FBXReader.h" +#include "FBXSerializer.h" -GLTFReader::GLTFReader() { +GLTFSerializer::GLTFSerializer() { } -bool GLTFReader::getStringVal(const QJsonObject& object, const QString& fieldname, +bool GLTFSerializer::getStringVal(const QJsonObject& object, const QString& fieldname, QString& value, QMap& defined) { bool _defined = (object.contains(fieldname) && object[fieldname].isString()); if (_defined) { @@ -50,7 +50,7 @@ bool GLTFReader::getStringVal(const QJsonObject& object, const QString& fieldnam return _defined; } -bool GLTFReader::getBoolVal(const QJsonObject& object, const QString& fieldname, +bool GLTFSerializer::getBoolVal(const QJsonObject& object, const QString& fieldname, bool& value, QMap& defined) { bool _defined = (object.contains(fieldname) && object[fieldname].isBool()); if (_defined) { @@ -60,7 +60,7 @@ bool GLTFReader::getBoolVal(const QJsonObject& object, const QString& fieldname, return _defined; } -bool GLTFReader::getIntVal(const QJsonObject& object, const QString& fieldname, +bool GLTFSerializer::getIntVal(const QJsonObject& object, const QString& fieldname, int& value, QMap& defined) { bool _defined = (object.contains(fieldname) && !object[fieldname].isNull()); if (_defined) { @@ -70,7 +70,7 @@ bool GLTFReader::getIntVal(const QJsonObject& object, const QString& fieldname, return _defined; } -bool GLTFReader::getDoubleVal(const QJsonObject& object, const QString& fieldname, +bool GLTFSerializer::getDoubleVal(const QJsonObject& object, const QString& fieldname, double& value, QMap& defined) { bool _defined = (object.contains(fieldname) && object[fieldname].isDouble()); if (_defined) { @@ -79,7 +79,7 @@ bool GLTFReader::getDoubleVal(const QJsonObject& object, const QString& fieldnam defined.insert(fieldname, _defined); return _defined; } -bool GLTFReader::getObjectVal(const QJsonObject& object, const QString& fieldname, +bool GLTFSerializer::getObjectVal(const QJsonObject& object, const QString& fieldname, QJsonObject& value, QMap& defined) { bool _defined = (object.contains(fieldname) && object[fieldname].isObject()); if (_defined) { @@ -89,7 +89,7 @@ bool GLTFReader::getObjectVal(const QJsonObject& object, const QString& fieldnam return _defined; } -bool GLTFReader::getIntArrayVal(const QJsonObject& object, const QString& fieldname, +bool GLTFSerializer::getIntArrayVal(const QJsonObject& object, const QString& fieldname, QVector& values, QMap& defined) { bool _defined = (object.contains(fieldname) && object[fieldname].isArray()); if (_defined) { @@ -104,7 +104,7 @@ bool GLTFReader::getIntArrayVal(const QJsonObject& object, const QString& fieldn return _defined; } -bool GLTFReader::getDoubleArrayVal(const QJsonObject& object, const QString& fieldname, +bool GLTFSerializer::getDoubleArrayVal(const QJsonObject& object, const QString& fieldname, QVector& values, QMap& defined) { bool _defined = (object.contains(fieldname) && object[fieldname].isArray()); if (_defined) { @@ -119,7 +119,7 @@ bool GLTFReader::getDoubleArrayVal(const QJsonObject& object, const QString& fie return _defined; } -bool GLTFReader::getObjectArrayVal(const QJsonObject& object, const QString& fieldname, +bool GLTFSerializer::getObjectArrayVal(const QJsonObject& object, const QString& fieldname, QJsonArray& objects, QMap& defined) { bool _defined = (object.contains(fieldname) && object[fieldname].isArray()); if (_defined) { @@ -129,7 +129,7 @@ bool GLTFReader::getObjectArrayVal(const QJsonObject& object, const QString& fie return _defined; } -int GLTFReader::getMeshPrimitiveRenderingMode(const QString& type) +int GLTFSerializer::getMeshPrimitiveRenderingMode(const QString& type) { if (type == "POINTS") { return GLTFMeshPrimitivesRenderingMode::POINTS; @@ -155,7 +155,7 @@ int GLTFReader::getMeshPrimitiveRenderingMode(const QString& type) return GLTFMeshPrimitivesRenderingMode::TRIANGLES; } -int GLTFReader::getAccessorType(const QString& type) +int GLTFSerializer::getAccessorType(const QString& type) { if (type == "SCALAR") { return GLTFAccessorType::SCALAR; @@ -181,7 +181,7 @@ int GLTFReader::getAccessorType(const QString& type) return GLTFAccessorType::SCALAR; } -int GLTFReader::getMaterialAlphaMode(const QString& type) +int GLTFSerializer::getMaterialAlphaMode(const QString& type) { if (type == "OPAQUE") { return GLTFMaterialAlphaMode::OPAQUE; @@ -195,7 +195,7 @@ int GLTFReader::getMaterialAlphaMode(const QString& type) return GLTFMaterialAlphaMode::OPAQUE; } -int GLTFReader::getCameraType(const QString& type) +int GLTFSerializer::getCameraType(const QString& type) { if (type == "orthographic") { return GLTFCameraTypes::ORTHOGRAPHIC; @@ -206,7 +206,7 @@ int GLTFReader::getCameraType(const QString& type) return GLTFCameraTypes::PERSPECTIVE; } -int GLTFReader::getImageMimeType(const QString& mime) +int GLTFSerializer::getImageMimeType(const QString& mime) { if (mime == "image/jpeg") { return GLTFImageMimetype::JPEG; @@ -217,7 +217,7 @@ int GLTFReader::getImageMimeType(const QString& mime) return GLTFImageMimetype::JPEG; } -int GLTFReader::getAnimationSamplerInterpolation(const QString& interpolation) +int GLTFSerializer::getAnimationSamplerInterpolation(const QString& interpolation) { if (interpolation == "LINEAR") { return GLTFAnimationSamplerInterpolation::LINEAR; @@ -225,7 +225,7 @@ int GLTFReader::getAnimationSamplerInterpolation(const QString& interpolation) return GLTFAnimationSamplerInterpolation::LINEAR; } -bool GLTFReader::setAsset(const QJsonObject& object) { +bool GLTFSerializer::setAsset(const QJsonObject& object) { QJsonObject jsAsset; bool isAssetDefined = getObjectVal(object, "asset", jsAsset, _file.defined); if (isAssetDefined) { @@ -239,7 +239,7 @@ bool GLTFReader::setAsset(const QJsonObject& object) { return isAssetDefined; } -bool GLTFReader::addAccessor(const QJsonObject& object) { +bool GLTFSerializer::addAccessor(const QJsonObject& object) { GLTFAccessor accessor; getIntVal(object, "bufferView", accessor.bufferView, accessor.defined); @@ -259,7 +259,7 @@ bool GLTFReader::addAccessor(const QJsonObject& object) { return true; } -bool GLTFReader::addAnimation(const QJsonObject& object) { +bool GLTFSerializer::addAnimation(const QJsonObject& object) { GLTFAnimation animation; QJsonArray channels; @@ -297,7 +297,7 @@ bool GLTFReader::addAnimation(const QJsonObject& object) { return true; } -bool GLTFReader::addBufferView(const QJsonObject& object) { +bool GLTFSerializer::addBufferView(const QJsonObject& object) { GLTFBufferView bufferview; getIntVal(object, "buffer", bufferview.buffer, bufferview.defined); @@ -310,7 +310,7 @@ bool GLTFReader::addBufferView(const QJsonObject& object) { return true; } -bool GLTFReader::addBuffer(const QJsonObject& object) { +bool GLTFSerializer::addBuffer(const QJsonObject& object) { GLTFBuffer buffer; getIntVal(object, "byteLength", buffer.byteLength, buffer.defined); @@ -324,7 +324,7 @@ bool GLTFReader::addBuffer(const QJsonObject& object) { return true; } -bool GLTFReader::addCamera(const QJsonObject& object) { +bool GLTFSerializer::addCamera(const QJsonObject& object) { GLTFCamera camera; QJsonObject jsPerspective; @@ -352,7 +352,7 @@ bool GLTFReader::addCamera(const QJsonObject& object) { return true; } -bool GLTFReader::addImage(const QJsonObject& object) { +bool GLTFSerializer::addImage(const QJsonObject& object) { GLTFImage image; QString mime; @@ -367,7 +367,7 @@ bool GLTFReader::addImage(const QJsonObject& object) { return true; } -bool GLTFReader::getIndexFromObject(const QJsonObject& object, const QString& field, +bool GLTFSerializer::getIndexFromObject(const QJsonObject& object, const QString& field, int& outidx, QMap& defined) { QJsonObject subobject; if (getObjectVal(object, field, subobject, defined)) { @@ -377,7 +377,7 @@ bool GLTFReader::getIndexFromObject(const QJsonObject& object, const QString& fi return false; } -bool GLTFReader::addMaterial(const QJsonObject& object) { +bool GLTFSerializer::addMaterial(const QJsonObject& object) { GLTFMaterial material; getStringVal(object, "name", material.name, material.defined); @@ -413,7 +413,7 @@ bool GLTFReader::addMaterial(const QJsonObject& object) { return true; } -bool GLTFReader::addMesh(const QJsonObject& object) { +bool GLTFSerializer::addMesh(const QJsonObject& object) { GLTFMesh mesh; getStringVal(object, "name", mesh.name, mesh.defined); @@ -467,7 +467,7 @@ bool GLTFReader::addMesh(const QJsonObject& object) { return true; } -bool GLTFReader::addNode(const QJsonObject& object) { +bool GLTFSerializer::addNode(const QJsonObject& object) { GLTFNode node; getStringVal(object, "name", node.name, node.defined); @@ -487,7 +487,7 @@ bool GLTFReader::addNode(const QJsonObject& object) { return true; } -bool GLTFReader::addSampler(const QJsonObject& object) { +bool GLTFSerializer::addSampler(const QJsonObject& object) { GLTFSampler sampler; getIntVal(object, "magFilter", sampler.magFilter, sampler.defined); @@ -501,7 +501,7 @@ bool GLTFReader::addSampler(const QJsonObject& object) { } -bool GLTFReader::addScene(const QJsonObject& object) { +bool GLTFSerializer::addScene(const QJsonObject& object) { GLTFScene scene; getStringVal(object, "name", scene.name, scene.defined); @@ -511,7 +511,7 @@ bool GLTFReader::addScene(const QJsonObject& object) { return true; } -bool GLTFReader::addSkin(const QJsonObject& object) { +bool GLTFSerializer::addSkin(const QJsonObject& object) { GLTFSkin skin; getIntVal(object, "inverseBindMatrices", skin.inverseBindMatrices, skin.defined); @@ -523,7 +523,7 @@ bool GLTFReader::addSkin(const QJsonObject& object) { return true; } -bool GLTFReader::addTexture(const QJsonObject& object) { +bool GLTFSerializer::addTexture(const QJsonObject& object) { GLTFTexture texture; getIntVal(object, "sampler", texture.sampler, texture.defined); getIntVal(object, "source", texture.source, texture.defined); @@ -533,7 +533,7 @@ bool GLTFReader::addTexture(const QJsonObject& object) { return true; } -bool GLTFReader::parseGLTF(const QByteArray& data) { +bool GLTFSerializer::parseGLTF(const QByteArray& data) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); QJsonDocument d = QJsonDocument::fromJson(data); @@ -664,7 +664,7 @@ bool GLTFReader::parseGLTF(const QByteArray& data) { return true; } -glm::mat4 GLTFReader::getModelTransform(const GLTFNode& node) { +glm::mat4 GLTFSerializer::getModelTransform(const GLTFNode& node) { glm::mat4 tmat = glm::mat4(1.0); if (node.defined["matrix"] && node.matrix.size() == 16) { @@ -697,7 +697,7 @@ glm::mat4 GLTFReader::getModelTransform(const GLTFNode& node) { return tmat; } -bool GLTFReader::buildGeometry(HFMModel& hfmModel, const QUrl& url) { +bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const QUrl& url) { //Build dependencies QVector> nodeDependencies(_file.nodes.size()); @@ -899,7 +899,7 @@ bool GLTFReader::buildGeometry(HFMModel& hfmModel, const QUrl& url) { } mesh.meshIndex = hfmModel.meshes.size(); - FBXReader::buildModelMesh(mesh, url.toString()); + FBXSerializer::buildModelMesh(mesh, url.toString()); } } @@ -910,7 +910,7 @@ bool GLTFReader::buildGeometry(HFMModel& hfmModel, const QUrl& url) { return true; } -HFMModel* GLTFReader::readGLTF(QByteArray& data, const QVariantHash& mapping, +HFMModel* GLTFSerializer::readGLTF(QByteArray& data, const QVariantHash& mapping, const QUrl& url, bool loadLightmaps, float lightmapLevel) { _url = url; @@ -934,7 +934,7 @@ HFMModel* GLTFReader::readGLTF(QByteArray& data, const QVariantHash& mapping, } -bool GLTFReader::readBinary(const QString& url, QByteArray& outdata) { +bool GLTFSerializer::readBinary(const QString& url, QByteArray& outdata) { QUrl binaryUrl = _url.resolved(url); qCDebug(modelformat) << "binaryUrl: " << binaryUrl << " OriginalUrl: " << _url; @@ -944,7 +944,7 @@ bool GLTFReader::readBinary(const QString& url, QByteArray& outdata) { return success; } -bool GLTFReader::doesResourceExist(const QString& url) { +bool GLTFSerializer::doesResourceExist(const QString& url) { if (_url.isEmpty()) { return false; } @@ -952,9 +952,9 @@ bool GLTFReader::doesResourceExist(const QString& url) { return DependencyManager::get()->resourceExists(candidateUrl); } -std::tuple GLTFReader::requestData(QUrl& url) { +std::tuple GLTFSerializer::requestData(QUrl& url) { auto request = DependencyManager::get()->createResourceRequest( - nullptr, url, true, -1, "GLTFReader::requestData"); + nullptr, url, true, -1, "GLTFSerializer::requestData"); if (!request) { return std::make_tuple(false, QByteArray()); @@ -973,7 +973,7 @@ std::tuple GLTFReader::requestData(QUrl& url) { } -QNetworkReply* GLTFReader::request(QUrl& url, bool isTest) { +QNetworkReply* GLTFSerializer::request(QUrl& url, bool isTest) { if (!qApp) { return nullptr; } @@ -997,7 +997,7 @@ QNetworkReply* GLTFReader::request(QUrl& url, bool isTest) { return netReply; // trying to sync later on. } -HFMTexture GLTFReader::getHFMTexture(const GLTFTexture& texture) { +HFMTexture GLTFSerializer::getHFMTexture(const GLTFTexture& texture) { HFMTexture fbxtex = HFMTexture(); fbxtex.texcoordSet = 0; @@ -1014,7 +1014,7 @@ HFMTexture GLTFReader::getHFMTexture(const GLTFTexture& texture) { return fbxtex; } -void GLTFReader::setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& material) { +void GLTFSerializer::setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& material) { if (material.defined["name"]) { @@ -1077,7 +1077,7 @@ void GLTFReader::setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& materia } template -bool GLTFReader::readArray(const QByteArray& bin, int byteOffset, int count, +bool GLTFSerializer::readArray(const QByteArray& bin, int byteOffset, int count, QVector& outarray, int accessorType) { QDataStream blobstream(bin); @@ -1134,7 +1134,7 @@ bool GLTFReader::readArray(const QByteArray& bin, int byteOffset, int count, return true; } template -bool GLTFReader::addArrayOfType(const QByteArray& bin, int byteOffset, int count, +bool GLTFSerializer::addArrayOfType(const QByteArray& bin, int byteOffset, int count, QVector& outarray, int accessorType, int componentType) { switch (componentType) { @@ -1158,7 +1158,7 @@ bool GLTFReader::addArrayOfType(const QByteArray& bin, int byteOffset, int count return false; } -void GLTFReader::retriangulate(const QVector& inIndices, const QVector& in_vertices, +void GLTFSerializer::retriangulate(const QVector& inIndices, const QVector& in_vertices, const QVector& in_normals, QVector& outIndices, QVector& out_vertices, QVector& out_normals) { for (int i = 0; i < inIndices.size(); i = i + 3) { @@ -1181,7 +1181,7 @@ void GLTFReader::retriangulate(const QVector& inIndices, const QVector // .obj files are not locale-specific. The C/ASCII charset applies. #include @@ -27,7 +27,7 @@ #include #include -#include "FBXReader.h" +#include "FBXSerializer.h" #include #include @@ -238,7 +238,7 @@ void OBJFace::addFrom(const OBJFace* face, int index) { // add using data from f } } -bool OBJReader::isValidTexture(const QByteArray &filename) { +bool OBJSerializer::isValidTexture(const QByteArray &filename) { if (_url.isEmpty()) { return false; } @@ -247,7 +247,7 @@ bool OBJReader::isValidTexture(const QByteArray &filename) { return DependencyManager::get()->resourceExists(candidateUrl); } -void OBJReader::parseMaterialLibrary(QIODevice* device) { +void OBJSerializer::parseMaterialLibrary(QIODevice* device) { OBJTokenizer tokenizer(device); QString matName = SMART_DEFAULT_MATERIAL_NAME; OBJMaterial& currentMaterial = materials[matName]; @@ -255,7 +255,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { switch (tokenizer.nextToken()) { case OBJTokenizer::COMMENT_TOKEN: #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader MTLLIB comment:" << tokenizer.getComment(); + qCDebug(modelformat) << "OBJSerializer MTLLIB comment:" << tokenizer.getComment(); #endif break; case OBJTokenizer::DATUM_TOKEN: @@ -264,7 +264,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { materials[matName] = currentMaterial; #ifdef WANT_DEBUG qCDebug(modelformat) << - "OBJ Reader Last material illumination model:" << currentMaterial.illuminationModel << + "OBJSerializer Last material illumination model:" << currentMaterial.illuminationModel << " shininess:" << currentMaterial.shininess << " opacity:" << currentMaterial.opacity << " diffuse color:" << currentMaterial.diffuseColor << @@ -287,7 +287,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { matName = tokenizer.getDatum(); currentMaterial = materials[matName]; #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader Starting new material definition " << matName; + qCDebug(modelformat) << "OBJSerializer Starting new material definition " << matName; #endif currentMaterial.diffuseTextureFilename = ""; currentMaterial.emissiveTextureFilename = ""; @@ -299,7 +299,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { currentMaterial.shininess = tokenizer.getFloat(); } else if (token == "Ni") { #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader Ignoring material Ni " << tokenizer.getFloat(); + qCDebug(modelformat) << "OBJSerializer Ignoring material Ni " << tokenizer.getFloat(); #else tokenizer.getFloat(); #endif @@ -311,13 +311,13 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { currentMaterial.illuminationModel = tokenizer.getFloat(); } else if (token == "Tf") { #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader Ignoring material Tf " << tokenizer.getVec3(); + qCDebug(modelformat) << "OBJSerializer Ignoring material Tf " << tokenizer.getVec3(); #else tokenizer.getVec3(); #endif } else if (token == "Ka") { #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader Ignoring material Ka " << tokenizer.getVec3();; + qCDebug(modelformat) << "OBJSerializer Ignoring material Ka " << tokenizer.getVec3();; #else tokenizer.getVec3(); #endif @@ -334,7 +334,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { parseTextureLine(textureLine, filename, textureOptions); if (filename.endsWith(".tga")) { #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader WARNING: currently ignoring tga texture " << filename << " in " << _url; + qCDebug(modelformat) << "OBJSerializer WARNING: currently ignoring tga texture " << filename << " in " << _url; #endif break; } @@ -354,7 +354,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { } } -void OBJReader::parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions) { +void OBJSerializer::parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions) { // Texture options reference http://paulbourke.net/dataformats/mtl/ // and https://wikivisually.com/wiki/Material_Template_Library @@ -368,7 +368,7 @@ void OBJReader::parseTextureLine(const QByteArray& textureLine, QByteArray& file if (option == "-blendu" || option == "-blendv") { #ifdef WANT_DEBUG const std::string& onoff = parser[i++]; - qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option" << option.c_str() << onoff.c_str(); + qCDebug(modelformat) << "OBJSerializer WARNING: Ignoring texture option" << option.c_str() << onoff.c_str(); #endif } else if (option == "-bm") { const std::string& bm = parser[i++]; @@ -377,22 +377,22 @@ void OBJReader::parseTextureLine(const QByteArray& textureLine, QByteArray& file #ifdef WANT_DEBUG const std::string& boost = parser[i++]; float boostFloat = std::stof(boost); - qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option" << option.c_str() << boost.c_str(); + qCDebug(modelformat) << "OBJSerializer WARNING: Ignoring texture option" << option.c_str() << boost.c_str(); #endif } else if (option == "-cc") { #ifdef WANT_DEBUG const std::string& onoff = parser[i++]; - qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option" << option.c_str() << onoff.c_str(); + qCDebug(modelformat) << "OBJSerializer WARNING: Ignoring texture option" << option.c_str() << onoff.c_str(); #endif } else if (option == "-clamp") { #ifdef WANT_DEBUG const std::string& onoff = parser[i++]; - qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option" << option.c_str() << onoff.c_str(); + qCDebug(modelformat) << "OBJSerializer WARNING: Ignoring texture option" << option.c_str() << onoff.c_str(); #endif } else if (option == "-imfchan") { #ifdef WANT_DEBUG const std::string& imfchan = parser[i++]; - qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option" << option.c_str() << imfchan.c_str(); + qCDebug(modelformat) << "OBJSerializer WARNING: Ignoring texture option" << option.c_str() << imfchan.c_str(); #endif } else if (option == "-mm") { if (i + 1 < parser.size()) { @@ -401,7 +401,7 @@ void OBJReader::parseTextureLine(const QByteArray& textureLine, QByteArray& file const std::string& mmGain = parser[i++]; float mmBaseFloat = std::stof(mmBase); float mmGainFloat = std::stof(mmGain); - qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option" << option.c_str() << mmBase.c_str() << mmGain.c_str(); + qCDebug(modelformat) << "OBJSerializer WARNING: Ignoring texture option" << option.c_str() << mmBase.c_str() << mmGain.c_str(); #endif } } else if (option == "-o" || option == "-s" || option == "-t") { @@ -413,23 +413,23 @@ void OBJReader::parseTextureLine(const QByteArray& textureLine, QByteArray& file float uFloat = std::stof(u); float vFloat = std::stof(v); float wFloat = std::stof(w); - qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option" << option.c_str() << u.c_str() << v.c_str() << w.c_str(); + qCDebug(modelformat) << "OBJSerializer WARNING: Ignoring texture option" << option.c_str() << u.c_str() << v.c_str() << w.c_str(); #endif } } else if (option == "-texres") { #ifdef WANT_DEBUG const std::string& texres = parser[i++]; float texresFloat = std::stof(texres); - qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option" << option.c_str() << texres.c_str(); + qCDebug(modelformat) << "OBJSerializer WARNING: Ignoring texture option" << option.c_str() << texres.c_str(); #endif } else if (option == "-type") { #ifdef WANT_DEBUG const std::string& type = parser[i++]; - qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option" << option.c_str() << type.c_str(); + qCDebug(modelformat) << "OBJSerializer WARNING: Ignoring texture option" << option.c_str() << type.c_str(); #endif } else if (option[0] == '-') { #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring unsupported texture option" << option.c_str(); + qCDebug(modelformat) << "OBJSerializer WARNING: Ignoring unsupported texture option" << option.c_str(); #endif } } else { // assume filename at end when no more options @@ -444,7 +444,7 @@ void OBJReader::parseTextureLine(const QByteArray& textureLine, QByteArray& file std::tuple requestData(QUrl& url) { auto request = DependencyManager::get()->createResourceRequest( - nullptr, url, true, -1, "(OBJReader) requestData"); + nullptr, url, true, -1, "(OBJSerializer) requestData"); if (!request) { return std::make_tuple(false, QByteArray()); @@ -488,7 +488,7 @@ QNetworkReply* request(QUrl& url, bool isTest) { } -bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMModel& hfmModel, +bool OBJSerializer::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMModel& hfmModel, float& scaleGuess, bool combineParts) { FaceGroup faces; HFMMesh& mesh = hfmModel.meshes[0]; @@ -557,7 +557,7 @@ bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mappi currentMaterialName = nextName; } #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader new current material:" << currentMaterialName; + qCDebug(modelformat) << "OBJSerializer new current material:" << currentMaterialName; #endif } } else if (token == "v") { @@ -652,7 +652,7 @@ done: } -HFMModel::Pointer OBJReader::readOBJ(QByteArray& data, const QVariantHash& mapping, bool combineParts, const QUrl& url) { +HFMModel::Pointer OBJSerializer::readOBJ(QByteArray& data, const QVariantHash& mapping, bool combineParts, const QUrl& url) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); QBuffer buffer { &data }; buffer.open(QIODevice::ReadOnly); @@ -720,7 +720,7 @@ HFMModel::Pointer OBJReader::readOBJ(QByteArray& data, const QVariantHash& mappi QString groupMaterialName = face.materialName; if (groupMaterialName.isEmpty() && specifiesUV) { #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader WARNING: " << url + qCDebug(modelformat) << "OBJSerializer WARNING: " << url << " needs a texture that isn't specified. Using default mechanism."; #endif groupMaterialName = SMART_DEFAULT_MATERIAL_NAME; @@ -822,11 +822,11 @@ HFMModel::Pointer OBJReader::readOBJ(QByteArray& data, const QVariantHash& mappi } // Build the single mesh. - FBXReader::buildModelMesh(mesh, url.toString()); + FBXSerializer::buildModelMesh(mesh, url.toString()); // hfmDebugDump(hfmModel); } catch(const std::exception& e) { - qCDebug(modelformat) << "OBJ reader fail: " << e.what(); + qCDebug(modelformat) << "OBJSerializer fail: " << e.what(); } QString queryPart = _url.query(); @@ -845,7 +845,7 @@ HFMModel::Pointer OBJReader::readOBJ(QByteArray& data, const QVariantHash& mappi preDefinedMaterial.diffuseColor = glm::vec3(1.0f); QVector extensions = { "jpg", "jpeg", "png", "tga" }; QByteArray base = basename.toUtf8(), textName = ""; - qCDebug(modelformat) << "OBJ Reader looking for default texture of" << url; + qCDebug(modelformat) << "OBJSerializer looking for default texture of" << url; for (int i = 0; i < extensions.count(); i++) { QByteArray candidateString = base + extensions[i]; if (isValidTexture(candidateString)) { @@ -856,7 +856,7 @@ HFMModel::Pointer OBJReader::readOBJ(QByteArray& data, const QVariantHash& mappi if (!textName.isEmpty()) { #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader found a default texture: " << textName; + qCDebug(modelformat) << "OBJSerializer found a default texture: " << textName; #endif preDefinedMaterial.diffuseTextureFilename = textName; } @@ -866,7 +866,7 @@ HFMModel::Pointer OBJReader::readOBJ(QByteArray& data, const QVariantHash& mappi foreach (QString libraryName, librariesSeen.keys()) { // Throw away any path part of libraryName, and merge against original url. QUrl libraryUrl = _url.resolved(QUrl(libraryName).fileName()); - qCDebug(modelformat) << "OBJ Reader material library" << libraryName << "used in" << _url; + qCDebug(modelformat) << "OBJSerializer material library" << libraryName << "used in" << _url; bool success; QByteArray data; std::tie(success, data) = requestData(libraryUrl); @@ -875,7 +875,7 @@ HFMModel::Pointer OBJReader::readOBJ(QByteArray& data, const QVariantHash& mappi buffer.open(QIODevice::ReadOnly); parseMaterialLibrary(&buffer); } else { - qCDebug(modelformat) << "OBJ Reader WARNING:" << libraryName << "did not answer"; + qCDebug(modelformat) << "OBJSerializer WARNING:" << libraryName << "did not answer"; } } } diff --git a/libraries/fbx/src/OBJReader.h b/libraries/fbx/src/OBJSerializer.h similarity index 97% rename from libraries/fbx/src/OBJReader.h rename to libraries/fbx/src/OBJSerializer.h index 0088e8e9d7..d33d2edf07 100644 --- a/libraries/fbx/src/OBJReader.h +++ b/libraries/fbx/src/OBJSerializer.h @@ -1,6 +1,6 @@ #include -#include "FBXReader.h" +#include "FBXSerializer.h" class OBJTokenizer { public: @@ -75,7 +75,7 @@ public: OBJMaterial() : shininess(0.0f), opacity(1.0f), diffuseColor(0.9f), specularColor(0.9f), emissiveColor(0.0f), illuminationModel(-1) {} }; -class OBJReader: public QObject { // QObject so we can make network requests. +class OBJSerializer: public QObject { // QObject so we can make network requests. Q_OBJECT public: typedef QVector FaceGroup; diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index dd58b0e75e..5a7e383630 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -12,9 +12,9 @@ #include "ModelCache.h" #include #include -#include "FBXReader.h" -#include "OBJReader.h" -#include "GLTFReader.h" +#include "FBXSerializer.h" +#include "OBJSerializer.h" +#include "GLTFSerializer.h" #include #include @@ -201,17 +201,17 @@ void GeometryReader::run() { throw QString("empty geometry, possibly due to an unsupported FBX version"); } } else if (_url.path().toLower().endsWith(".obj")) { - hfmModel = OBJReader().readOBJ(_data, _mapping, _combineParts, _url); + hfmModel = OBJSerializer().readOBJ(_data, _mapping, _combineParts, _url); } else if (_url.path().toLower().endsWith(".obj.gz")) { QByteArray uncompressedData; if (gunzip(_data, uncompressedData)){ - hfmModel = OBJReader().readOBJ(uncompressedData, _mapping, _combineParts, _url); + hfmModel = OBJSerializer().readOBJ(uncompressedData, _mapping, _combineParts, _url); } else { throw QString("failed to decompress .obj.gz"); } } else if (_url.path().toLower().endsWith(".gltf")) { - std::shared_ptr glreader = std::make_shared(); + std::shared_ptr glreader = std::make_shared(); hfmModel.reset(glreader->readGLTF(_data, _mapping, _url)); if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { throw QString("empty geometry, possibly due to an unsupported GLTF version"); diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index 1bb340b83c..9d458e7512 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -18,7 +18,7 @@ #include #include -#include "FBXReader.h" +#include "FBXSerializer.h" #include "TextureCache.h" // Alias instead of derive to avoid copying diff --git a/tests-manual/gpu/src/TestFbx.cpp b/tests-manual/gpu/src/TestFbx.cpp index 9253f8bc91..290913e406 100644 --- a/tests-manual/gpu/src/TestFbx.cpp +++ b/tests-manual/gpu/src/TestFbx.cpp @@ -12,7 +12,7 @@ #include -#include +#include struct MyVertex { vec3 position; diff --git a/tools/skeleton-dump/src/SkeletonDumpApp.cpp b/tools/skeleton-dump/src/SkeletonDumpApp.cpp index 10b13aef36..bad38f24ba 100644 --- a/tools/skeleton-dump/src/SkeletonDumpApp.cpp +++ b/tools/skeleton-dump/src/SkeletonDumpApp.cpp @@ -12,7 +12,7 @@ #include "SkeletonDumpApp.h" #include #include -#include +#include #include SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc, argv) { diff --git a/tools/vhacd-util/src/VHACDUtil.cpp b/tools/vhacd-util/src/VHACDUtil.cpp index 8de9c39da9..b1dcdebe60 100644 --- a/tools/vhacd-util/src/VHACDUtil.cpp +++ b/tools/vhacd-util/src/VHACDUtil.cpp @@ -17,7 +17,7 @@ #include -// FBXReader jumbles the order of the meshes by reading them back out of a hashtable. This will put +// FBXSerializer jumbles the order of the meshes by reading them back out of a hashtable. This will put // them back in the order in which they appeared in the file. bool HFMModelLessThan(const HFMMesh& e1, const HFMMesh& e2) { return e1.meshIndex < e2.meshIndex; @@ -44,7 +44,7 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, HFMModel& result) { HFMModel::Pointer hfmModel; if (filename.toLower().endsWith(".obj")) { bool combineParts = false; - hfmModel = OBJReader().readOBJ(fbxContents, QVariantHash(), combineParts); + hfmModel = OBJSerializer().readOBJ(fbxContents, QVariantHash(), combineParts); } else if (filename.toLower().endsWith(".fbx")) { hfmModel.reset(readFBX(fbxContents, QVariantHash(), filename)); } else { diff --git a/tools/vhacd-util/src/VHACDUtil.h b/tools/vhacd-util/src/VHACDUtil.h index dd8f606756..7a6f2f1db6 100644 --- a/tools/vhacd-util/src/VHACDUtil.h +++ b/tools/vhacd-util/src/VHACDUtil.h @@ -18,8 +18,8 @@ #include #include //c++11 feature #include -#include -#include +#include +#include #include namespace vhacd { diff --git a/tools/vhacd-util/src/VHACDUtilApp.h b/tools/vhacd-util/src/VHACDUtilApp.h index 7dadad20b3..1cbb29bb88 100644 --- a/tools/vhacd-util/src/VHACDUtilApp.h +++ b/tools/vhacd-util/src/VHACDUtilApp.h @@ -15,7 +15,7 @@ #include -#include +#include const int VHACD_RETURN_CODE_FAILURE_TO_READ = 1; const int VHACD_RETURN_CODE_FAILURE_TO_WRITE = 2; From 0271f7d3344182c07b15b546dea590912b0ab34c Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Wed, 7 Nov 2018 17:07:44 -0800 Subject: [PATCH 017/109] Create the HFMSerializer interface class --- libraries/hfm/src/hfm/HFMSerializer.h | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 libraries/hfm/src/hfm/HFMSerializer.h diff --git a/libraries/hfm/src/hfm/HFMSerializer.h b/libraries/hfm/src/hfm/HFMSerializer.h new file mode 100644 index 0000000000..bd63d8bf82 --- /dev/null +++ b/libraries/hfm/src/hfm/HFMSerializer.h @@ -0,0 +1,29 @@ +// +// FBXSerializer.h +// libraries/hfm/src/hfm +// +// Created by Sabrina Shanman on 2018/11/07. +// Copyright 2018 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_HFMSerializer_h +#define hifi_HFMSerializer_h + +#include +#include +#include + +#include "HFM.h" + +namespace hfm { + +class Serializer { + virtual Model* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl(), bool combineParts = false) = 0; +}; + +}; + +#endif // hifi_HFMSerializer_h From 00f2b4eeb9087aa043c77bc62e512823b61839ab Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 5 Nov 2018 17:30:44 -0800 Subject: [PATCH 018/109] Make the existing model serializers based on HFMSerializer --- interface/src/ModelPackager.cpp | 2 +- libraries/animation/src/AnimationCache.cpp | 2 +- libraries/baking/src/FBXBaker.cpp | 8 ++++---- libraries/baking/src/OBJBaker.cpp | 2 +- libraries/fbx/src/FBXSerializer.cpp | 17 +++++++++-------- libraries/fbx/src/FBXSerializer.h | 18 +++++++++--------- libraries/fbx/src/GLTFSerializer.cpp | 4 ++-- libraries/fbx/src/GLTFSerializer.h | 7 ++++--- libraries/fbx/src/OBJSerializer.cpp | 6 +++--- libraries/fbx/src/OBJSerializer.h | 7 ++++--- libraries/hfm/src/hfm/HFMSerializer.h | 2 ++ .../src/model-networking/ModelCache.cpp | 9 ++++----- tests-manual/gpu/src/TestFbx.cpp | 2 +- tools/skeleton-dump/src/SkeletonDumpApp.cpp | 2 +- tools/vhacd-util/src/VHACDUtil.cpp | 4 ++-- 15 files changed, 48 insertions(+), 44 deletions(-) diff --git a/interface/src/ModelPackager.cpp b/interface/src/ModelPackager.cpp index a7fc0b9e20..5d7d4b1396 100644 --- a/interface/src/ModelPackager.cpp +++ b/interface/src/ModelPackager.cpp @@ -109,7 +109,7 @@ bool ModelPackager::loadModel() { qCDebug(interfaceapp) << "Reading FBX file : " << _fbxInfo.filePath(); QByteArray fbxContents = fbx.readAll(); - _hfmModel.reset(readFBX(fbxContents, QVariantHash(), _fbxInfo.filePath())); + _hfmModel.reset(FBXSerializer().read(fbxContents, QVariantHash(), _fbxInfo.filePath())); // make sure we have some basic mappings populateBasicMapping(_mapping, _fbxInfo.filePath(), *_hfmModel); diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index 06dfc0262a..5c9f083a3b 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -71,7 +71,7 @@ void AnimationReader::run() { // Parse the FBX directly from the QNetworkReply HFMModel::Pointer hfmModel; if (_url.path().toLower().endsWith(".fbx")) { - hfmModel.reset(readFBX(_data, QVariantHash(), _url.path())); + hfmModel.reset(FBXSerializer().read(_data, QVariantHash(), _url.path())); } else { QString errorStr("usupported format"); emit onError(299, errorStr); diff --git a/libraries/baking/src/FBXBaker.cpp b/libraries/baking/src/FBXBaker.cpp index 6349b06c49..afaca1dd62 100644 --- a/libraries/baking/src/FBXBaker.cpp +++ b/libraries/baking/src/FBXBaker.cpp @@ -187,10 +187,10 @@ void FBXBaker::importScene() { return; } - FBXSerializer serializer; + FBXSerializer fbxSerializer; qCDebug(model_baking) << "Parsing" << _modelURL; - _rootNode = serializer._rootNode = serializer.parseFBX(&fbxFile); + _rootNode = fbxSerializer._rootNode = fbxSerializer.parseFBX(&fbxFile); #ifdef HIFI_DUMP_FBX { @@ -206,8 +206,8 @@ void FBXBaker::importScene() { } #endif - _hfmModel = serializer.extractHFMModel({}, _modelURL.toString()); - _textureContentMap = serializer._textureContent; + _hfmModel = fbxSerializer.extractHFMModel({}, _modelURL.toString()); + _textureContentMap = fbxSerializer._textureContent; } void FBXBaker::rewriteAndBakeSceneModels() { diff --git a/libraries/baking/src/OBJBaker.cpp b/libraries/baking/src/OBJBaker.cpp index 389e708c12..83079bc052 100644 --- a/libraries/baking/src/OBJBaker.cpp +++ b/libraries/baking/src/OBJBaker.cpp @@ -145,7 +145,7 @@ void OBJBaker::bakeOBJ() { bool combineParts = true; // set true so that OBJSerializer reads material info from material library OBJSerializer serializer; - auto geometry = serializer.readOBJ(objData, QVariantHash(), combineParts, _modelURL); + auto geometry = serializer.read(objData, QVariantHash(), _modelURL, combineParts); // Write OBJ Data as FBX tree nodes createFBXNodeTree(_rootNode, *geometry); diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index fb7d95cf37..1cbb0ce386 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1796,19 +1796,20 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr return hfmModelPtr; } -HFMModel* readFBX(const QByteArray& data, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { +HFMModel* FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url, bool combineParts) { QBuffer buffer(const_cast(&data)); buffer.open(QIODevice::ReadOnly); - return readFBX(&buffer, mapping, url, loadLightmaps, lightmapLevel); + return read(&buffer, mapping, url, combineParts); } -HFMModel* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { - FBXSerializer serializer; - serializer._rootNode = FBXSerializer::parseFBX(device); - serializer._loadLightmaps = loadLightmaps; - serializer._lightmapLevel = lightmapLevel; +HFMModel* FBXSerializer::read(QIODevice* device, const QVariantHash& mapping, const QUrl& url, bool combineParts) { + _rootNode = parseFBX(device); qCDebug(modelformat) << "Reading FBX: " << url; - return serializer.extractHFMModel(mapping, url); + return extractHFMModel(mapping, url.toString()); +} + +HFMModel* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { + return FBXSerializer().extractHFMModel(mapping, url); } diff --git a/libraries/fbx/src/FBXSerializer.h b/libraries/fbx/src/FBXSerializer.h index 9809b257e8..1173af2693 100644 --- a/libraries/fbx/src/FBXSerializer.h +++ b/libraries/fbx/src/FBXSerializer.h @@ -27,7 +27,7 @@ #include #include "FBX.h" -#include +#include #include #include @@ -35,10 +35,6 @@ class QIODevice; class FBXNode; -/// Reads HFMModel from the supplied model and mapping data. -/// \exception QString if an error occurs in parsing -HFMModel* readFBX(const QByteArray& data, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f); - /// Reads HFMModel from the supplied model and mapping data. /// \exception QString if an error occurs in parsing HFMModel* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f); @@ -102,9 +98,13 @@ public: class ExtractedMesh; -class FBXSerializer { +class FBXSerializer : public HFMSerializer { public: HFMModel* _hfmModel; + /// Reads HFMModel from the supplied model and mapping data. + /// \exception QString if an error occurs in parsing + HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl(), bool combineParts = false) override; + HFMModel* read(QIODevice* device, const QVariantHash& mapping, const QUrl& url = QUrl(), bool combineParts = false); FBXNode _rootNode; static FBXNode parseFBX(QIODevice* device); @@ -147,9 +147,9 @@ public: void consolidateHFMMaterials(const QVariantHash& mapping); - bool _loadLightmaps = true; - float _lightmapOffset = 0.0f; - float _lightmapLevel; + bool _loadLightmaps { true }; + float _lightmapOffset { 0.0f }; + float _lightmapLevel { 1.0f }; QMultiMap _connectionParentMap; QMultiMap _connectionChildMap; diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index 5e60cfffe7..8f529868db 100644 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -910,8 +910,8 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const QUrl& url) { return true; } -HFMModel* GLTFSerializer::readGLTF(QByteArray& data, const QVariantHash& mapping, - const QUrl& url, bool loadLightmaps, float lightmapLevel) { +HFMModel* GLTFSerializer::read(const QByteArray& data, const QVariantHash& mapping, + const QUrl& url, bool combineParts) { _url = url; diff --git a/libraries/fbx/src/GLTFSerializer.h b/libraries/fbx/src/GLTFSerializer.h index 8ce64a83f2..754d097614 100644 --- a/libraries/fbx/src/GLTFSerializer.h +++ b/libraries/fbx/src/GLTFSerializer.h @@ -15,6 +15,7 @@ #include #include #include +#include #include "FBXSerializer.h" @@ -702,12 +703,12 @@ struct GLTFFile { } }; -class GLTFSerializer : public QObject { +class GLTFSerializer : public QObject, public HFMSerializer { Q_OBJECT public: GLTFSerializer(); - HFMModel* readGLTF(QByteArray& data, const QVariantHash& mapping, - const QUrl& url, bool loadLightmaps = true, float lightmapLevel = 1.0f); + HFMModel* read(const QByteArray& data, const QVariantHash& mapping, + const QUrl& url = QUrl(), bool combineParts = false) override; private: GLTFFile _file; QUrl _url; diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index a1a6893280..1684b2812c 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -652,12 +652,12 @@ done: } -HFMModel::Pointer OBJSerializer::readOBJ(QByteArray& data, const QVariantHash& mapping, bool combineParts, const QUrl& url) { +HFMModel* OBJSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url, bool combineParts) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); - QBuffer buffer { &data }; + QBuffer buffer { const_cast(&data) }; buffer.open(QIODevice::ReadOnly); - auto hfmModelPtr { std::make_shared() }; + auto hfmModelPtr = new HFMModel(); HFMModel& hfmModel { *hfmModelPtr }; OBJTokenizer tokenizer { &buffer }; float scaleGuess = 1.0f; diff --git a/libraries/fbx/src/OBJSerializer.h b/libraries/fbx/src/OBJSerializer.h index d33d2edf07..ccb97c02ff 100644 --- a/libraries/fbx/src/OBJSerializer.h +++ b/libraries/fbx/src/OBJSerializer.h @@ -1,5 +1,6 @@ #include +#include #include "FBXSerializer.h" class OBJTokenizer { @@ -75,7 +76,7 @@ public: OBJMaterial() : shininess(0.0f), opacity(1.0f), diffuseColor(0.9f), specularColor(0.9f), emissiveColor(0.0f), illuminationModel(-1) {} }; -class OBJSerializer: public QObject { // QObject so we can make network requests. +class OBJSerializer: public QObject, public HFMSerializer { // QObject so we can make network requests. Q_OBJECT public: typedef QVector FaceGroup; @@ -86,8 +87,8 @@ public: QVector faceGroups; QString currentMaterialName; QHash materials; - - HFMModel::Pointer readOBJ(QByteArray& data, const QVariantHash& mapping, bool combineParts, const QUrl& url = QUrl()); + + HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl(), bool combineParts = false) override; private: QUrl _url; diff --git a/libraries/hfm/src/hfm/HFMSerializer.h b/libraries/hfm/src/hfm/HFMSerializer.h index bd63d8bf82..3cd48b76b2 100644 --- a/libraries/hfm/src/hfm/HFMSerializer.h +++ b/libraries/hfm/src/hfm/HFMSerializer.h @@ -26,4 +26,6 @@ class Serializer { }; +using HFMSerializer = hfm::Serializer; + #endif // hifi_HFMSerializer_h diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 5a7e383630..507ee23f7c 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -196,23 +196,22 @@ void GeometryReader::run() { HFMModel::Pointer hfmModel; if (_url.path().toLower().endsWith(".fbx")) { - hfmModel.reset(readFBX(_data, _mapping, _url.path())); + hfmModel.reset(FBXSerializer().read(_data, _mapping, _url.path())); if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { throw QString("empty geometry, possibly due to an unsupported FBX version"); } } else if (_url.path().toLower().endsWith(".obj")) { - hfmModel = OBJSerializer().readOBJ(_data, _mapping, _combineParts, _url); + hfmModel.reset(OBJSerializer().read(_data, _mapping, _url, _combineParts)); } else if (_url.path().toLower().endsWith(".obj.gz")) { QByteArray uncompressedData; if (gunzip(_data, uncompressedData)){ - hfmModel = OBJSerializer().readOBJ(uncompressedData, _mapping, _combineParts, _url); + hfmModel.reset(OBJSerializer().read(uncompressedData, _mapping, _url, _combineParts)); } else { throw QString("failed to decompress .obj.gz"); } } else if (_url.path().toLower().endsWith(".gltf")) { - std::shared_ptr glreader = std::make_shared(); - hfmModel.reset(glreader->readGLTF(_data, _mapping, _url)); + hfmModel.reset(GLTFSerializer().read(_data, _mapping, _url)); if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { throw QString("empty geometry, possibly due to an unsupported GLTF version"); } diff --git a/tests-manual/gpu/src/TestFbx.cpp b/tests-manual/gpu/src/TestFbx.cpp index 290913e406..379481baa8 100644 --- a/tests-manual/gpu/src/TestFbx.cpp +++ b/tests-manual/gpu/src/TestFbx.cpp @@ -100,7 +100,7 @@ bool TestFbx::isReady() const { void TestFbx::parseFbx(const QByteArray& fbxData) { QVariantHash mapping; - HFMModel* hfmModel = readFBX(fbxData, mapping); + HFMModel* hfmModel = FBXSerializer().read(fbxData, mapping); size_t totalVertexCount = 0; size_t totalIndexCount = 0; size_t totalPartCount = 0; diff --git a/tools/skeleton-dump/src/SkeletonDumpApp.cpp b/tools/skeleton-dump/src/SkeletonDumpApp.cpp index bad38f24ba..cbee73528f 100644 --- a/tools/skeleton-dump/src/SkeletonDumpApp.cpp +++ b/tools/skeleton-dump/src/SkeletonDumpApp.cpp @@ -54,7 +54,7 @@ SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc return; } QByteArray blob = file.readAll(); - std::unique_ptr geometry(readFBX(blob, QVariantHash())); + std::unique_ptr geometry(FBXSerializer().read(blob, QVariantHash())); std::unique_ptr skeleton(new AnimSkeleton(*geometry)); skeleton->dump(verbose); } diff --git a/tools/vhacd-util/src/VHACDUtil.cpp b/tools/vhacd-util/src/VHACDUtil.cpp index b1dcdebe60..4036dbefa7 100644 --- a/tools/vhacd-util/src/VHACDUtil.cpp +++ b/tools/vhacd-util/src/VHACDUtil.cpp @@ -44,9 +44,9 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, HFMModel& result) { HFMModel::Pointer hfmModel; if (filename.toLower().endsWith(".obj")) { bool combineParts = false; - hfmModel = OBJSerializer().readOBJ(fbxContents, QVariantHash(), combineParts); + hfmModel.reset(OBJSerializer().read(fbxContents, QVariantHash(), filename, combineParts)); } else if (filename.toLower().endsWith(".fbx")) { - hfmModel.reset(readFBX(fbxContents, QVariantHash(), filename)); + hfmModel.reset(FBXSerializer().read(fbxContents, QVariantHash(), filename)); } else { qWarning() << "file has unknown extension" << filename; return false; From 0cbe0bd266875ccc811b1f4a6687f2a9450fdfb7 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Thu, 8 Nov 2018 13:36:57 -0800 Subject: [PATCH 019/109] Add missing copyright comment and header guard to OBJSerializer.h --- libraries/fbx/src/OBJSerializer.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libraries/fbx/src/OBJSerializer.h b/libraries/fbx/src/OBJSerializer.h index ccb97c02ff..824110c345 100644 --- a/libraries/fbx/src/OBJSerializer.h +++ b/libraries/fbx/src/OBJSerializer.h @@ -1,3 +1,16 @@ +// +// OBJSerializer.h +// libraries/fbx/src/ +// +// Created by Seth Alves on 3/6/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_OBJSerializer_h +#define hifi_OBJSerializer_h #include #include @@ -106,3 +119,5 @@ private: // What are these utilities doing here? One is used by fbx loading code in VHACD Utils, and the other a general debugging utility. void setMeshPartDefaults(HFMMeshPart& meshPart, QString materialID); void hfmDebugDump(const HFMModel& hfmModel); + +#endif // hifi_OBJSerializer_h From baa8cdb054a2ff871df59bcb871ad408a9982d58 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Thu, 8 Nov 2018 16:20:38 -0800 Subject: [PATCH 020/109] Remove combineParts from the Serializer interface --- libraries/baking/src/OBJBaker.cpp | 2 +- libraries/fbx/src/FBXSerializer.cpp | 6 +++--- libraries/fbx/src/FBXSerializer.h | 4 ++-- libraries/fbx/src/GLTFSerializer.cpp | 7 +++---- libraries/fbx/src/GLTFSerializer.h | 3 +-- libraries/fbx/src/OBJSerializer.cpp | 11 ++++++----- libraries/fbx/src/OBJSerializer.h | 2 +- libraries/hfm/src/hfm/HFMSerializer.h | 2 +- .../src/model-networking/ModelCache.cpp | 11 +++++++---- tools/vhacd-util/src/VHACDUtil.cpp | 3 +-- 10 files changed, 26 insertions(+), 25 deletions(-) diff --git a/libraries/baking/src/OBJBaker.cpp b/libraries/baking/src/OBJBaker.cpp index 83079bc052..ae29a82c28 100644 --- a/libraries/baking/src/OBJBaker.cpp +++ b/libraries/baking/src/OBJBaker.cpp @@ -145,7 +145,7 @@ void OBJBaker::bakeOBJ() { bool combineParts = true; // set true so that OBJSerializer reads material info from material library OBJSerializer serializer; - auto geometry = serializer.read(objData, QVariantHash(), _modelURL, combineParts); + auto geometry = serializer.read(objData, QVariantHash(), _modelURL); // Write OBJ Data as FBX tree nodes createFBXNodeTree(_rootNode, *geometry); diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 1cbb0ce386..ebd105706b 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1796,13 +1796,13 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr return hfmModelPtr; } -HFMModel* FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url, bool combineParts) { +HFMModel* FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { QBuffer buffer(const_cast(&data)); buffer.open(QIODevice::ReadOnly); - return read(&buffer, mapping, url, combineParts); + return read(&buffer, mapping, url); } -HFMModel* FBXSerializer::read(QIODevice* device, const QVariantHash& mapping, const QUrl& url, bool combineParts) { +HFMModel* FBXSerializer::read(QIODevice* device, const QVariantHash& mapping, const QUrl& url) { _rootNode = parseFBX(device); qCDebug(modelformat) << "Reading FBX: " << url; diff --git a/libraries/fbx/src/FBXSerializer.h b/libraries/fbx/src/FBXSerializer.h index 1173af2693..a4832e61e9 100644 --- a/libraries/fbx/src/FBXSerializer.h +++ b/libraries/fbx/src/FBXSerializer.h @@ -103,8 +103,8 @@ public: HFMModel* _hfmModel; /// Reads HFMModel from the supplied model and mapping data. /// \exception QString if an error occurs in parsing - HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl(), bool combineParts = false) override; - HFMModel* read(QIODevice* device, const QVariantHash& mapping, const QUrl& url = QUrl(), bool combineParts = false); + HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; + HFMModel* read(QIODevice* device, const QVariantHash& mapping, const QUrl& url = QUrl()); FBXNode _rootNode; static FBXNode parseFBX(QIODevice* device); diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index 8f529868db..17b1189eae 100644 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -910,13 +910,12 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const QUrl& url) { return true; } -HFMModel* GLTFSerializer::read(const QByteArray& data, const QVariantHash& mapping, - const QUrl& url, bool combineParts) { +HFMModel* GLTFSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { _url = url; // Normalize url for local files - QUrl normalizeUrl = DependencyManager::get()->normalizeURL(url); + QUrl normalizeUrl = DependencyManager::get()->normalizeURL(_url); if (normalizeUrl.scheme().isEmpty() || (normalizeUrl.scheme() == "file")) { QString localFileName = PathUtils::expandToLocalDataAbsolutePath(normalizeUrl).toLocalFile(); _url = QUrl(QFileInfo(localFileName).absoluteFilePath()); @@ -927,7 +926,7 @@ HFMModel* GLTFSerializer::read(const QByteArray& data, const QVariantHash& mappi HFMModel* hfmModelPtr = new HFMModel(); HFMModel& hfmModel = *hfmModelPtr; - buildGeometry(hfmModel, url); + buildGeometry(hfmModel, _url); //hfmDebugDump(data); return hfmModelPtr; diff --git a/libraries/fbx/src/GLTFSerializer.h b/libraries/fbx/src/GLTFSerializer.h index 754d097614..86e31d23dd 100644 --- a/libraries/fbx/src/GLTFSerializer.h +++ b/libraries/fbx/src/GLTFSerializer.h @@ -707,8 +707,7 @@ class GLTFSerializer : public QObject, public HFMSerializer { Q_OBJECT public: GLTFSerializer(); - HFMModel* read(const QByteArray& data, const QVariantHash& mapping, - const QUrl& url = QUrl(), bool combineParts = false) override; + HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; private: GLTFFile _file; QUrl _url; diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index 1684b2812c..fb9b882940 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -652,7 +652,7 @@ done: } -HFMModel* OBJSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url, bool combineParts) { +HFMModel* OBJSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); QBuffer buffer { const_cast(&data) }; buffer.open(QIODevice::ReadOnly); @@ -665,6 +665,7 @@ HFMModel* OBJSerializer::read(const QByteArray& data, const QVariantHash& mappin bool needsMaterialLibrary = false; _url = url; + bool combineParts = mapping.value("combineParts").toBool(); hfmModel.meshExtents.reset(); hfmModel.meshes.append(HFMMesh()); @@ -822,7 +823,7 @@ HFMModel* OBJSerializer::read(const QByteArray& data, const QVariantHash& mappin } // Build the single mesh. - FBXSerializer::buildModelMesh(mesh, url.toString()); + FBXSerializer::buildModelMesh(mesh, _url.toString()); // hfmDebugDump(hfmModel); } catch(const std::exception& e) { @@ -838,14 +839,14 @@ HFMModel* OBJSerializer::read(const QByteArray& data, const QVariantHash& mappin } // Some .obj files use the convention that a group with uv coordinates that doesn't define a material, should use // a texture with the same basename as the .obj file. - if (preDefinedMaterial.userSpecifiesUV && !url.isEmpty()) { - QString filename = url.fileName(); + if (preDefinedMaterial.userSpecifiesUV && !_url.isEmpty()) { + QString filename = _url.fileName(); int extIndex = filename.lastIndexOf('.'); // by construction, this does not fail QString basename = filename.remove(extIndex + 1, sizeof("obj")); preDefinedMaterial.diffuseColor = glm::vec3(1.0f); QVector extensions = { "jpg", "jpeg", "png", "tga" }; QByteArray base = basename.toUtf8(), textName = ""; - qCDebug(modelformat) << "OBJSerializer looking for default texture of" << url; + qCDebug(modelformat) << "OBJSerializer looking for default texture of" << _url; for (int i = 0; i < extensions.count(); i++) { QByteArray candidateString = base + extensions[i]; if (isValidTexture(candidateString)) { diff --git a/libraries/fbx/src/OBJSerializer.h b/libraries/fbx/src/OBJSerializer.h index 824110c345..82bd2705df 100644 --- a/libraries/fbx/src/OBJSerializer.h +++ b/libraries/fbx/src/OBJSerializer.h @@ -101,7 +101,7 @@ public: QString currentMaterialName; QHash materials; - HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl(), bool combineParts = false) override; + HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; private: QUrl _url; diff --git a/libraries/hfm/src/hfm/HFMSerializer.h b/libraries/hfm/src/hfm/HFMSerializer.h index 3cd48b76b2..6bac9980d2 100644 --- a/libraries/hfm/src/hfm/HFMSerializer.h +++ b/libraries/hfm/src/hfm/HFMSerializer.h @@ -21,7 +21,7 @@ namespace hfm { class Serializer { - virtual Model* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl(), bool combineParts = false) = 0; + virtual Model* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) = 0; }; }; diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 507ee23f7c..0ea3ff80ad 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -195,23 +195,26 @@ void GeometryReader::run() { HFMModel::Pointer hfmModel; + QVariantHash serializerMapping = _mapping; + serializerMapping["combineParts"] = _combineParts; + if (_url.path().toLower().endsWith(".fbx")) { - hfmModel.reset(FBXSerializer().read(_data, _mapping, _url.path())); + hfmModel.reset(FBXSerializer().read(_data, serializerMapping, _url)); if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { throw QString("empty geometry, possibly due to an unsupported FBX version"); } } else if (_url.path().toLower().endsWith(".obj")) { - hfmModel.reset(OBJSerializer().read(_data, _mapping, _url, _combineParts)); + hfmModel.reset(OBJSerializer().read(_data, serializerMapping, _url)); } else if (_url.path().toLower().endsWith(".obj.gz")) { QByteArray uncompressedData; if (gunzip(_data, uncompressedData)){ - hfmModel.reset(OBJSerializer().read(uncompressedData, _mapping, _url, _combineParts)); + hfmModel.reset(OBJSerializer().read(uncompressedData, serializerMapping, _url)); } else { throw QString("failed to decompress .obj.gz"); } } else if (_url.path().toLower().endsWith(".gltf")) { - hfmModel.reset(GLTFSerializer().read(_data, _mapping, _url)); + hfmModel.reset(GLTFSerializer().read(_data, serializerMapping, _url)); if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { throw QString("empty geometry, possibly due to an unsupported GLTF version"); } diff --git a/tools/vhacd-util/src/VHACDUtil.cpp b/tools/vhacd-util/src/VHACDUtil.cpp index 4036dbefa7..c72b2dff75 100644 --- a/tools/vhacd-util/src/VHACDUtil.cpp +++ b/tools/vhacd-util/src/VHACDUtil.cpp @@ -43,8 +43,7 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, HFMModel& result) { QByteArray fbxContents = fbx.readAll(); HFMModel::Pointer hfmModel; if (filename.toLower().endsWith(".obj")) { - bool combineParts = false; - hfmModel.reset(OBJSerializer().read(fbxContents, QVariantHash(), filename, combineParts)); + hfmModel.reset(OBJSerializer().read(fbxContents, QVariantHash(), filename)); } else if (filename.toLower().endsWith(".fbx")) { hfmModel.reset(FBXSerializer().read(fbxContents, QVariantHash(), filename)); } else { From 5a9af5b2c3982fb542949f587743e1e54fc3563f Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Thu, 8 Nov 2018 17:25:14 -0800 Subject: [PATCH 021/109] Correct the folder location in the FBXSerializer header/source top comment --- libraries/fbx/src/FBXSerializer.cpp | 2 +- libraries/fbx/src/FBXSerializer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index ebd105706b..b0410d4e52 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1,6 +1,6 @@ // // FBXSerializer.cpp -// interface/src/renderer +// libraries/fbx/src // // Created by Andrzej Kapolka on 9/18/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/fbx/src/FBXSerializer.h b/libraries/fbx/src/FBXSerializer.h index a4832e61e9..b079baf1bd 100644 --- a/libraries/fbx/src/FBXSerializer.h +++ b/libraries/fbx/src/FBXSerializer.h @@ -1,6 +1,6 @@ // // FBXSerializer.h -// interface/src/renderer +// libraries/fbx/src // // Created by Andrzej Kapolka on 9/18/13. // Copyright 2013 High Fidelity, Inc. From f971294d6db0f7f12bf3e67ae0a6af397e7733e9 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 9 Nov 2018 09:21:02 -0800 Subject: [PATCH 022/109] Make HFMSerializer return a smart pointer to an HFMModel --- interface/src/ModelPackager.cpp | 2 +- interface/src/ModelPackager.h | 2 +- libraries/animation/src/AnimationCache.cpp | 2 +- libraries/fbx/src/FBXSerializer.cpp | 4 ++-- libraries/fbx/src/FBXSerializer.h | 2 +- libraries/fbx/src/GLTFSerializer.cpp | 4 ++-- libraries/fbx/src/GLTFSerializer.h | 2 +- libraries/fbx/src/OBJSerializer.cpp | 4 ++-- libraries/fbx/src/OBJSerializer.h | 2 +- libraries/hfm/src/hfm/HFMSerializer.h | 2 +- .../model-networking/src/model-networking/ModelCache.cpp | 8 ++++---- tests-manual/gpu/src/TestFbx.cpp | 3 +-- tools/skeleton-dump/src/SkeletonDumpApp.cpp | 2 +- tools/vhacd-util/src/VHACDUtil.cpp | 4 ++-- 14 files changed, 21 insertions(+), 22 deletions(-) diff --git a/interface/src/ModelPackager.cpp b/interface/src/ModelPackager.cpp index 5d7d4b1396..5b3b53a40c 100644 --- a/interface/src/ModelPackager.cpp +++ b/interface/src/ModelPackager.cpp @@ -109,7 +109,7 @@ bool ModelPackager::loadModel() { qCDebug(interfaceapp) << "Reading FBX file : " << _fbxInfo.filePath(); QByteArray fbxContents = fbx.readAll(); - _hfmModel.reset(FBXSerializer().read(fbxContents, QVariantHash(), _fbxInfo.filePath())); + _hfmModel = FBXSerializer().read(fbxContents, QVariantHash(), _fbxInfo.filePath()); // make sure we have some basic mappings populateBasicMapping(_mapping, _fbxInfo.filePath(), *_hfmModel); diff --git a/interface/src/ModelPackager.h b/interface/src/ModelPackager.h index 849f6ac3da..a2c23bfa74 100644 --- a/interface/src/ModelPackager.h +++ b/interface/src/ModelPackager.h @@ -46,7 +46,7 @@ private: QString _scriptDir; QVariantHash _mapping; - std::unique_ptr _hfmModel; + std::shared_ptr _hfmModel; QStringList _textures; QStringList _scripts; }; diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index 5c9f083a3b..c9911d938f 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -71,7 +71,7 @@ void AnimationReader::run() { // Parse the FBX directly from the QNetworkReply HFMModel::Pointer hfmModel; if (_url.path().toLower().endsWith(".fbx")) { - hfmModel.reset(FBXSerializer().read(_data, QVariantHash(), _url.path())); + hfmModel = FBXSerializer().read(_data, QVariantHash(), _url.path()); } else { QString errorStr("usupported format"); emit onError(299, errorStr); diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index b0410d4e52..c5c0b94f9b 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1796,10 +1796,10 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr return hfmModelPtr; } -HFMModel* FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { +HFMModel::Pointer FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { QBuffer buffer(const_cast(&data)); buffer.open(QIODevice::ReadOnly); - return read(&buffer, mapping, url); + return HFMModel::Pointer(read(&buffer, mapping, url)); } HFMModel* FBXSerializer::read(QIODevice* device, const QVariantHash& mapping, const QUrl& url) { diff --git a/libraries/fbx/src/FBXSerializer.h b/libraries/fbx/src/FBXSerializer.h index b079baf1bd..89f815ec1e 100644 --- a/libraries/fbx/src/FBXSerializer.h +++ b/libraries/fbx/src/FBXSerializer.h @@ -103,7 +103,7 @@ public: HFMModel* _hfmModel; /// Reads HFMModel from the supplied model and mapping data. /// \exception QString if an error occurs in parsing - HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; + HFMModel::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; HFMModel* read(QIODevice* device, const QVariantHash& mapping, const QUrl& url = QUrl()); FBXNode _rootNode; diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index 17b1189eae..b4082f222a 100644 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -910,7 +910,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const QUrl& url) { return true; } -HFMModel* GLTFSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { +HFMModel::Pointer GLTFSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { _url = url; @@ -923,7 +923,7 @@ HFMModel* GLTFSerializer::read(const QByteArray& data, const QVariantHash& mappi parseGLTF(data); //_file.dump(); - HFMModel* hfmModelPtr = new HFMModel(); + auto hfmModelPtr = std::make_shared(); HFMModel& hfmModel = *hfmModelPtr; buildGeometry(hfmModel, _url); diff --git a/libraries/fbx/src/GLTFSerializer.h b/libraries/fbx/src/GLTFSerializer.h index 86e31d23dd..f5fc360326 100644 --- a/libraries/fbx/src/GLTFSerializer.h +++ b/libraries/fbx/src/GLTFSerializer.h @@ -707,7 +707,7 @@ class GLTFSerializer : public QObject, public HFMSerializer { Q_OBJECT public: GLTFSerializer(); - HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; + HFMModel::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; private: GLTFFile _file; QUrl _url; diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index fb9b882940..e8b517da6b 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -652,12 +652,12 @@ done: } -HFMModel* OBJSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { +HFMModel::Pointer OBJSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); QBuffer buffer { const_cast(&data) }; buffer.open(QIODevice::ReadOnly); - auto hfmModelPtr = new HFMModel(); + auto hfmModelPtr = std::make_shared(); HFMModel& hfmModel { *hfmModelPtr }; OBJTokenizer tokenizer { &buffer }; float scaleGuess = 1.0f; diff --git a/libraries/fbx/src/OBJSerializer.h b/libraries/fbx/src/OBJSerializer.h index 82bd2705df..a6fe3817ca 100644 --- a/libraries/fbx/src/OBJSerializer.h +++ b/libraries/fbx/src/OBJSerializer.h @@ -101,7 +101,7 @@ public: QString currentMaterialName; QHash materials; - HFMModel* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; + HFMModel::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; private: QUrl _url; diff --git a/libraries/hfm/src/hfm/HFMSerializer.h b/libraries/hfm/src/hfm/HFMSerializer.h index 6bac9980d2..424b340a6c 100644 --- a/libraries/hfm/src/hfm/HFMSerializer.h +++ b/libraries/hfm/src/hfm/HFMSerializer.h @@ -21,7 +21,7 @@ namespace hfm { class Serializer { - virtual Model* read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) = 0; + virtual Model::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) = 0; }; }; diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 0ea3ff80ad..abca3488f6 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -199,22 +199,22 @@ void GeometryReader::run() { serializerMapping["combineParts"] = _combineParts; if (_url.path().toLower().endsWith(".fbx")) { - hfmModel.reset(FBXSerializer().read(_data, serializerMapping, _url)); + hfmModel = FBXSerializer().read(_data, serializerMapping, _url); if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { throw QString("empty geometry, possibly due to an unsupported FBX version"); } } else if (_url.path().toLower().endsWith(".obj")) { - hfmModel.reset(OBJSerializer().read(_data, serializerMapping, _url)); + hfmModel = OBJSerializer().read(_data, serializerMapping, _url); } else if (_url.path().toLower().endsWith(".obj.gz")) { QByteArray uncompressedData; if (gunzip(_data, uncompressedData)){ - hfmModel.reset(OBJSerializer().read(uncompressedData, serializerMapping, _url)); + hfmModel = OBJSerializer().read(uncompressedData, serializerMapping, _url); } else { throw QString("failed to decompress .obj.gz"); } } else if (_url.path().toLower().endsWith(".gltf")) { - hfmModel.reset(GLTFSerializer().read(_data, serializerMapping, _url)); + hfmModel = GLTFSerializer().read(_data, serializerMapping, _url); if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { throw QString("empty geometry, possibly due to an unsupported GLTF version"); } diff --git a/tests-manual/gpu/src/TestFbx.cpp b/tests-manual/gpu/src/TestFbx.cpp index 379481baa8..d3eab9e8e3 100644 --- a/tests-manual/gpu/src/TestFbx.cpp +++ b/tests-manual/gpu/src/TestFbx.cpp @@ -100,7 +100,7 @@ bool TestFbx::isReady() const { void TestFbx::parseFbx(const QByteArray& fbxData) { QVariantHash mapping; - HFMModel* hfmModel = FBXSerializer().read(fbxData, mapping); + HFMModel::Pointer hfmModel = FBXSerializer().read(fbxData, mapping); size_t totalVertexCount = 0; size_t totalIndexCount = 0; size_t totalPartCount = 0; @@ -163,7 +163,6 @@ void TestFbx::parseFbx(const QByteArray& fbxData) { _vertexBuffer->append(vertices); _indexBuffer->append(indices); _indirectBuffer->append(parts); - delete hfmModel; } void TestFbx::renderTest(size_t testId, RenderArgs* args) { diff --git a/tools/skeleton-dump/src/SkeletonDumpApp.cpp b/tools/skeleton-dump/src/SkeletonDumpApp.cpp index cbee73528f..42a1c78090 100644 --- a/tools/skeleton-dump/src/SkeletonDumpApp.cpp +++ b/tools/skeleton-dump/src/SkeletonDumpApp.cpp @@ -54,7 +54,7 @@ SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc return; } QByteArray blob = file.readAll(); - std::unique_ptr geometry(FBXSerializer().read(blob, QVariantHash())); + HFMModel::Pointer geometry = FBXSerializer().read(blob, QVariantHash()); std::unique_ptr skeleton(new AnimSkeleton(*geometry)); skeleton->dump(verbose); } diff --git a/tools/vhacd-util/src/VHACDUtil.cpp b/tools/vhacd-util/src/VHACDUtil.cpp index c72b2dff75..89794bf40a 100644 --- a/tools/vhacd-util/src/VHACDUtil.cpp +++ b/tools/vhacd-util/src/VHACDUtil.cpp @@ -43,9 +43,9 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, HFMModel& result) { QByteArray fbxContents = fbx.readAll(); HFMModel::Pointer hfmModel; if (filename.toLower().endsWith(".obj")) { - hfmModel.reset(OBJSerializer().read(fbxContents, QVariantHash(), filename)); + hfmModel = OBJSerializer().read(fbxContents, QVariantHash(), filename); } else if (filename.toLower().endsWith(".fbx")) { - hfmModel.reset(FBXSerializer().read(fbxContents, QVariantHash(), filename)); + hfmModel = FBXSerializer().read(fbxContents, QVariantHash(), filename); } else { qWarning() << "file has unknown extension" << filename; return false; From 8e0fb0f9c440c378b1456d8b60bc850c2eb90114 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 9 Nov 2018 10:52:45 -0800 Subject: [PATCH 023/109] Remove unused alternate read functions in FBXSerializer --- libraries/fbx/src/FBXSerializer.cpp | 11 ++--------- libraries/fbx/src/FBXSerializer.h | 5 ----- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index c5c0b94f9b..9f5867feda 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1799,17 +1799,10 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr HFMModel::Pointer FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { QBuffer buffer(const_cast(&data)); buffer.open(QIODevice::ReadOnly); - return HFMModel::Pointer(read(&buffer, mapping, url)); -} -HFMModel* FBXSerializer::read(QIODevice* device, const QVariantHash& mapping, const QUrl& url) { - _rootNode = parseFBX(device); + _rootNode = parseFBX(&buffer); qCDebug(modelformat) << "Reading FBX: " << url; - return extractHFMModel(mapping, url.toString()); -} - -HFMModel* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { - return FBXSerializer().extractHFMModel(mapping, url); + return HFMModel::Pointer(extractHFMModel(mapping, url.toString())); } diff --git a/libraries/fbx/src/FBXSerializer.h b/libraries/fbx/src/FBXSerializer.h index 89f815ec1e..c69f75cc5c 100644 --- a/libraries/fbx/src/FBXSerializer.h +++ b/libraries/fbx/src/FBXSerializer.h @@ -35,10 +35,6 @@ class QIODevice; class FBXNode; -/// Reads HFMModel from the supplied model and mapping data. -/// \exception QString if an error occurs in parsing -HFMModel* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f); - class TextureParam { public: glm::vec2 UVTranslation; @@ -104,7 +100,6 @@ public: /// Reads HFMModel from the supplied model and mapping data. /// \exception QString if an error occurs in parsing HFMModel::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; - HFMModel* read(QIODevice* device, const QVariantHash& mapping, const QUrl& url = QUrl()); FBXNode _rootNode; static FBXNode parseFBX(QIODevice* device); From 5b6e2aae5a85d9d4ff445ba38e088616199d6606 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 9 Nov 2018 11:07:45 -0800 Subject: [PATCH 024/109] Remove/move some unused serializer imports --- interface/src/ModelPackager.cpp | 1 + interface/src/ModelPropertiesDialog.h | 2 +- libraries/baking/src/ModelBaker.cpp | 1 - tools/vhacd-util/src/VHACDUtil.cpp | 2 ++ tools/vhacd-util/src/VHACDUtil.h | 4 ++-- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/ModelPackager.cpp b/interface/src/ModelPackager.cpp index 5b3b53a40c..7e63085d1d 100644 --- a/interface/src/ModelPackager.cpp +++ b/interface/src/ModelPackager.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "ModelSelector.h" diff --git a/interface/src/ModelPropertiesDialog.h b/interface/src/ModelPropertiesDialog.h index 7068d5cb76..7c0f9d86c1 100644 --- a/interface/src/ModelPropertiesDialog.h +++ b/interface/src/ModelPropertiesDialog.h @@ -14,7 +14,7 @@ #include -#include +#include #include #include "ui/ModelsBrowser.h" diff --git a/libraries/baking/src/ModelBaker.cpp b/libraries/baking/src/ModelBaker.cpp index 646f1bc010..34f302b501 100644 --- a/libraries/baking/src/ModelBaker.cpp +++ b/libraries/baking/src/ModelBaker.cpp @@ -13,7 +13,6 @@ #include -#include #include #ifdef _WIN32 diff --git a/tools/vhacd-util/src/VHACDUtil.cpp b/tools/vhacd-util/src/VHACDUtil.cpp index 89794bf40a..9401da4314 100644 --- a/tools/vhacd-util/src/VHACDUtil.cpp +++ b/tools/vhacd-util/src/VHACDUtil.cpp @@ -15,6 +15,8 @@ #include #include +#include +#include // FBXSerializer jumbles the order of the meshes by reading them back out of a hashtable. This will put diff --git a/tools/vhacd-util/src/VHACDUtil.h b/tools/vhacd-util/src/VHACDUtil.h index 7a6f2f1db6..0fb70e8af7 100644 --- a/tools/vhacd-util/src/VHACDUtil.h +++ b/tools/vhacd-util/src/VHACDUtil.h @@ -18,10 +18,10 @@ #include #include //c++11 feature #include -#include -#include #include +#include + namespace vhacd { class VHACDUtil { public: From 93c7578f54519cf168b4a7f53d8b3851b098f644 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 12 Nov 2018 14:33:16 -0800 Subject: [PATCH 025/109] Convert hfm::Serializer to use hifi-namespaced types --- libraries/hfm/src/hfm/HFMSerializer.h | 6 ++---- libraries/shared/src/shared/HifiTypes.h | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 libraries/shared/src/shared/HifiTypes.h diff --git a/libraries/hfm/src/hfm/HFMSerializer.h b/libraries/hfm/src/hfm/HFMSerializer.h index 424b340a6c..db18f21e06 100644 --- a/libraries/hfm/src/hfm/HFMSerializer.h +++ b/libraries/hfm/src/hfm/HFMSerializer.h @@ -12,16 +12,14 @@ #ifndef hifi_HFMSerializer_h #define hifi_HFMSerializer_h -#include -#include -#include +#include #include "HFM.h" namespace hfm { class Serializer { - virtual Model::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) = 0; + virtual Model::Pointer read(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url = hifi::URL()) = 0; }; }; diff --git a/libraries/shared/src/shared/HifiTypes.h b/libraries/shared/src/shared/HifiTypes.h new file mode 100644 index 0000000000..500170c88b --- /dev/null +++ b/libraries/shared/src/shared/HifiTypes.h @@ -0,0 +1,25 @@ +// +// HifiTypes.h +// libraries/shared/src/shared +// +// Created by Sabrina Shanman on 2018/11/12. +// Copyright 2018 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_HifiTypes_h +#define hifi_HifiTypes_h + +#include +#include +#include + +namespace hifi { + using ByteArray = QByteArray; + using VariantHash = QVariantHash; + using URL = QUrl; +}; + +#endif // hifi_HifiTypes_h From 2d309028133adaf845a168fe43c69d7a66928300 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Wed, 14 Nov 2018 09:11:56 -0800 Subject: [PATCH 026/109] Fix OBJBaker not setting combineParts --- libraries/baking/src/OBJBaker.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/baking/src/OBJBaker.cpp b/libraries/baking/src/OBJBaker.cpp index ae29a82c28..5a1239f88f 100644 --- a/libraries/baking/src/OBJBaker.cpp +++ b/libraries/baking/src/OBJBaker.cpp @@ -143,9 +143,10 @@ void OBJBaker::bakeOBJ() { QByteArray objData = objFile.readAll(); - bool combineParts = true; // set true so that OBJSerializer reads material info from material library OBJSerializer serializer; - auto geometry = serializer.read(objData, QVariantHash(), _modelURL); + QVariantHash mapping; + mapping["combineParts"] = true; // set true so that OBJSerializer reads material info from material library + auto geometry = serializer.read(objData, mapping, _modelURL); // Write OBJ Data as FBX tree nodes createFBXNodeTree(_rootNode, *geometry); From a5fe4709a932db636b67651aa2e58ede6fa30c01 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Wed, 14 Nov 2018 17:50:21 -0800 Subject: [PATCH 027/109] Update Fade.slh --- libraries/render-utils/src/Fade.slh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/Fade.slh b/libraries/render-utils/src/Fade.slh index 686289217c..cd1e06f52e 100644 --- a/libraries/render-utils/src/Fade.slh +++ b/libraries/render-utils/src/Fade.slh @@ -86,7 +86,7 @@ float evalFadeGradient(FadeObjectParams params, vec3 position) { float evalFadeAlpha(FadeObjectParams params, vec3 position) { float alpha = evalFadeGradient(params, position) - params.threshold; - alpha *= 1.0 - 2.0 * fadeParameters[params.category]._isInverted; + alpha *= 1.0 - 2.0 * float(fadeParameters[params.category]._isInverted); return alpha; } @@ -164,4 +164,4 @@ layout(location=RENDER_UTILS_ATTR_FADE3) out vec4 _fadeData3; _fadeData3 = inTexCoord4; <@endfunc@> -<@endif@> \ No newline at end of file +<@endif@> From 53b7cc13761c073e88dbf976ee201f402ed49117 Mon Sep 17 00:00:00 2001 From: vladest Date: Sat, 17 Nov 2018 15:06:25 +0100 Subject: [PATCH 028/109] Fix QML achoring warnings on Layouts --- interface/resources/qml/hifi/tablet/TabletHome.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletHome.qml b/interface/resources/qml/hifi/tablet/TabletHome.qml index f1f54e8419..1b0165ea94 100644 --- a/interface/resources/qml/hifi/tablet/TabletHome.qml +++ b/interface/resources/qml/hifi/tablet/TabletHome.qml @@ -61,7 +61,7 @@ Item { RalewaySemiBold { text: Account.loggedIn ? qsTr("Log out") : qsTr("Log in") horizontalAlignment: Text.AlignRight - anchors.right: parent.right + Layout.alignment: Qt.AlignRight font.pixelSize: 20 color: "#afafaf" } @@ -71,7 +71,7 @@ Item { height: Account.loggedIn ? parent.height/2 - parent.spacing/2 : 0 text: Account.loggedIn ? "[" + tabletRoot.usernameShort + "]" : "" horizontalAlignment: Text.AlignRight - anchors.right: parent.right + Layout.alignment: Qt.AlignRight font.pixelSize: 20 color: "#afafaf" } From 932d1dbcd735d4b5e6a69afd07903a8cc3ce5999 Mon Sep 17 00:00:00 2001 From: vladest Date: Sat, 17 Nov 2018 17:20:02 +0100 Subject: [PATCH 029/109] Fixed width binding loop warning --- interface/resources/qml/LoginDialog/LinkAccountBody.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 103761236d..3e4614c342 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -23,6 +23,8 @@ Item { width: root.pane.width property bool failAfterSignUp: false + onWidthChanged: d.resize(); + function login() { flavorText.visible = false mainTextContainer.visible = false @@ -127,7 +129,7 @@ Item { Column { id: form width: parent.width - onHeightChanged: d.resize(); onWidthChanged: d.resize(); + onHeightChanged: d.resize(); anchors { top: mainTextContainer.bottom From 837b321004e0901330c5f131753911f67b734495 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sat, 17 Nov 2018 10:35:05 -0800 Subject: [PATCH 030/109] merging with master --- interface/src/graphics/RenderEventHandler.cpp | 2 +- libraries/render-utils/src/AmbientOcclusionEffect.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/graphics/RenderEventHandler.cpp b/interface/src/graphics/RenderEventHandler.cpp index 3ac48b894d..42af3bb9c0 100644 --- a/interface/src/graphics/RenderEventHandler.cpp +++ b/interface/src/graphics/RenderEventHandler.cpp @@ -25,7 +25,7 @@ RenderEventHandler::RenderEventHandler(CheckCall checkCall, RenderCall renderCal // Transfer to a new thread moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) { hifi::qt::addBlockingForbiddenThread("Render", renderThread); - _renderContext->moveToThreadWithContext(renderThread); + //_renderContext->moveToThreadWithContext(renderThread); _lastTimeRendered.start(); }, std::bind(&RenderEventHandler::initialize, this), QThread::HighestPriority); } diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.h b/libraries/render-utils/src/AmbientOcclusionEffect.h index 864aef09e4..af6f6b21a3 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.h +++ b/libraries/render-utils/src/AmbientOcclusionEffect.h @@ -78,7 +78,6 @@ using AmbientOcclusionFramebufferPointer = std::shared_ptr Date: Mon, 19 Nov 2018 10:31:06 -0800 Subject: [PATCH 031/109] WIP - Readme to install on Mac. --- tools/nitpick/README.md | 162 +++++++++++++++++++++------------------- 1 file changed, 85 insertions(+), 77 deletions(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index e8129ae29e..aeafdc3384 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -12,70 +12,78 @@ Nitpick has 5 functions, separated into 4 tabs: 1. Evaluating the results of running tests 1. Web interface -## Installation -### Executable -1. On Windows: download the installer by browsing to [here](). -2. Double click on the installer and install to a convenient location +## Build +Nitpick is built as part of the High Fidelity build. +### Creating installers +#### Windows +1. Verify that 7Zip is installed. +1. cd to the `build\tools\nitpick\Release` directory +1. Delete any existing installers (named nitpick-installer-###.exe) +1. Select all, right-click and select 7-Zip->Add to archive... +1. Set Archive format to 7z +1. Check "Create SFX archive +1. Enter installer name (i.e. `nitpick-installer-v1.0.exe`) +1. Click "OK" +1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe: aws s3 cp nitpick-installer-v1.0.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.exe +#### Mac +1. (First time) install create-dmg: + `brew install create-dmg` +1. cd to the `build/tools/nitpick/Release` folder +1. Delete any existing installer: `rm nitpick.dmg` +1. Create installer: `create-dmg --volname nitpick-installer-v1.0 nitpick-installer-v1.0.dmg "source_folder/" +1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Mac/nitpick-installer-v1.0.dmg: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.0.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.dmg` +### Installation +#### Windows +1. Download the installer by browsing to [here](). +1. (First time) download and install vc_redist.x64.exe (available at https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe) +1. (First time) download and install Python 3 from https://hifi-qa.s3.amazonaws.com/nitpick/Windows/python-3.7.0-amd64.exe (also located at https://www.python.org/downloads/) + 1. After installation - create an environment variable called PYTHON_PATH and set it to the folder containing the Python executable. +1. (First time) download and install AWS CLI from https://hifi-qa.s3.amazonaws.com/nitpick/Windows/AWSCLI64PY3.msi (also available at https://aws.amazon.com/cli/ + 1. Open a new command prompt and run `aws configure` + 1. Enter the AWS account number + 1. Enter the secret key + 1. Leave region name and ouput format as default [None] + 1. Install the latest release of Boto3 via pip: `pip install boto3` + +1. Double click on the installer and install to a convenient location ![](./setup_7z.PNG) -3. To run nitpick, double click **nitpick.exe**. -### Python -The TestRail interface requires Python 3 to be installed. Nitpick has been tested with Python 3.7.0 but should work with newer versions. - -Python 3 can be downloaded from: -1. Windows installer -2. Linux (source) (**Gzipped source tarball**) -3. Mac (**macOS 64-bit/32-bit installer** or **macOS 64-bit/32-bit installer**) - -#### Windows -After installation - create an environment variable called PYTHON_PATH and set it to the folder containing the Python executable. - -#### Mac -After installation - run `open "/Applications/Python 3.6/Install Certificates.command"`. This is needed because the Mac Python supplied no longer links with the deprecated Apple-supplied system OpenSSL libraries but rather supplies a private copy of OpenSSL 1.0.2 which does not automatically access the system default root certificates. -Verify that `/usr/local/bin/python3` exists. - -### AWS interface -#### Windows -1. Download the AWS CLI from `https://aws.amazon.com/cli/` -1. Install (installer is named `AWSCLI64PY3.msi`) -1. Open a new command prompt and run `aws configure` -1. Enter the AWS account number -1. Enter the secret key -1. Leave region name and ouput format as default [None] -1. Install the latest release of Boto3 via pip: -pip install boto3 -#### Mac -1. Install pip with the script provided by the Python Packaging Authority: +1. To run nitpick, double click **nitpick.exe** +####Mac +1. DOWNLOAD INSTALLER +1. Install Python from https://www.python.org/downloads/release/python-370/ (**macOS 64-bit installer** or **macOS 64-bit/32-bit installer**) + 1. After installation - run `open "/Applications/Python 3.6/Install Certificates.command"`. This is needed because the Mac Python supplied no longer links with the deprecated Apple-supplied system OpenSSL libraries but rather supplies a private copy of OpenSSL 1.0.2 which does not automatically access the system default root certificates. + 1. Verify that `/usr/local/bin/python3` exists. +1. (First time - AWS interface) Install pip with the script provided by the Python Packaging Authority: $ curl -O https://bootstrap.pypa.io/get-pip.py $ python3 get-pip.py --user + 1. Use pip to install the AWS CLI. + $ pip3 install awscli --upgrade --user + This will install aws in your user. For user XXX, aws will be located in ~/Library/Python/3.7/bin + 1. Open a new command prompt and run `aws configure` + 1. Enter the AWS account number + 1. Enter the secret key + 1. Leave region name and ouput format as default [None] + 1. Install the latest release of Boto3 via pip: pip3 install boto3 -1. Use pip to install the AWS CLI. -$ pip3 install awscli --upgrade --user -This will install aws in your user. For user XXX, aws will be located in /Users/XXX/Library/Python/3.7/bin -1. Open a new command prompt and run `aws configure` -1. Enter the AWS account number -1. Enter the secret key -1. Leave region name and ouput format as default [None] -1. Install the latest release of Boto3 via pip: -pip3 install boto3 - -# Create +#Use +## Create ![](./Create.PNG) The Create tab provides functions to create tests from snapshots, MD files, a test outline and recursive scripts. -## Create Tests -### Usage +### Create Tests +#### Usage This function is used to create/update Expected Images after a successful run of a test, or multiple tests. The user will be asked for the snapshot folder and then the tests root folder. All snapshots located in the snapshot folder will be used to create or update the expected images in the relevant tests. -### Details +#### Details As an example - if the snapshots folder contains an image named `tests.content.entity.zone.zoneOrientation.00003.png`, then this file will be copied to `tests/contente/enity/zone/zoneOrientation/ExpectedImage0003.png`. -## Create Tests Outline -### Usage +### Create Tests Outline +#### Usage This function creates an MD file in the (user-selected) tests root folder. The file provides links to both the tests and the MD files. -## Create MD file -### Usage +### Create MD file +#### Usage This function creates a file named `test.md` from a `test.js` script. The user will be asked for the folder containing the test script: -### Details +#### Details The process to produce the MD file is a simplistic parse of the test script. - The string in the `nitpick.perform(...)` function call will be the title of the file @@ -86,25 +94,25 @@ The process to produce the MD file is a simplistic parse of the test script. - The step description is the string in the addStep/addStepStepSnapshot commands - Image links are provided where applicable to the local Expected Images files -## Create all MD files -### Usage +### Create all MD files +#### Usage This function creates all MD files recursively from the user-selected root folder. This can be any folder in the tests hierarchy (e.g. all engine\material tests). The file provides a hierarchal list of all the tests -## Create testAuto script -### Usage +### Create testAuto script +#### Usage This function creates a script named `testAuto.js` in a user-selected test folder. -### Details +#### Details The script created runs the `test.js` script in the folder in automatic mode. The script is the same for all tests. -## Create all testAuto scripts -### Usage +### Create all testAuto scripts +#### Usage This function creates all testAuto scripts recursively from the user-selected root folder. This can be any folder in the tests hierarchy (e.g. all engine\material tests). The file provides a hierarchical list of all the tests -## Create Recursive Script -### Usage +### Create Recursive Script +#### Usage After the user selects a folder within the tests hierarchy, a script is created, named `testRecursive.js`. This script calls all `test.js` scripts in the sub-folders. -### Details +#### Details The various scripts are called in alphabetical order. An example of a recursive script is as follows: @@ -130,18 +138,18 @@ Script.include(testsRootPath + "content/overlay/layer/drawHUDLayer/test.js"); nitpick.runRecursive(); ``` -## Create all Recursive Scripts -### Usage +### Create all Recursive Scripts +#### Usage In this case all recursive scripts, from the selected folder down, are created. Running this function in the tests root folder will create (or update) all the recursive scripts. -# Windows +## Windows ![](./Windows.PNG) This tab is Windows-specific. It provides buttons to hide and show the task bar. The task bar should be hidden for all tests that use the primary camera. This is required to ensure that the snapshots are the right size. -# Run +## Run ![](./Run.PNG) The run tab is used to run tests in automatic mode. The tests require the location of a folder to store files in; this folder can safely be re-used for any number of runs (the "Working Folder"). The test script that is run is `https://github.com/highfidelity/hifi_tests/blob/master/tests/testRecursive.js`. The user can use a different branch' or even repository, if required. @@ -163,7 +171,7 @@ The working folder will ultimately contain the following: 1. The `dev-builds.xml` file, if it was downloaded. 1. The HighFidelity installer. Note that this is always named `HighFidelity-Beta-latest-dev` so as not to store too many installers over time. 1. A log file describing the runs. This file is appended to after each run. -# Evaluate +## Evaluate ![](./Evaluate.PNG) The Evaluate tab provides a single function - evaluating the results of a test run. @@ -171,11 +179,11 @@ The Evaluate tab provides a single function - evaluating the results of a test r A checkbox (defaulting to checked) runs the evaluation in interactive mode. In this mode - every failure is shown to the user, who can then decide whether to pass the test, fail it or abort the whole evaluation. If any tests have failed, then a zipped folder will be created in the snapshots folder, with a description of each failed step in each test. -### Usage +#### Usage Before starting the evaluation, make sure the GitHub user and branch are set correctly. The user should not normally be changed, but the branch may need to be set to the appropriate RC. After setting the check-box as required and pressing Evaluate - the user will be asked for the snapshots folder. -### Details +#### Details Evaluation proceeds in a number of steps: 1. A folder is created to store any failures @@ -191,7 +199,7 @@ Evaluation proceeds in a number of steps: 1. At the end of the test, the folder is zipped and the original folder is deleted. If there are no errors then the zipped folder will be empty. -# Web Interface +## Web Interface ![](./WebInterface.PNG) This tab has two functions: updating the TestRail cases, runs and results, and creating web page reports that are stored on AWS. @@ -206,8 +214,8 @@ Any access to TestRail will require the TestRail account (default is High Fideli - The Project ID defaults to 14 - Interface. - The Suite ID defaults to 1147 - Rendering. - The TestRail page provides 3 functions for writing to TestRail. -## Create Test Cases -### Usage +### Create Test Cases +#### Usage This function can either create an XML file that can then be imported into TestRail through TestRail itself, or automatically create the appropriate TestRail Sections. The user will be first asked for the tests root folder and a folder to store temporary files (this is the output folder). @@ -219,7 +227,7 @@ If Python is selected, the user will then be prompted for TestRail data. After After selecting the appropriate Release, press OK. The Python script will be created in the output folder, and the user will be prompted to run it. A busy window will appear until the process is complete. -### Details +#### Details A number of Python scripts are created: - `testrail.py` is the TestRail interface code. - `stack.py` is a simple stack class @@ -227,7 +235,7 @@ A number of Python scripts are created: - `addTestCases` is the script that writes to TestRail. In addition - a file containing all the releases will be created - `releases.txt` -## Create Run +### Create Run A Run is created from previously created Test Cases. The user will first be prompted for a temporary folder (for the Python scripts). @@ -237,7 +245,7 @@ After entering TestRail data and pressing `Accept` - the Sections combo will be After selecting the appropriate Section, press OK. The Python script will be created in the output folder, and the user will be prompted to run it. A busy window will appear until the process is complete. -### Details +#### Details A number of Python scripts are created: - `testrail.py` is the TestRail interface code. - `stack.py` is a simple stack class @@ -245,7 +253,7 @@ A number of Python scripts are created: - `addRun` is the script that writes to TestRail. In addition - a file containing all the releases will be created - `sections.txt` -## Update Run Results +### Update Run Results This function updates a Run with the results of an automated test. The user will first be prompted to enter the zipped results folder and a folder to store temporary files (this is the output folder). @@ -255,13 +263,13 @@ After entering TestRail data and pressing `Accept` - the Run combo will be popul After selecting the appropriate Run, press OK. The Python script will be created in the output folder, and the user will be prompted to run it. A busy window will appear until the process is complete. -### Details +#### Details A number of Python scripts are created: - `testrail.py` is the TestRail interface code. - `getRuns.py` reads the release names from TestRail - `addRun` is the script that writes to TestRail. In addition - a file containing all the releases will be created - `runs.txt`. -## Create Web Page +### Create Web Page This function requests a zipped results folder and converts it to a web page. The page is created in a user-selecetd working folder. If the `Update AWS` checkbox is checked then the page will also be copied to AWS, and the appropriate URL will be displayed in the window below the button. From eea89655f69e0eb0f1dbe874a041b9cb4fd179a4 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 19 Nov 2018 10:33:04 -0800 Subject: [PATCH 032/109] WIP - Readme to install on Mac. --- tools/nitpick/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index aeafdc3384..8b16319b1a 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -34,7 +34,7 @@ Nitpick is built as part of the High Fidelity build. 1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Mac/nitpick-installer-v1.0.dmg: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.0.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.dmg` ### Installation #### Windows -1. Download the installer by browsing to [here](). +1. Download the installer by browsing to [here]() 1. (First time) download and install vc_redist.x64.exe (available at https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe) 1. (First time) download and install Python 3 from https://hifi-qa.s3.amazonaws.com/nitpick/Windows/python-3.7.0-amd64.exe (also located at https://www.python.org/downloads/) 1. After installation - create an environment variable called PYTHON_PATH and set it to the folder containing the Python executable. @@ -49,7 +49,7 @@ Nitpick is built as part of the High Fidelity build. ![](./setup_7z.PNG) 1. To run nitpick, double click **nitpick.exe** ####Mac -1. DOWNLOAD INSTALLER +1. Download the installer by browsing to [here](). 1. Install Python from https://www.python.org/downloads/release/python-370/ (**macOS 64-bit installer** or **macOS 64-bit/32-bit installer**) 1. After installation - run `open "/Applications/Python 3.6/Install Certificates.command"`. This is needed because the Mac Python supplied no longer links with the deprecated Apple-supplied system OpenSSL libraries but rather supplies a private copy of OpenSSL 1.0.2 which does not automatically access the system default root certificates. 1. Verify that `/usr/local/bin/python3` exists. From d6fbcb1668b9134b2013f72e44f801150d4cedc6 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 19 Nov 2018 11:04:09 -0800 Subject: [PATCH 033/109] remove entity highlighting --- .../controllers/controllerDispatcher.js | 4 - .../controllerModules/equipEntity.js | 6 - .../controllerModules/farActionGrabEntity.js | 84 +++------- .../highlightNearbyEntities.js | 155 ------------------ .../mouseHighlightEntities.js | 104 ------------ .../controllerModules/nearActionGrabEntity.js | 7 - .../controllerModules/nearParentGrabEntity.js | 25 +-- .../controllerModules/nearTrigger.js | 3 +- .../system/controllers/controllerScripts.js | 2 - 9 files changed, 31 insertions(+), 359 deletions(-) delete mode 100644 scripts/system/controllers/controllerModules/highlightNearbyEntities.js delete mode 100644 scripts/system/controllers/controllerModules/mouseHighlightEntities.js diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index b657faefba..2658f11989 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -129,9 +129,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); return getControllerWorldLocation(Controller.Standard.RightHand, true); }; - Selection.enableListHighlight(DISPATCHER_HOVERING_LIST, DISPATCHER_HOVERING_STYLE); - Selection.enableListToScene(DISPATCHER_HOVERING_LIST); - this.updateTimings = function () { _this.intervalCount++; var thisInterval = Date.now(); @@ -525,7 +522,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); Controller.disableMapping(MAPPING_NAME); _this.pointerManager.removePointers(); Pointers.removePointer(this.mouseRayPick); - Selection.disableListHighlight(DISPATCHER_HOVERING_LIST); }; } diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 12a69d7b27..c61e46c8eb 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -459,13 +459,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.dropGestureReset(); this.clearEquipHaptics(); Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); - unhighlightTargetEntity(this.targetEntityID); - var message = { - hand: this.hand, - entityID: this.targetEntityID - }; - Messages.sendLocalMessage('Hifi-unhighlight-entity', JSON.stringify(message)); var grabbedProperties = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES); var grabData = getGrabbableData(grabbedProperties); diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 91119a4292..1eaed44ce2 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -84,7 +84,6 @@ Script.include("/~/system/libraries/controllers.js"); this.entityWithContextOverlay = false; this.contextOverlayTimer = false; this.locked = false; - this.highlightedEntity = null; this.reticleMinX = MARGIN; this.reticleMaxX = null; this.reticleMinY = MARGIN; @@ -410,9 +409,6 @@ Script.include("/~/system/libraries/controllers.js"); if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || (this.notPointingAtEntity(controllerData) && Window.isPhysicsEnabled()) || this.targetIsNull()) { this.endFarGrabAction(); - Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", - this.highlightedEntity); - this.highlightedEntity = null; this.restoreIgnoredEntities(); return makeRunningValues(false, [], []); } @@ -466,9 +462,6 @@ Script.include("/~/system/libraries/controllers.js"); if (rayPickInfo.type === Picks.INTERSECTED_ENTITY) { if (controllerData.triggerClicks[this.hand]) { var entityID = rayPickInfo.objectID; - Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", - this.highlightedEntity); - this.highlightedEntity = null; var targetProps = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES); if (targetProps.href !== "") { AddressManager.handleLookupString(targetProps.href); @@ -513,66 +506,43 @@ Script.include("/~/system/libraries/controllers.js"); this.startFarGrabAction(controllerData, targetProps); } } - } else { - var targetEntityID = rayPickInfo.objectID; - if (this.highlightedEntity !== targetEntityID) { - Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", - this.highlightedEntity); - var selectionTargetProps = Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES); + } else if (!this.entityWithContextOverlay) { + var _this = this; - var selectionTargetObject = new TargetObject(targetEntityID, selectionTargetProps); - selectionTargetObject.parentProps = getEntityParents(selectionTargetProps); - var selectionTargetEntity = selectionTargetObject.getTargetEntity(); - - if (entityIsGrabbable(selectionTargetEntity.props) || - entityIsGrabbable(selectionTargetObject.entityProps)) { - - Selection.addToSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", rayPickInfo.objectID); + if (_this.potentialEntityWithContextOverlay !== rayPickInfo.objectID) { + if (_this.contextOverlayTimer) { + Script.clearTimeout(_this.contextOverlayTimer); } - this.highlightedEntity = rayPickInfo.objectID; + _this.contextOverlayTimer = false; + _this.potentialEntityWithContextOverlay = rayPickInfo.objectID; } - if (!this.entityWithContextOverlay) { - var _this = this; - - if (_this.potentialEntityWithContextOverlay !== rayPickInfo.objectID) { - if (_this.contextOverlayTimer) { - Script.clearTimeout(_this.contextOverlayTimer); + if (!_this.contextOverlayTimer) { + _this.contextOverlayTimer = Script.setTimeout(function () { + if (!_this.entityWithContextOverlay && + _this.contextOverlayTimer && + _this.potentialEntityWithContextOverlay === rayPickInfo.objectID) { + var props = Entities.getEntityProperties(rayPickInfo.objectID, DISPATCHER_PROPERTIES); + var pointerEvent = { + type: "Move", + id: _this.hand + 1, // 0 is reserved for hardware mouse + pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID, + rayPickInfo.intersection, props), + pos3D: rayPickInfo.intersection, + normal: rayPickInfo.surfaceNormal, + direction: Vec3.subtract(ZERO_VEC, rayPickInfo.surfaceNormal), + button: "Secondary" + }; + if (ContextOverlay.createOrDestroyContextOverlay(rayPickInfo.objectID, pointerEvent)) { + _this.entityWithContextOverlay = rayPickInfo.objectID; + } } _this.contextOverlayTimer = false; - _this.potentialEntityWithContextOverlay = rayPickInfo.objectID; - } - - if (!_this.contextOverlayTimer) { - _this.contextOverlayTimer = Script.setTimeout(function () { - if (!_this.entityWithContextOverlay && - _this.contextOverlayTimer && - _this.potentialEntityWithContextOverlay === rayPickInfo.objectID) { - var props = Entities.getEntityProperties(rayPickInfo.objectID, DISPATCHER_PROPERTIES); - var pointerEvent = { - type: "Move", - id: _this.hand + 1, // 0 is reserved for hardware mouse - pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID, - rayPickInfo.intersection, props), - pos3D: rayPickInfo.intersection, - normal: rayPickInfo.surfaceNormal, - direction: Vec3.subtract(ZERO_VEC, rayPickInfo.surfaceNormal), - button: "Secondary" - }; - if (ContextOverlay.createOrDestroyContextOverlay(rayPickInfo.objectID, pointerEvent)) { - _this.entityWithContextOverlay = rayPickInfo.objectID; - } - } - _this.contextOverlayTimer = false; - }, 500); - } + }, 500); } } } else if (this.distanceRotating) { this.distanceRotate(otherFarGrabModule); - } else if (this.highlightedEntity) { - Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity); - this.highlightedEntity = null; } } return this.exitIfDisabled(controllerData); diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js deleted file mode 100644 index 403b5d5149..0000000000 --- a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js +++ /dev/null @@ -1,155 +0,0 @@ -// -// highlightNearbyEntities.js -// -// Created by Dante Ruiz 2018-4-10 -// Copyright 2017 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 - - -/* global Script, MyAvatar, entityIsCloneable, Messages, print */ - -"use strict"; - -(function () { - Script.include("/~/system/libraries/controllerDispatcherUtils.js"); - Script.include("/~/system/libraries/controllers.js"); - Script.include("/~/system/libraries/cloneEntityUtils.js"); - var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js"); - - function differenceInArrays(firstArray, secondArray) { - var differenceArray = firstArray.filter(function(element) { - return secondArray.indexOf(element) < 0; - }); - - return differenceArray; - } - - function HighlightNearbyEntities(hand) { - this.hand = hand; - this.otherHand = hand === dispatcherUtils.RIGHT_HAND ? dispatcherUtils.LEFT_HAND : - dispatcherUtils.RIGHT_HAND; - this.highlightedEntities = []; - - this.parameters = dispatcherUtils.makeDispatcherModuleParameters( - 480, - this.hand === dispatcherUtils.RIGHT_HAND ? ["rightHand"] : ["leftHand"], - [], - 100); - - - this.isGrabable = function(controllerData, props) { - var canGrabEntity = false; - if (dispatcherUtils.entityIsGrabbable(props) || entityIsCloneable(props)) { - // if we've attempted to grab a child, roll up to the root of the tree - var groupRootProps = dispatcherUtils.findGroupParent(controllerData, props); - canGrabEntity = true; - if (!dispatcherUtils.entityIsGrabbable(groupRootProps)) { - canGrabEntity = false; - } - } - return canGrabEntity; - }; - - this.clearAll = function() { - this.highlightedEntities.forEach(function(entity) { - dispatcherUtils.unhighlightTargetEntity(entity); - }); - }; - - this.hasHyperLink = function(props) { - return (props.href !== "" && props.href !== undefined); - }; - - this.removeEntityFromHighlightList = function(entityID) { - var index = this.highlightedEntities.indexOf(entityID); - if (index > -1) { - this.highlightedEntities.splice(index, 1); - } - }; - - this.getOtherModule = function() { - var otherModule = this.hand === dispatcherUtils.RIGHT_HAND ? leftHighlightNearbyEntities : - rightHighlightNearbyEntities; - return otherModule; - }; - - this.getOtherHandHighlightedEntities = function() { - return this.getOtherModule().highlightedEntities; - }; - - this.highlightEntities = function(controllerData) { - var nearbyEntitiesProperties = controllerData.nearbyEntityProperties[this.hand]; - var otherHandHighlightedEntities = this.getOtherHandHighlightedEntities(); - var newHighlightedEntities = []; - var sensorScaleFactor = MyAvatar.sensorToWorldScale; - for (var i = 0; i < nearbyEntitiesProperties.length; i++) { - var props = nearbyEntitiesProperties[i]; - if (props.distance > dispatcherUtils.NEAR_GRAB_RADIUS * sensorScaleFactor) { - continue; - } - if (this.isGrabable(controllerData, props) || this.hasHyperLink(props)) { - dispatcherUtils.highlightTargetEntity(props.id); - if (newHighlightedEntities.indexOf(props.id) < 0) { - newHighlightedEntities.push(props.id); - } - } - } - - var unhighlightEntities = differenceInArrays(this.highlightedEntities, newHighlightedEntities); - - unhighlightEntities.forEach(function(entityID) { - if (otherHandHighlightedEntities.indexOf(entityID) < 0 ) { - dispatcherUtils.unhighlightTargetEntity(entityID); - } - }); - this.highlightedEntities = newHighlightedEntities; - }; - - this.isReady = function(controllerData) { - this.highlightEntities(controllerData); - return dispatcherUtils.makeRunningValues(false, [], []); - }; - - this.run = function(controllerData) { - return this.isReady(controllerData); - }; - } - - var handleMessage = function(channel, message, sender) { - var data; - if (sender === MyAvatar.sessionUUID) { - if (channel === 'Hifi-unhighlight-entity') { - try { - data = JSON.parse(message); - var hand = data.hand; - if (hand === dispatcherUtils.LEFT_HAND) { - leftHighlightNearbyEntities.removeEntityFromHighlightList(data.entityID); - } else if (hand === dispatcherUtils.RIGHT_HAND) { - rightHighlightNearbyEntities.removeEntityFromHighlightList(data.entityID); - } - } catch (e) { - print("highlightNearbyEntities -- Failed to parse message: " + JSON.stringify(message)); - } - } else if (channel === 'Hifi-unhighlight-all') { - leftHighlightNearbyEntities.clearAll(); - rightHighlightNearbyEntities.clearAll(); - } - } - }; - var leftHighlightNearbyEntities = new HighlightNearbyEntities(dispatcherUtils.LEFT_HAND); - var rightHighlightNearbyEntities = new HighlightNearbyEntities(dispatcherUtils.RIGHT_HAND); - - dispatcherUtils.enableDispatcherModule("LeftHighlightNearbyEntities", leftHighlightNearbyEntities); - dispatcherUtils.enableDispatcherModule("RightHighlightNearbyEntities", rightHighlightNearbyEntities); - - function cleanup() { - dispatcherUtils.disableDispatcherModule("LeftHighlightNearbyEntities"); - dispatcherUtils.disableDispatcherModule("RightHighlightNearbyEntities"); - } - Messages.subscribe('Hifi-unhighlight-entity'); - Messages.subscribe('Hifi-unhighlight-all'); - Messages.messageReceived.connect(handleMessage); - Script.scriptEnding.connect(cleanup); -}()); diff --git a/scripts/system/controllers/controllerModules/mouseHighlightEntities.js b/scripts/system/controllers/controllerModules/mouseHighlightEntities.js deleted file mode 100644 index 59a68d98a4..0000000000 --- a/scripts/system/controllers/controllerModules/mouseHighlightEntities.js +++ /dev/null @@ -1,104 +0,0 @@ -// -// mouseHighlightEntities.js -// -// scripts/system/controllers/controllerModules/ -// -// Created by Dante Ruiz 2018-4-11 -// Copyright 2017 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 -// - -/* jslint bitwise: true */ - -/* global Script, print, Entities, Messages, Picks, HMD, MyAvatar, isInEditMode, DISPATCHER_PROPERTIES */ - - -(function() { - Script.include("/~/system/libraries/utils.js"); - var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js"); - - function MouseHighlightEntities() { - this.highlightedEntity = null; - this.grabbedEntity = null; - - this.parameters = dispatcherUtils.makeDispatcherModuleParameters( - 5, - ["mouse"], - [], - 100); - - this.setGrabbedEntity = function(entity) { - this.grabbedEntity = entity; - this.highlightedEntity = null; - }; - - this.isReady = function(controllerData) { - if (HMD.active) { - if (this.highlightedEntity) { - dispatcherUtils.unhighlightTargetEntity(this.highlightedEntity); - this.highlightedEntity = null; - } - } else if (!this.grabbedEntity && !isInEditMode()) { - var pickResult = controllerData.mouseRayPick; - if (pickResult.type === Picks.INTERSECTED_ENTITY) { - var targetEntityID = pickResult.objectID; - - if (this.highlightedEntity !== targetEntityID) { - var targetProps = Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES); - - if (this.highlightedEntity) { - dispatcherUtils.unhighlightTargetEntity(this.highlightedEntity); - this.highlightedEntity = null; - } - - if (dispatcherUtils.entityIsGrabbable(targetProps)) { - // highlight entity - dispatcherUtils.highlightTargetEntity(targetEntityID); - this.highlightedEntity = targetEntityID; - } - } - } else if (this.highlightedEntity) { - dispatcherUtils.unhighlightTargetEntity(this.highlightedEntity); - this.highlightedEntity = null; - } - } - - return dispatcherUtils.makeRunningValues(false, [], []); - }; - - this.run = function(controllerData) { - return this.isReady(controllerData); - }; - } - - var mouseHighlightEntities = new MouseHighlightEntities(); - dispatcherUtils.enableDispatcherModule("MouseHighlightEntities", mouseHighlightEntities); - - var handleMessage = function(channel, message, sender) { - var data; - if (sender === MyAvatar.sessionUUID) { - if (channel === 'Hifi-Object-Manipulation') { - try { - data = JSON.parse(message); - if (data.action === 'grab') { - var grabbedEntity = data.grabbedEntity; - mouseHighlightEntities.setGrabbedEntity(grabbedEntity); - } else if (data.action === 'release') { - mouseHighlightEntities.setGrabbedEntity(null); - } - } catch (e) { - print("Warning: mouseHighlightEntities -- error parsing Hifi-Object-Manipulation: " + message); - } - } - } - }; - - function cleanup() { - dispatcherUtils.disableDispatcherModule("MouseHighlightEntities"); - } - Messages.subscribe('Hifi-Object-Manipulation'); - Messages.messageReceived.connect(handleMessage); - Script.scriptEnding.connect(cleanup); -})(); diff --git a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js index 5ced6080a2..dac98a7e0a 100644 --- a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js @@ -115,13 +115,6 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(this.targetEntityID, "startNearGrab", args); - unhighlightTargetEntity(this.targetEntityID); - var message = { - hand: this.hand, - entityID: this.targetEntityID - }; - - Messages.sendLocalMessage('Hifi-unhighlight-entity', JSON.stringify(message)); }; // this is for when the action is going to time-out diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index f354067a77..b327b88e1b 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -11,7 +11,7 @@ TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS, findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, findHandChildEntities, TEAR_AWAY_DISTANCE, MSECS_PER_SEC, TEAR_AWAY_CHECK_TIME, - TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Uuid, highlightTargetEntity, unhighlightTargetEntity, + TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Uuid, distanceBetweenEntityLocalPositionAndBoundingBox, getGrabbableData, getGrabPointSphereOffset, DISPATCHER_PROPERTIES */ @@ -45,7 +45,6 @@ Script.include("/~/system/libraries/controllers.js"); this.autoUnequipCounter = 0; this.lastUnexpectedChildrenCheckTime = 0; this.robbed = false; - this.highlightedEntity = null; this.cloneAllowed = true; this.parameters = makeDispatcherModuleParameters( @@ -95,14 +94,7 @@ Script.include("/~/system/libraries/controllers.js"); this.startNearParentingGrabEntity = function (controllerData, targetProps) { var grabData = getGrabbableData(targetProps); Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); - unhighlightTargetEntity(this.targetEntityID); - this.highlightedEntity = null; - var message = { - hand: this.hand, - entityID: this.targetEntityID - }; - Messages.sendLocalMessage('Hifi-unhighlight-entity', JSON.stringify(message)); var handJointIndex; if (grabData.grabFollowsController) { handJointIndex = getControllerJointIndex(this.hand); @@ -164,8 +156,7 @@ Script.include("/~/system/libraries/controllers.js"); grabbedEntity: this.targetEntityID, joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand" })); - unhighlightTargetEntity(this.targetEntityID); - this.highlightedEntity = null; + this.grabbing = false; this.targetEntityID = null; this.robbed = false; @@ -290,15 +281,9 @@ Script.include("/~/system/libraries/controllers.js"); return makeRunningValues(false, [], []); // let nearActionGrabEntity handle it } else { this.targetEntityID = targetProps.id; - this.highlightedEntity = this.targetEntityID; - highlightTargetEntity(this.targetEntityID); return makeRunningValues(true, [this.targetEntityID], []); } } else { - if (this.highlightedEntity) { - unhighlightTargetEntity(this.highlightedEntity); - this.highlightedEntity = null; - } this.hapticTargetID = null; this.robbed = false; return makeRunningValues(false, [], []); @@ -316,8 +301,6 @@ Script.include("/~/system/libraries/controllers.js"); var props = controllerData.nearbyEntityPropertiesByID[this.targetEntityID]; if (!props) { // entity was deleted - unhighlightTargetEntity(this.targetEntityID); - this.highlightedEntity = null; this.grabbing = false; this.targetEntityID = null; this.hapticTargetID = null; @@ -335,12 +318,10 @@ Script.include("/~/system/libraries/controllers.js"); var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(this.targetEntityID, "continueNearGrab", args); } else { - // still searching / highlighting + // still searching var readiness = this.isReady(controllerData); if (!readiness.active) { this.robbed = false; - unhighlightTargetEntity(this.highlightedEntity); - this.highlightedEntity = null; return readiness; } if (controllerData.triggerClicks[this.hand] || controllerData.secondaryValues[this.hand] > BUMPER_ON_VALUE) { diff --git a/scripts/system/controllers/controllerModules/nearTrigger.js b/scripts/system/controllers/controllerModules/nearTrigger.js index f4e39cfbb9..4bff4ea3f0 100644 --- a/scripts/system/controllers/controllerModules/nearTrigger.js +++ b/scripts/system/controllers/controllerModules/nearTrigger.js @@ -7,7 +7,7 @@ /* global Script, Entities, MyAvatar, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, getGrabbableData, - Vec3, TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS, unhighlightTargetEntity + Vec3, TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -55,7 +55,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.startNearTrigger = function (controllerData) { var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(this.targetEntityID, "startNearTrigger", args); - unhighlightTargetEntity(this.targetEntityID); }; this.continueNearTrigger = function (controllerData) { diff --git a/scripts/system/controllers/controllerScripts.js b/scripts/system/controllers/controllerScripts.js index 999e448171..83fa455519 100644 --- a/scripts/system/controllers/controllerScripts.js +++ b/scripts/system/controllers/controllerScripts.js @@ -35,9 +35,7 @@ var CONTOLLER_SCRIPTS = [ "controllerModules/hudOverlayPointer.js", "controllerModules/mouseHMD.js", "controllerModules/scaleEntity.js", - "controllerModules/highlightNearbyEntities.js", "controllerModules/nearGrabHyperLinkEntity.js", - "controllerModules/mouseHighlightEntities.js", "controllerModules/nearTabletHighlight.js" ]; From d30334fc3a236882bbb2e5ce8c05be158542ec4f Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 19 Nov 2018 11:47:00 -0800 Subject: [PATCH 034/109] Updating on Mac --- tools/nitpick/README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index 8b16319b1a..e112497aba 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -28,10 +28,14 @@ Nitpick is built as part of the High Fidelity build. #### Mac 1. (First time) install create-dmg: `brew install create-dmg` +1. Copy the quazip dynamic library: + `cp ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib ~/hifi/build/tools/nitpick/Release` +1. Change the loader instruction to find the dynamic library locally + `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib ./libquazip5.1.0.0.dylib ~/hifi/build/tools/nitpick/Release/nitpick` 1. cd to the `build/tools/nitpick/Release` folder -1. Delete any existing installer: `rm nitpick.dmg` -1. Create installer: `create-dmg --volname nitpick-installer-v1.0 nitpick-installer-v1.0.dmg "source_folder/" -1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Mac/nitpick-installer-v1.0.dmg: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.0.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.dmg` +1. Delete any existing installer: rm nitpick.dmg` +1. Create installer: `create-dmg --volname nitpick-installer-v1.0 nitpick-installer-v1.0.dmg "source_folder/"` +1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.0.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.dmg` ### Installation #### Windows 1. Download the installer by browsing to [here]() From 7ffa70d0ac3558c31811877dc6af0b66b66dbea2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 20 Nov 2018 09:36:58 +1300 Subject: [PATCH 035/109] Fix memory accumulating while Interface is minimized --- interface/src/Application.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7a30b566e9..929a27c88b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6222,6 +6222,11 @@ void Application::update(float deltaTime) { PerformanceTimer perfTimer("enqueueFrame"); getMain3DScene()->enqueueFrame(); } + + // If the display plugin is inactive then the frames won't be processed so process them here. + if (!getActiveDisplayPlugin()->isActive()) { + getMain3DScene()->processTransactionQueue(); + } } void Application::updateRenderArgs(float deltaTime) { From d4281212d6ba479644e49c2cc2b83dac814ef4dd Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 19 Nov 2018 14:32:47 -0800 Subject: [PATCH 036/109] First running version. --- tools/nitpick/README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index e112497aba..a0006cabe0 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -26,15 +26,16 @@ Nitpick is built as part of the High Fidelity build. 1. Click "OK" 1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe: aws s3 cp nitpick-installer-v1.0.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.exe #### Mac +These steps assume the hifi repository has been cloned to `~/hifi`. 1. (First time) install create-dmg: `brew install create-dmg` -1. Copy the quazip dynamic library: - `cp ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib ~/hifi/build/tools/nitpick/Release` +1. Copy the quazip dynamic library to the Release: + `cp ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib ~/hifi/build/tools/nitpick/Release/` 1. Change the loader instruction to find the dynamic library locally - `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib ./libquazip5.1.0.0.dylib ~/hifi/build/tools/nitpick/Release/nitpick` + `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib ~/hifi/build/tools/nitpick/Release/libquazip5.1.dylib ~/hifi/build/tools/nitpick/Release/nitpick` 1. cd to the `build/tools/nitpick/Release` folder -1. Delete any existing installer: rm nitpick.dmg` -1. Create installer: `create-dmg --volname nitpick-installer-v1.0 nitpick-installer-v1.0.dmg "source_folder/"` +1. Delete any existing installer: `rm nitpick.dmg` +1. Create installer (note final period!): `create-dmg --volname nitpick-installer-v1.0 nitpick-installer-v1.0.dmg .` 1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.0.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.dmg` ### Installation #### Windows From a448efb45279acbae68578545f694ea42470290b Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 19 Nov 2018 16:01:53 -0800 Subject: [PATCH 037/109] WIP - Readme to install on Mac. --- tools/nitpick/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index a0006cabe0..c891ee1844 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -53,7 +53,7 @@ These steps assume the hifi repository has been cloned to `~/hifi`. 1. Double click on the installer and install to a convenient location ![](./setup_7z.PNG) 1. To run nitpick, double click **nitpick.exe** -####Mac +#### Mac 1. Download the installer by browsing to [here](). 1. Install Python from https://www.python.org/downloads/release/python-370/ (**macOS 64-bit installer** or **macOS 64-bit/32-bit installer**) 1. After installation - run `open "/Applications/Python 3.6/Install Certificates.command"`. This is needed because the Mac Python supplied no longer links with the deprecated Apple-supplied system OpenSSL libraries but rather supplies a private copy of OpenSSL 1.0.2 which does not automatically access the system default root certificates. From da60aaa5af4454861b8263fb12220789cbd54b53 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 19 Nov 2018 17:52:21 -0800 Subject: [PATCH 038/109] WIP - Readme to install on Mac. --- tools/nitpick/README.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index c891ee1844..3bbc4fbac1 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -29,17 +29,16 @@ Nitpick is built as part of the High Fidelity build. These steps assume the hifi repository has been cloned to `~/hifi`. 1. (First time) install create-dmg: `brew install create-dmg` -1. Copy the quazip dynamic library to the Release: - `cp ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib ~/hifi/build/tools/nitpick/Release/` -1. Change the loader instruction to find the dynamic library locally - `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib ~/hifi/build/tools/nitpick/Release/libquazip5.1.dylib ~/hifi/build/tools/nitpick/Release/nitpick` 1. cd to the `build/tools/nitpick/Release` folder +1. Copy the quazip dynamic library (note final period): + `cp ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib .` +1. Change the loader instruction to find the dynamic library locally + `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib libquazip5.1.dylib nitpick` 1. Delete any existing installer: `rm nitpick.dmg` -1. Create installer (note final period!): `create-dmg --volname nitpick-installer-v1.0 nitpick-installer-v1.0.dmg .` +1. Create installer (note final period): `create-dmg --volname nitpick-installer-v1.0 nitpick-installer-v1.0.dmg .` 1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.0.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.dmg` ### Installation #### Windows -1. Download the installer by browsing to [here]() 1. (First time) download and install vc_redist.x64.exe (available at https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe) 1. (First time) download and install Python 3 from https://hifi-qa.s3.amazonaws.com/nitpick/Windows/python-3.7.0-amd64.exe (also located at https://www.python.org/downloads/) 1. After installation - create an environment variable called PYTHON_PATH and set it to the folder containing the Python executable. @@ -50,12 +49,13 @@ These steps assume the hifi repository has been cloned to `~/hifi`. 1. Leave region name and ouput format as default [None] 1. Install the latest release of Boto3 via pip: `pip install boto3` +1. Download the installer by browsing to [here]() 1. Double click on the installer and install to a convenient location ![](./setup_7z.PNG) -1. To run nitpick, double click **nitpick.exe** + +1. __To run nitpick, double click **nitpick.exe**__ #### Mac -1. Download the installer by browsing to [here](). -1. Install Python from https://www.python.org/downloads/release/python-370/ (**macOS 64-bit installer** or **macOS 64-bit/32-bit installer**) +1. (Firat time) install Python from https://www.python.org/downloads/release/python-370/ (**macOS 64-bit installer** or **macOS 64-bit/32-bit installer**) 1. After installation - run `open "/Applications/Python 3.6/Install Certificates.command"`. This is needed because the Mac Python supplied no longer links with the deprecated Apple-supplied system OpenSSL libraries but rather supplies a private copy of OpenSSL 1.0.2 which does not automatically access the system default root certificates. 1. Verify that `/usr/local/bin/python3` exists. 1. (First time - AWS interface) Install pip with the script provided by the Python Packaging Authority: @@ -69,7 +69,13 @@ $ python3 get-pip.py --user 1. Enter the secret key 1. Leave region name and ouput format as default [None] 1. Install the latest release of Boto3 via pip: pip3 install boto3 +1. Download the installer by browsing to [here](). +1. Double-click on the downloaded image to mount it +1. Create a folder for the nitpick files (e.g. ~/nitpick) +1. Copy the downloaded files to the folder + `cp -r /Volumes/nitpick-installer-v1.0/* .` +1. __To run nitpick, cd to the folder that you copied to and run `./nitpick`__ #Use ## Create ![](./Create.PNG) From e24eee897ee504a974fcf4955f979c3e0e015efb Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 19 Nov 2018 17:59:02 -0800 Subject: [PATCH 039/109] Typo. --- interface/src/Application.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 603a02ffae..fb6e8ec566 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4899,12 +4899,6 @@ void Application::idle() { _idleLoopStdev.reset(); } } - - // This is done here so it won't be during a resize/move event - if (_setGeometryRequested) { - _setGeometryRequested = false; - _window->setGeometry(requestedGeometry); - } _overlayConductor.update(secondsSinceLastUpdate); From 58408497d1177006b462625175dfb0fa6715ef98 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 19 Nov 2018 21:27:23 -0500 Subject: [PATCH 040/109] hopefully fix hud crash --- .../display-plugins/OpenGLDisplayPlugin.cpp | 20 +++++++++---- .../display-plugins/hmd/HmdDisplayPlugin.cpp | 28 ++++++++++++------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 190d4d4104..9991130efc 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -534,18 +534,26 @@ void OpenGLDisplayPlugin::updateFrameData() { } std::function OpenGLDisplayPlugin::getHUDOperator() { - return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { - if (_hudPipeline && hudTexture) { + auto hudPipeline = _hudPipeline; + auto hudMirrorPipeline = _mirrorHUDPipeline; + auto hudStereo = isStereo(); + auto hudCompositeFramebufferSize = _compositeFramebuffer->getSize(); + glm::ivec4 hudEyeViewports[2]; + for_each_eye([&](Eye eye) { + hudEyeViewports[eye] = eyeViewport(eye); + }); + return [hudPipeline, hudMirrorPipeline, hudStereo, hudEyeViewports, hudCompositeFramebufferSize](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { + if (hudPipeline && hudTexture) { batch.enableStereo(false); - batch.setPipeline(mirror ? _mirrorHUDPipeline : _hudPipeline); + batch.setPipeline(mirror ? hudMirrorPipeline : hudPipeline); batch.setResourceTexture(0, hudTexture); - if (isStereo()) { + if (hudStereo) { for_each_eye([&](Eye eye) { - batch.setViewportTransform(eyeViewport(eye)); + batch.setViewportTransform(hudEyeViewports[eye]); batch.draw(gpu::TRIANGLE_STRIP, 4); }); } else { - batch.setViewportTransform(ivec4(uvec2(0), _compositeFramebuffer->getSize())); + batch.setViewportTransform(ivec4(uvec2(0), hudCompositeFramebufferSize)); batch.draw(gpu::TRIANGLE_STRIP, 4); } } diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index d76b211ede..c0b1a7b753 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -420,18 +420,26 @@ void HmdDisplayPlugin::HUDRenderer::updatePipeline() { std::function HmdDisplayPlugin::HUDRenderer::render(HmdDisplayPlugin& plugin) { updatePipeline(); - return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { - if (pipeline && hudTexture) { - batch.setPipeline(pipeline); - batch.setInputFormat(format); - gpu::BufferView posView(vertices, VERTEX_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::POSITION)._element); - gpu::BufferView uvView(vertices, TEXTURE_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::TEXCOORD)._element); + auto hudPipeline = pipeline; + auto hudFormat = format; + auto hudVertices = vertices; + auto hudIndices = indices; + auto hudUniformBuffer = uniformsBuffer; + auto hudUniforms = uniforms; + auto hudIndexCount = indexCount; + return [hudPipeline, hudFormat, hudVertices, hudIndices, hudUniformBuffer, hudUniforms, hudIndexCount](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { + if (hudPipeline && hudTexture) { + batch.setPipeline(hudPipeline); + + batch.setInputFormat(hudFormat); + gpu::BufferView posView(hudVertices, VERTEX_OFFSET, hudVertices->getSize(), VERTEX_STRIDE, hudFormat->getAttributes().at(gpu::Stream::POSITION)._element); + gpu::BufferView uvView(hudVertices, TEXTURE_OFFSET, hudVertices->getSize(), VERTEX_STRIDE, hudFormat->getAttributes().at(gpu::Stream::TEXCOORD)._element); batch.setInputBuffer(gpu::Stream::POSITION, posView); batch.setInputBuffer(gpu::Stream::TEXCOORD, uvView); - batch.setIndexBuffer(gpu::UINT16, indices, 0); - uniformsBuffer->setSubData(0, uniforms); - batch.setUniformBuffer(0, uniformsBuffer); + batch.setIndexBuffer(gpu::UINT16, hudIndices, 0); + hudUniformBuffer->setSubData(0, hudUniforms); + batch.setUniformBuffer(0, hudUniformBuffer); auto compositorHelper = DependencyManager::get(); glm::mat4 modelTransform = compositorHelper->getUiTransform(); @@ -441,7 +449,7 @@ std::function HmdDis batch.setModelTransform(modelTransform); batch.setResourceTexture(0, hudTexture); - batch.drawIndexed(gpu::TRIANGLES, indexCount); + batch.drawIndexed(gpu::TRIANGLES, hudIndexCount); } }; } From e8d45c46c186863b304cacffb3a217650cf72f55 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 19 Nov 2018 23:31:20 -0500 Subject: [PATCH 041/109] shouldn't be able to write actionData --- libraries/entities/src/EntityScriptingInterface.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 3d68a27bc9..5487ae33b0 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -486,6 +486,8 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties propertiesWithSimID.setLastEditedBy(sessionID); + propertiesWithSimID.setActionData(QByteArray()); + bool scalesWithParent = propertiesWithSimID.getScalesWithParent(); propertiesWithSimID = convertPropertiesFromScriptSemantics(propertiesWithSimID, scalesWithParent); @@ -830,6 +832,8 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& properties.setClientOnly(entity->getClientOnly()); properties.setOwningAvatarID(entity->getOwningAvatarID()); + properties.setActionData(entity->getDynamicData()); + // make sure the properties has a type, so that the encode can know which properties to include properties.setType(entity->getType()); From db607e564ff3c4f2d199fd0bdbb991878a2a5e1e Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 20 Nov 2018 09:13:07 -0800 Subject: [PATCH 042/109] fixing keyboard mallets dimensions --- interface/src/ui/Keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/Keyboard.cpp b/interface/src/ui/Keyboard.cpp index 6852691634..46a25a24a7 100644 --- a/interface/src/ui/Keyboard.cpp +++ b/interface/src/ui/Keyboard.cpp @@ -60,7 +60,7 @@ static const float MALLET_TOUCH_Y_OFFSET = 0.050f; static const float MALLET_Y_OFFSET = 0.160f; static const glm::quat MALLET_ROTATION_OFFSET{0.70710678f, 0.0f, -0.70710678f, 0.0f}; -static const glm::vec3 MALLET_MODEL_DIMENSIONS{0.03f, MALLET_LENGTH, 0.03f}; +static const glm::vec3 MALLET_MODEL_DIMENSIONS{0.01f, MALLET_LENGTH, 0.01f}; static const glm::vec3 MALLET_POSITION_OFFSET{0.0f, -MALLET_Y_OFFSET / 2.0f, 0.0f}; static const glm::vec3 MALLET_TIP_OFFSET{0.0f, MALLET_LENGTH - MALLET_TOUCH_Y_OFFSET, 0.0f}; From a2bcc9e899118fe47c0260e66f26539b3f5e4740 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 20 Nov 2018 15:19:54 -0800 Subject: [PATCH 043/109] teeny weeny typo... --- tools/nitpick/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index 3bbc4fbac1..dce3880123 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -55,7 +55,7 @@ These steps assume the hifi repository has been cloned to `~/hifi`. 1. __To run nitpick, double click **nitpick.exe**__ #### Mac -1. (Firat time) install Python from https://www.python.org/downloads/release/python-370/ (**macOS 64-bit installer** or **macOS 64-bit/32-bit installer**) +1. (First time) install Python from https://www.python.org/downloads/release/python-370/ (**macOS 64-bit installer** or **macOS 64-bit/32-bit installer**) 1. After installation - run `open "/Applications/Python 3.6/Install Certificates.command"`. This is needed because the Mac Python supplied no longer links with the deprecated Apple-supplied system OpenSSL libraries but rather supplies a private copy of OpenSSL 1.0.2 which does not automatically access the system default root certificates. 1. Verify that `/usr/local/bin/python3` exists. 1. (First time - AWS interface) Install pip with the script provided by the Python Packaging Authority: From f6ffb16103b3788078ca2cd90cf65c7562c263d4 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 20 Nov 2018 15:21:39 -0800 Subject: [PATCH 044/109] Version 1.1 --- tools/nitpick/src/ui/Nitpick.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nitpick/src/ui/Nitpick.cpp b/tools/nitpick/src/ui/Nitpick.cpp index a4aef8fad5..201d6e562d 100644 --- a/tools/nitpick/src/ui/Nitpick.cpp +++ b/tools/nitpick/src/ui/Nitpick.cpp @@ -36,7 +36,7 @@ Nitpick::Nitpick(QWidget* parent) : QMainWindow(parent) { _ui.statusLabel->setText(""); _ui.plainTextEdit->setReadOnly(true); - setWindowTitle("Nitpick - v1.0"); + setWindowTitle("Nitpick - v1.1"); // Coming soon to a nitpick near you... //// _helpWindow.textBrowser->setText() From c3c41700f6a9ea8fd00782e631a9ce38c4fdbd57 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 20 Nov 2018 17:01:58 -0800 Subject: [PATCH 045/109] Can delete temporarY AppData folder and rename High Fidelity folder as a temporary folder --- tools/nitpick/src/TestRunner.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/nitpick/src/TestRunner.cpp b/tools/nitpick/src/TestRunner.cpp index c7823ba751..30aad70f5f 100644 --- a/tools/nitpick/src/TestRunner.cpp +++ b/tools/nitpick/src/TestRunner.cpp @@ -336,16 +336,18 @@ void TestRunner::saveExistingHighFidelityAppDataFolder() { QString dataDirectory{ "NOT FOUND" }; dataDirectory = qgetenv("USERPROFILE") + "\\AppData\\Roaming"; - +#elif defined Q_OS_MAC + QString dataDirectory{ QDir::homePath() + "/Library/Application Support" }; +#endif if (_runLatest->isChecked()) { - _appDataFolder = dataDirectory + "\\High Fidelity"; + _appDataFolder = dataDirectory + "/High Fidelity"; } else { // We are running a PR build - _appDataFolder = dataDirectory + "\\High Fidelity - " + getPRNumberFromURL(_url->text()); + _appDataFolder = dataDirectory + "/High Fidelity - " + getPRNumberFromURL(_url->text()); } _savedAppDataFolder = dataDirectory + "/" + UNIQUE_FOLDER_NAME; - if (_savedAppDataFolder.exists()) { + if (QDir(_savedAppDataFolder).exists()) { _savedAppDataFolder.removeRecursively(); } @@ -356,9 +358,6 @@ void TestRunner::saveExistingHighFidelityAppDataFolder() { // Copy an "empty" AppData folder (i.e. no entities) copyFolder(QDir::currentPath() + "/AppDataHighFidelity", _appDataFolder.path()); -#elif defined Q_OS_MAC - // TODO: find Mac equivalent of AppData -#endif } void TestRunner::createSnapshotFolder() { From 44b9b92450f9f2c884a9cad8194dcc8225c6719a Mon Sep 17 00:00:00 2001 From: sam gateau Date: Tue, 20 Nov 2018 17:32:04 -0800 Subject: [PATCH 046/109] Getting ready for merge --- interface/src/Application.cpp | 39 +---- interface/src/Application.h | 18 -- interface/src/graphics/GraphicsEngine.cpp | 31 +--- interface/src/graphics/GraphicsEngine.h | 6 - interface/src/graphics/RenderEventHandler.cpp | 4 - interface/src/graphics/RenderThread.cpp | 1 - interface/src/graphics/RenderThread.h | 108 ------------ interface/src/ui/ApplicationOverlay.cpp | 2 - .../utilities/render/GlobalLighting.js | 155 ------------------ .../utilities/render/engineInspector.js | 71 -------- .../utilities/render/engineInspector.qml | 30 ---- .../utilities/render/engineProfiler.js | 59 ------- .../utilities/render/engineProfiler.qml | 31 ---- 13 files changed, 10 insertions(+), 545 deletions(-) delete mode 100644 interface/src/graphics/RenderThread.cpp delete mode 100644 interface/src/graphics/RenderThread.h delete mode 100644 scripts/developer/utilities/render/GlobalLighting.js delete mode 100644 scripts/developer/utilities/render/engineInspector.js delete mode 100644 scripts/developer/utilities/render/engineInspector.qml delete mode 100644 scripts/developer/utilities/render/engineProfiler.js delete mode 100644 scripts/developer/utilities/render/engineProfiler.qml diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f4bd15403e..dae9e3dad2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -87,7 +87,6 @@ #include #include #include -//#include #include #include #include @@ -2313,7 +2312,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo DependencyManager::get()->createKeyboard(); _pendingIdleEvent = false; - // _pendingRenderEvent = false; _graphicsEngine.startup(); qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); @@ -2578,11 +2576,6 @@ void Application::cleanupBeforeQuit() { // Cleanup all overlays after the scripts, as scripts might add more _overlays.cleanupAllOverlays(); - // The cleanup process enqueues the transactions but does not process them. Calling this here will force the actual - // removal of the items. - // See https://highfidelity.fogbugz.com/f/cases/5328 - // _main3DScene->enqueueFrame(); // flush all the transactions - // _main3DScene->processTransactionQueue(); // process and apply deletions // first stop all timers directly or by invokeMethod // depending on what thread they run in @@ -2598,8 +2591,6 @@ void Application::cleanupBeforeQuit() { _window->saveGeometry(); - // _gpuContext->shutdown(); - // Destroy third party processes after scripts have finished using them. #ifdef HAVE_DDE DependencyManager::destroy(); @@ -2655,9 +2646,7 @@ Application::~Application() { _shapeManager.collectGarbage(); assert(_shapeManager.getNumShapes() == 0); - // shutdown render engine - //_main3DScene = nullptr; - //_renderEngine = nullptr; + // shutdown graphics engine _graphicsEngine.shutdown(); _gameWorkload.shutdown(); @@ -2717,9 +2706,6 @@ Application::~Application() { // Can't log to file passed this point, FileLogger about to be deleted qInstallMessageHandler(LogHandler::verboseMessageHandler); - - -// _renderEventHandler->deleteLater(); } void Application::initializeGL() { @@ -4681,19 +4667,6 @@ void Application::idle() { PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get()->getStat("PendingProcessing").toInt()); auto renderConfig = _graphicsEngine.getRenderEngine()->getConfiguration(); PROFILE_COUNTER_IF_CHANGED(render, "gpuTime", float, (float)_graphicsEngine.getGPUContext()->getFrameTimerGPUAverage()); -/* auto opaqueRangeTimer = renderConfig->getConfig("OpaqueRangeTimer"); - auto linearDepth = renderConfig->getConfig("LinearDepth"); - auto surfaceGeometry = renderConfig->getConfig("SurfaceGeometry"); - auto renderDeferred = renderConfig->getConfig("RenderDeferred"); - auto toneAndPostRangeTimer = renderConfig->getConfig("ToneAndPostRangeTimer"); - - PROFILE_COUNTER(render_detail, "gpuTimes", { - { "OpaqueRangeTimer", opaqueRangeTimer ? opaqueRangeTimer->property("gpuRunTime") : 0 }, - { "LinearDepth", linearDepth ? linearDepth->property("gpuRunTime") : 0 }, - { "SurfaceGeometry", surfaceGeometry ? surfaceGeometry->property("gpuRunTime") : 0 }, - { "RenderDeferred", renderDeferred ? renderDeferred->property("gpuRunTime") : 0 }, - { "ToneAndPostRangeTimer", toneAndPostRangeTimer ? toneAndPostRangeTimer->property("gpuRunTime") : 0 } - });*/ PROFILE_RANGE(app, __FUNCTION__); @@ -5062,9 +5035,6 @@ QVector Application::pasteEntities(float x, float y, float z) { void Application::init() { // Make sure Login state is up to date DependencyManager::get()->toggleLoginDialog(); -// if (!DISABLE_DEFERRED) { - // DependencyManager::get()->init(); - // } DependencyManager::get()->init(); _timerStart.start(); @@ -6129,13 +6099,6 @@ void Application::update(float deltaTime) { updateRenderArgs(deltaTime); - // HACK - // load the view frustum - // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. - // Then we can move this logic into the Avatar::simulate call. -// myAvatar->preDisplaySide(&_appRenderArgs._renderArgs); - - { PerformanceTimer perfTimer("AnimDebugDraw"); AnimDebugDraw::getInstance().update(); diff --git a/interface/src/Application.h b/interface/src/Application.h index b5ce040c94..2f23fc72d7 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -153,8 +153,6 @@ public: void updateSecondaryCameraViewFrustum(); void updateCamera(RenderArgs& renderArgs, float deltaTime); - // bool shouldPaint() const; -// void paintGL(); void resizeGL(); bool event(QEvent* event) override; @@ -276,11 +274,6 @@ public: void setMaxOctreePacketsPerSecond(int maxOctreePPS); int getMaxOctreePacketsPerSecond() const; -/* render::ScenePointer getMain3DScene() override { return _main3DScene; } - const render::ScenePointer& getMain3DScene() const { return _main3DScene; } - render::EnginePointer getRenderEngine() override { return _renderEngine; } - gpu::ContextPointer getGPUContext() const { return _gpuContext; } - */ render::ScenePointer getMain3DScene() override { return _graphicsEngine.getRenderScene(); } const render::ScenePointer& getMain3DScene() const { return _graphicsEngine.getRenderScene(); } render::EnginePointer getRenderEngine() override { return _graphicsEngine.getRenderEngine(); } @@ -541,8 +534,6 @@ private: void initializeAcceptedFiles(); - // void runRenderFrame(RenderArgs* renderArgs/*, Camera& whichCamera, bool selfAvatarOnly = false*/); - bool importJSONFromURL(const QString& urlString); bool importSVOFromURL(const QString& urlString); bool importFromZIP(const QString& filePath); @@ -598,7 +589,6 @@ private: QTimer _minimizedWindowTimer; QElapsedTimer _timerStart; QElapsedTimer _lastTimeUpdated; - // QElapsedTimer _lastTimeRendered; int _minimumGPUTextureMemSizeStabilityCount { 30 }; @@ -684,10 +674,6 @@ private: quint64 _lastFaceTrackerUpdate; - // render::ScenePointer _main3DScene{ new render::Scene(glm::vec3(-0.5f * (float)TREE_SCALE), (float)TREE_SCALE) }; - // render::EnginePointer _renderEngine{ new render::RenderEngine() }; - // gpu::ContextPointer _gpuContext; // initialized during window creation - GameWorkload _gameWorkload; GraphicsEngine _graphicsEngine; @@ -769,12 +755,8 @@ private: QUrl _avatarOverrideUrl; bool _saveAvatarOverrideUrl { false }; - // QObject* _renderEventHandler{ nullptr }; - - // friend class RenderEventHandler; std::atomic _pendingIdleEvent { true }; - // std::atomic _pendingRenderEvent { true }; bool quitWhenFinished { false }; diff --git a/interface/src/graphics/GraphicsEngine.cpp b/interface/src/graphics/GraphicsEngine.cpp index 55be37ba60..aecaa74d12 100644 --- a/interface/src/graphics/GraphicsEngine.cpp +++ b/interface/src/graphics/GraphicsEngine.cpp @@ -127,12 +127,7 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI bool GraphicsEngine::shouldPaint() const { -// if (_aboutToQuit || _window->isMinimized()) { -// return false; - // } - - - auto displayPlugin = qApp->getActiveDisplayPlugin(); + auto displayPlugin = qApp->getActiveDisplayPlugin(); #ifdef DEBUG_PAINT_DELAY static uint64_t paintDelaySamples{ 0 }; @@ -148,15 +143,14 @@ bool GraphicsEngine::shouldPaint() const { } #endif - // Throttle if requested - //if (displayPlugin->isThrottled() && (_graphicsEngine._renderEventHandler->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { - if ( displayPlugin->isThrottled() && - (static_cast(_renderEventHandler)->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { - return false; - } + // Throttle if requested + //if (displayPlugin->isThrottled() && (_graphicsEngine._renderEventHandler->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { + if ( displayPlugin->isThrottled() && + (static_cast(_renderEventHandler)->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { + return false; + } - return true; - // } + return true; } bool GraphicsEngine::checkPendingRenderEvent() { @@ -170,17 +164,11 @@ void GraphicsEngine::render_performFrame() { // Some plugins process message events, allowing paintGL to be called reentrantly. _renderFrameCount++; - // SG: Moved into the RenderEventHandler - //_lastTimeRendered.start(); auto lastPaintBegin = usecTimestampNow(); PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_renderFrameCount); PerformanceTimer perfTimer("paintGL"); - /* if (nullptr == _displayPlugin) { - return; - }*/ - DisplayPluginPointer displayPlugin; { PROFILE_RANGE(render, "/getActiveDisplayPlugin"); @@ -310,5 +298,4 @@ void GraphicsEngine::render_performFrame() { void GraphicsEngine::editRenderArgs(RenderArgsEditor editor) { QMutexLocker renderLocker(&_renderArgsMutex); editor(_appRenderArgs); - -} \ No newline at end of file +} diff --git a/interface/src/graphics/GraphicsEngine.h b/interface/src/graphics/GraphicsEngine.h index 6efddce51a..490f5312b5 100644 --- a/interface/src/graphics/GraphicsEngine.h +++ b/interface/src/graphics/GraphicsEngine.h @@ -16,8 +16,6 @@ #include -#include "RenderThread.h" - #include #include @@ -53,8 +51,6 @@ public: render::EnginePointer getRenderEngine() const { return _renderEngine; } gpu::ContextPointer getGPUContext() const { return _gpuContext; } - FrameQueuePointer getFrameQueue() const { return _frameQueue; } - // Same as the one in application bool shouldPaint() const; bool checkPendingRenderEvent(); @@ -83,8 +79,6 @@ protected: gpu::ContextPointer _gpuContext; // initialized during window creation - FrameQueuePointer _frameQueue{ new FrameQueue() }; - QObject* _renderEventHandler{ nullptr }; friend class RenderEventHandler; diff --git a/interface/src/graphics/RenderEventHandler.cpp b/interface/src/graphics/RenderEventHandler.cpp index 42af3bb9c0..bdb2cae060 100644 --- a/interface/src/graphics/RenderEventHandler.cpp +++ b/interface/src/graphics/RenderEventHandler.cpp @@ -19,13 +19,9 @@ RenderEventHandler::RenderEventHandler(CheckCall checkCall, RenderCall renderCal _checkCall(checkCall), _renderCall(renderCall) { - // Deleting the object with automatically shutdown the thread - // connect(qApp, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater); - // Transfer to a new thread moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) { hifi::qt::addBlockingForbiddenThread("Render", renderThread); - //_renderContext->moveToThreadWithContext(renderThread); _lastTimeRendered.start(); }, std::bind(&RenderEventHandler::initialize, this), QThread::HighestPriority); } diff --git a/interface/src/graphics/RenderThread.cpp b/interface/src/graphics/RenderThread.cpp deleted file mode 100644 index 63df2033e8..0000000000 --- a/interface/src/graphics/RenderThread.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "RenderThread.h" \ No newline at end of file diff --git a/interface/src/graphics/RenderThread.h b/interface/src/graphics/RenderThread.h deleted file mode 100644 index abddf746e6..0000000000 --- a/interface/src/graphics/RenderThread.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef PRODUCERCONSUMERPIPE_H -#define PRODUCERCONSUMERPIPE_H - -#include -#include -#include -#include -#include - -// Producer is blocked if the consumer doesn't consume enough -// Consumer reads same value if producer doesn't produce enough -template -class ProducerConsumerPipe { -public: - - ProducerConsumerPipe(); - ProducerConsumerPipe(const T& initValue); - - const T& read(); - void read(T& value, const T& resetValue); - void write(const T& value); - bool isWritePossible(); - -private: - - short _readIndex; - short _writeIndex; - std::array _values; - std::array _used; - - void initialize(); - void updateReadIndex(); -}; - -template -ProducerConsumerPipe::ProducerConsumerPipe() { - initialize(); -} - -template -ProducerConsumerPipe::ProducerConsumerPipe(const T& initValue) { - _values.fill(initValue); - initialize(); -} - -template -void ProducerConsumerPipe::initialize() { - _readIndex = 0; - _writeIndex = 2; - _used[_readIndex].test_and_set(std::memory_order_acquire); - _used[_writeIndex].test_and_set(std::memory_order_acquire); - _used[1].clear(); -} - -template -void ProducerConsumerPipe::updateReadIndex() { - int nextReadIndex = (_readIndex + 1) % _values.size(); - - if (!_used[nextReadIndex].test_and_set(std::memory_order_acquire)) { - int readIndex = _readIndex; - _used[readIndex].clear(std::memory_order_release); - _readIndex = nextReadIndex; - } -} - -template -const T& ProducerConsumerPipe::read() { - updateReadIndex(); - return _values[_readIndex]; -} - -template -void ProducerConsumerPipe::read(T& value, const T& resetValue) { - updateReadIndex(); - value = _values[_readIndex]; - _values[_readIndex] = resetValue; -} - -template -bool ProducerConsumerPipe::isWritePossible() { - int nextWriteIndex = (_writeIndex + 1) % _values.size(); - return (_used[nextWriteIndex].test_and_set(std::memory_order_acquire)); -} - -template -void ProducerConsumerPipe::write(const T& value) { - int nextWriteIndex = (_writeIndex + 1) % _values.size(); - int writeIndex = _writeIndex; - - _values[writeIndex] = value; - - while (_used[nextWriteIndex].test_and_set(std::memory_order_acquire)) { - // spin - std::this_thread::yield(); - } - _used[writeIndex].clear(std::memory_order_release); - _writeIndex = nextWriteIndex; -} - - -#include - -using FrameQueue = ProducerConsumerPipe; - -using FrameQueuePointer = std::shared_ptr; - - -#endif diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index aed54463ba..46cdbd5b3e 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -55,8 +55,6 @@ ApplicationOverlay::~ApplicationOverlay() { // Renders the overlays either to a texture or to the screen void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { PROFILE_RANGE(render, __FUNCTION__); -// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()"); - buildFramebufferObject(); if (!_overlayFramebuffer) { diff --git a/scripts/developer/utilities/render/GlobalLighting.js b/scripts/developer/utilities/render/GlobalLighting.js deleted file mode 100644 index 766b87314f..0000000000 --- a/scripts/developer/utilities/render/GlobalLighting.js +++ /dev/null @@ -1,155 +0,0 @@ -// -// Global lighting.js -// -// Sam Gateau, created on 6/7/2018. -// Copyright 2018 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 -// -var createdOverlays = []; -var overlayFrames = {}; - -Script.scriptEnding.connect(function () { - for (var i = 0; i < createdOverlays.length; i++) { - Overlays.deleteOverlay(createdOverlays[i]); - } -}); - - -var DIM = {x: 0.1, y: 0.13, z: 0.1}; -var avatarHeadJoint = MyAvatar.getJointIndex("Head"); - -function createOrb(i) { - - var props = { - dimensions: DIM, - } - - props["url"] = "https://github.com/highfidelity/hifi_tests/blob/master/assets/models/material_matrix_models/fbx/blender/hifi_metallicV_albedoV_ao.fbx?raw=true" - props["position"] = getCamePos(i) - // props["localPosition"] = { x: 0.4 * i, y: 0, z: 0} - props["rotation"] = getCameOri() - - if (createdOverlays.length > 0) { - props["parentID"] = createdOverlays[0] - - } - - var oID = Overlays.addOverlay("model", props); - - /* { - position: getCamePos(), - // position: MyAvatar.getJointPosition(avatarHeadJoint), - // localPosition: {x: 0, y: 1, z: 0}, - // localRotation: {x: 0, y: 0, z: 0, w:1}, - url: "https://github.com/highfidelity/hifi_tests/blob/master/assets/models/material_matrix_models/fbx/blender/hifi_metallicV_albedoV_ao.fbx?raw=true", - dimensions: DIM, - // parentID: MyAvatar.SELF_ID, - // parentJointIndex: avatarHeadJoint, - })*/ - - overlayFrames[oID] = { position: getCamePos(), rotation: getCameOri() } - - // Overlays.editOverlay(oID, overlayFrames[oID]) - - props = Overlays.getProperties(oID, ["position", "rotation"]) - print("createOrb" + oID + JSON.stringify(props)) - - return oID; -} - - -function createSnap(i) { - - var props = { - // dimensions: DIM, - // url: "resource://spectatorCameraFrame", - emissive: true, - url: "https://hifi-public.s3.amazonaws.com/sam/2018-oct/code/PackagedApp/asset/CarrotHunt.png", - dimensions: DIM, - // parentID: MyAvatar.SELF_ID, - // parentJointIndex: avatarHeadJoint, - alpha: 1, - // localRotation: { w: 1, x: 0, y: 0, z: 0 }, - // localPosition: { x: 0, y: 0.0, z: -1.0 }, - dimensions: DIM - } - - // props["url"] = "https://github.com/highfidelity/hifi_tests/blob/master/assets/models/material_matrix_models/fbx/blender/hifi_metallicV_albedoV_ao.fbx?raw=true" - props["position"] = getCamePos(i) - // props["localPosition"] = { x: 0.4 * i, y: 0, z: 0} - props["rotation"] = getCameOri() - - if (createdOverlays.length > 0) { - props["parentID"] = createdOverlays[0] - - } - - var oID = Overlays.addOverlay("image3d", props); - - /* { - position: getCamePos(), - // position: MyAvatar.getJointPosition(avatarHeadJoint), - // localPosition: {x: 0, y: 1, z: 0}, - // localRotation: {x: 0, y: 0, z: 0, w:1}, - url: "https://github.com/highfidelity/hifi_tests/blob/master/assets/models/material_matrix_models/fbx/blender/hifi_metallicV_albedoV_ao.fbx?raw=true", - dimensions: DIM, - // parentID: MyAvatar.SELF_ID, - // parentJointIndex: avatarHeadJoint, - })*/ - - overlayFrames[oID] = { position: getCamePos(), rotation: getCameOri() } - - // Overlays.editOverlay(oID, overlayFrames[oID]) - - props = Overlays.getProperties(oID, ["position", "rotation"]) - print("createOrb" + oID + JSON.stringify(props)) - - return oID; -} - -function createOrbs() { - print("createOrbs") - - createdOverlays.push(createOrb(0)); - createdOverlays.push(createOrb(1)); - createdOverlays.push(createSnap(2)); - -} - -var camSpace = {} - -function updateCamSpace() { - camSpace["pos"] = Camera.Position; - camSpace["ori"] = Camera.orientation; - camSpace["X"] = Vec3.multiply(Quat.getRight(Camera.orientation), Camera.frustum.aspectRatio); - camSpace["Y"] = Quat.getUp(Camera.orientation); - camSpace["Z"] = Vec3.multiply(Quat.getForward(), -1); -} - -function getCamePos(i) { - - return Vec3.sum(Camera.position, Vec3.multiplyQbyV(Camera.orientation, { x: -0.5 + 0.2 * i, y: -0.3, z: -1 })) - // return Vec3.add(Camera.position, {x: i * 0.3, y:0, z:1} -} -function getCameOri() { - return Camera.orientation -} -function updateFrames() { - for (var i = 0; i < createdOverlays.length; i++) { - overlayFrames[createdOverlays[i]] = { position: getCamePos(i), rotation: getCameOri() } - } - Overlays.editOverlays(overlayFrames) - -} - - -createOrbs() - -var accumulated = 0; -Script.update.connect(function(deltaTime) { - accumulated += deltaTime; - if (accumulated > 1) - updateFrames() -}); \ No newline at end of file diff --git a/scripts/developer/utilities/render/engineInspector.js b/scripts/developer/utilities/render/engineInspector.js deleted file mode 100644 index 74e4231ff1..0000000000 --- a/scripts/developer/utilities/render/engineInspector.js +++ /dev/null @@ -1,71 +0,0 @@ - /*function openEngineTaskView() { - // Set up the qml ui - var qml = Script.resolvePath('engineInspector.qml'); - var window = new OverlayWindow({ - title: 'Render Engine', - source: qml, - width: 500, - height: 100 - }); - window.setPosition(200, 50); - window.closed.connect(function() { Script.stop(); }); - } - openEngineTaskView();*/ - - (function() { - var TABLET_BUTTON_NAME = "Inspector"; - var QMLAPP_URL = Script.resolvePath("./engineInspector.qml"); - var ICON_URL = Script.resolvePath("../../../system/assets/images/luci-i.svg"); - var ACTIVE_ICON_URL = Script.resolvePath("../../../system/assets/images/luci-a.svg"); - - var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); - var button = tablet.addButton({ - text: TABLET_BUTTON_NAME, - icon: ICON_URL, - activeIcon: ACTIVE_ICON_URL - }); - - Script.scriptEnding.connect(function () { - killWindow() - button.clicked.disconnect(onClicked); - tablet.removeButton(button); - }); - - button.clicked.connect(onClicked); - - var onScreen = false; - var window; - - function onClicked() { - if (onScreen) { - killWindow() - } else { - createWindow() - } - } - - function createWindow() { - var qml = Script.resolvePath(QMLAPP_URL); - window = new OverlayWindow({ - title: 'Render Engine Inspector', - source: qml, - width: 250, - height: 500 - }); - window.setPosition(200, 50); - window.closed.connect(killWindow); - onScreen = true - button.editProperties({isActive: true}); - } - - function killWindow() { - if (window !== undefined) { - window.closed.disconnect(killWindow); - window.close() - window = undefined - } - onScreen = false - button.editProperties({isActive: false}) - } - }()); - \ No newline at end of file diff --git a/scripts/developer/utilities/render/engineInspector.qml b/scripts/developer/utilities/render/engineInspector.qml deleted file mode 100644 index 31283a4756..0000000000 --- a/scripts/developer/utilities/render/engineInspector.qml +++ /dev/null @@ -1,30 +0,0 @@ -// -// EngineInspector.qml -// -// Created by Sam Gateau on 06/07/2018 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html -// -import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Layouts 1.3 - -import stylesUit 1.0 -import controlsUit 1.0 as HifiControls - -import "../lib/jet/qml" as Jet - -Item { - HifiConstants { id: hifi;} - id: root; - anchors.fill: parent - - property var rootConfig: Render.getConfig("") - - Jet.TaskListView { - rootConfig: root.rootConfig - anchors.fill: root - } -} \ No newline at end of file diff --git a/scripts/developer/utilities/render/engineProfiler.js b/scripts/developer/utilities/render/engineProfiler.js deleted file mode 100644 index 418cab8622..0000000000 --- a/scripts/developer/utilities/render/engineProfiler.js +++ /dev/null @@ -1,59 +0,0 @@ - - - (function() { - var TABLET_BUTTON_NAME = "Profiler"; - var QMLAPP_URL = Script.resolvePath("./engineProfiler.qml"); - var ICON_URL = Script.resolvePath("../../../system/assets/images/luci-i.svg"); - var ACTIVE_ICON_URL = Script.resolvePath("../../../system/assets/images/luci-a.svg"); - - var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); - var button = tablet.addButton({ - text: TABLET_BUTTON_NAME, - icon: ICON_URL, - activeIcon: ACTIVE_ICON_URL - }); - - Script.scriptEnding.connect(function () { - killWindow() - button.clicked.disconnect(onClicked); - tablet.removeButton(button); - }); - - button.clicked.connect(onClicked); - - var onScreen = false; - var window; - - function onClicked() { - if (onScreen) { - killWindow() - } else { - createWindow() - } - } - - function createWindow() { - var qml = Script.resolvePath(QMLAPP_URL); - window = Desktop.createWindow(Script.resolvePath(QMLAPP_URL), { - title: 'Render Engine Profiler', - flags: Desktop.ALWAYS_ON_TOP, - presentationMode: Desktop.PresentationMode.NATIVE, - size: {x: 500, y: 100} - }); - window.setPosition(200, 50); - window.closed.connect(killWindow); - onScreen = true - button.editProperties({isActive: true}); - } - - function killWindow() { - if (window !== undefined) { - window.closed.disconnect(killWindow); - window.close() - window = undefined - } - onScreen = false - button.editProperties({isActive: false}) - } - }()); - \ No newline at end of file diff --git a/scripts/developer/utilities/render/engineProfiler.qml b/scripts/developer/utilities/render/engineProfiler.qml deleted file mode 100644 index bfa049d089..0000000000 --- a/scripts/developer/utilities/render/engineProfiler.qml +++ /dev/null @@ -1,31 +0,0 @@ -// -// EngineProfiler.qml -// -// Created by Sam Gateau on 06/07/2018 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html -// -import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Layouts 1.3 - -import "qrc:///qml/styles-uit" -import "qrc:///qml/controls-uit" as HifiControls - -import "../lib/jet/qml" as Jet - -Item { - HifiConstants { id: hifi;} - id: root; - anchors.fill: parent - - property var rootConfig: Render.getConfig("") - - - Jet.TaskTimeFrameView { - rootConfig: root.rootConfig - anchors.fill: root - } -} \ No newline at end of file From f3bbd412d147719dc97f763657ab6e35f595680d Mon Sep 17 00:00:00 2001 From: sam gateau Date: Tue, 20 Nov 2018 17:40:59 -0800 Subject: [PATCH 047/109] Cleaning too many changes --- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 6 +++--- .../display-plugins/OpenGLDisplayPlugin.cpp | 11 +---------- libraries/gpu/src/gpu/Buffer.cpp | 18 ------------------ libraries/gpu/src/gpu/Buffer.h | 4 ++-- 4 files changed, 6 insertions(+), 33 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 7e95727fcc..d8b8cbd54a 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -165,11 +165,11 @@ static const uint32_t MIN_THROTTLE_CHECK_FRAMES = 60; bool Basic2DWindowOpenGLDisplayPlugin::isThrottled() const { static auto lastCheck = presentCount(); // Don't access the menu API every single frame - // if ((presentCount() - lastCheck) > MIN_THROTTLE_CHECK_FRAMES) { + if ((presentCount() - lastCheck) > MIN_THROTTLE_CHECK_FRAMES) { static const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus"; // FIXME - this value duplicated in Menu.h _isThrottled = (!_container->isForeground() && _container->isOptionChecked(ThrottleFPSIfNotFocus)); - // lastCheck = presentCount(); - // } + lastCheck = presentCount(); + } return _isThrottled; } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 362952ddd7..190d4d4104 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -172,16 +172,7 @@ public: // If there's no active plugin, just sleep if (currentPlugin == nullptr) { // Minimum sleep ends up being about 2 ms anyway - QThread::msleep(16); - continue; - } - - static uint _vsyncLoopIndex = 0; - _vsyncLoopIndex++; - - if (currentPlugin->isThrottled() && (_vsyncLoopIndex % 8)) { - // Minimum sleep ends up being about 2 ms anyway - QThread::msleep(16); + QThread::msleep(1); continue; } diff --git a/libraries/gpu/src/gpu/Buffer.cpp b/libraries/gpu/src/gpu/Buffer.cpp index b3716c3490..ebb768e597 100644 --- a/libraries/gpu/src/gpu/Buffer.cpp +++ b/libraries/gpu/src/gpu/Buffer.cpp @@ -163,24 +163,6 @@ Buffer::Size Buffer::getSize() const { const Element BufferView::DEFAULT_ELEMENT = Element( gpu::SCALAR, gpu::UINT8, gpu::RAW ); -BufferView::BufferView(const BufferView& view) : - _buffer(view._buffer), - _offset(view._offset), - _size(view._size), - _element(view._element), - _stride(view._stride) -{} - -BufferView& BufferView::operator=(const BufferView& view) { - _buffer = (view._buffer); - _offset = (view._offset); - _size = (view._size); - _element = (view._element); - _stride = (view._stride); - - return (*this); -} - BufferView::BufferView() : BufferView(DEFAULT_ELEMENT) {} diff --git a/libraries/gpu/src/gpu/Buffer.h b/libraries/gpu/src/gpu/Buffer.h index e486e2392a..01cc652fd1 100644 --- a/libraries/gpu/src/gpu/Buffer.h +++ b/libraries/gpu/src/gpu/Buffer.h @@ -183,8 +183,8 @@ public: Element _element { DEFAULT_ELEMENT }; uint16 _stride { 0 }; - BufferView(const BufferView& view); - BufferView& operator=(const BufferView& view); + BufferView(const BufferView& view) = default; + BufferView& operator=(const BufferView& view) = default; BufferView(); BufferView(const Element& element); From 4ef54cd4f277e43bcbc355a87f8019da617266e9 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 20 Nov 2018 17:45:37 -0800 Subject: [PATCH 048/109] Tests run without Interface crashing. --- tools/nitpick/src/TestRunner.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/nitpick/src/TestRunner.cpp b/tools/nitpick/src/TestRunner.cpp index 30aad70f5f..0a5002d02d 100644 --- a/tools/nitpick/src/TestRunner.cpp +++ b/tools/nitpick/src/TestRunner.cpp @@ -350,7 +350,6 @@ void TestRunner::saveExistingHighFidelityAppDataFolder() { if (QDir(_savedAppDataFolder).exists()) { _savedAppDataFolder.removeRecursively(); } - if (_appDataFolder.exists()) { // The original folder is saved in a unique name _appDataFolder.rename(_appDataFolder.path(), _savedAppDataFolder.path()); From 4c0f8b176b72ba0e66c0f50510d4fba0b4a67388 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 20 Nov 2018 19:59:43 -0800 Subject: [PATCH 049/109] No need for this after implementation of AppData on Mac. --- tools/nitpick/src/TestRunner.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tools/nitpick/src/TestRunner.cpp b/tools/nitpick/src/TestRunner.cpp index 0a5002d02d..9549dedb91 100644 --- a/tools/nitpick/src/TestRunner.cpp +++ b/tools/nitpick/src/TestRunner.cpp @@ -467,12 +467,7 @@ void TestRunner::runInterfaceWithTestScript() { // Move to an empty area url = "file:///~serverless/tutorial.json"; } else { -#ifdef Q_OS_WIN url = "hifi://localhost"; -#elif defined Q_OS_MAC - // TODO: Find out Mac equivalent of AppData, then this won't be needed - url = "hifi://localhost/9999,9999,9999"; -#endif } QString testScript = From eb2533d22418f0fc24b3f37f685d7235b2ae26fc Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 20 Nov 2018 20:51:20 -0800 Subject: [PATCH 050/109] Updated CMake file to include the AppData folder --- tools/nitpick/CMakeLists.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/nitpick/CMakeLists.txt b/tools/nitpick/CMakeLists.txt index 543b9c9b47..efb5125f69 100644 --- a/tools/nitpick/CMakeLists.txt +++ b/tools/nitpick/CMakeLists.txt @@ -50,10 +50,12 @@ if (WIN32) ) # add a custom command to copy the empty Apps/Data High Fidelity folder (i.e. - a valid folder with no entities) + # this also copied to the containing folder, to facilitate running from Visual Studio add_custom_command( TARGET ${TARGET_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/AppDataHighFidelity" "$/AppDataHighFidelity" + COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/AppDataHighFidelity" "AppDataHighFidelity" ) # add a custom command to copy the SSL DLLs @@ -62,5 +64,12 @@ if (WIN32) POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_directory "$ENV{VCPKG_ROOT}/installed/x64-windows/bin" "$" ) +elseif (APPLE) + # add a custom command to copy the empty Apps/Data High Fidelity folder (i.e. - a valid folder with no entities) + add_custom_command( + TARGET ${TARGET_NAME} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/AppDataHighFidelity" "$/AppDataHighFidelity" + ) +endif () -endif () \ No newline at end of file From 2b71a82e4e59b853800a705f623744372d275d2a Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 20 Nov 2018 20:52:13 -0800 Subject: [PATCH 051/109] Updated to v1.1 --- tools/nitpick/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index dce3880123..e325be1f40 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -35,8 +35,8 @@ These steps assume the hifi repository has been cloned to `~/hifi`. 1. Change the loader instruction to find the dynamic library locally `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib libquazip5.1.dylib nitpick` 1. Delete any existing installer: `rm nitpick.dmg` -1. Create installer (note final period): `create-dmg --volname nitpick-installer-v1.0 nitpick-installer-v1.0.dmg .` -1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.0.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.dmg` +1. Create installer (note final period): `create-dmg --volname nitpick-installer-v1.1 nitpick-installer-v1.1.dmg .` +1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.1.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.dmg` ### Installation #### Windows 1. (First time) download and install vc_redist.x64.exe (available at https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe) From c99a8101f7a6468dd7bfe4f094321495a5419411 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 20 Nov 2018 16:48:26 -0500 Subject: [PATCH 052/109] trying to fix build errors --- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 4 ++-- .../src/display-plugins/hmd/HmdDisplayPlugin.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 9991130efc..2d19a745e1 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -538,11 +538,11 @@ std::function OpenGL auto hudMirrorPipeline = _mirrorHUDPipeline; auto hudStereo = isStereo(); auto hudCompositeFramebufferSize = _compositeFramebuffer->getSize(); - glm::ivec4 hudEyeViewports[2]; + std::array hudEyeViewports; for_each_eye([&](Eye eye) { hudEyeViewports[eye] = eyeViewport(eye); }); - return [hudPipeline, hudMirrorPipeline, hudStereo, hudEyeViewports, hudCompositeFramebufferSize](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { + return [=](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { if (hudPipeline && hudTexture) { batch.enableStereo(false); batch.setPipeline(mirror ? hudMirrorPipeline : hudPipeline); diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index c0b1a7b753..321bcc3fd2 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -428,7 +428,7 @@ std::function HmdDis auto hudUniformBuffer = uniformsBuffer; auto hudUniforms = uniforms; auto hudIndexCount = indexCount; - return [hudPipeline, hudFormat, hudVertices, hudIndices, hudUniformBuffer, hudUniforms, hudIndexCount](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { + return [=](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { if (hudPipeline && hudTexture) { batch.setPipeline(hudPipeline); From 6b1c7bf96e3a67420c0c7929bf9d65691f5d696a Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 20 Nov 2018 23:15:09 -0800 Subject: [PATCH 053/109] restoring the engine render views and cleaning up the task / config section of the pr --- libraries/render-utils/src/BloomEffect.cpp | 1 - libraries/task/src/task/Config.cpp | 3 - libraries/task/src/task/Config.h | 2 +- libraries/task/src/task/Task.h | 2 +- scripts/developer/utilities/lib/jet/jet.js | 5 +- .../utilities/render/engineInspector.js | 71 +++++++++++++++++++ .../utilities/render/engineInspector.qml | 30 ++++++++ .../utilities/render/engineProfiler.js | 59 +++++++++++++++ .../utilities/render/engineProfiler.qml | 31 ++++++++ 9 files changed, 196 insertions(+), 8 deletions(-) create mode 100644 scripts/developer/utilities/render/engineInspector.js create mode 100644 scripts/developer/utilities/render/engineInspector.qml create mode 100644 scripts/developer/utilities/render/engineProfiler.js create mode 100644 scripts/developer/utilities/render/engineProfiler.qml diff --git a/libraries/render-utils/src/BloomEffect.cpp b/libraries/render-utils/src/BloomEffect.cpp index e5b32bb1d4..414a1c3f91 100644 --- a/libraries/render-utils/src/BloomEffect.cpp +++ b/libraries/render-utils/src/BloomEffect.cpp @@ -283,7 +283,6 @@ void BloomEffect::configure(const Config& config) { blurName.back() = '0' + i; auto blurConfig = config.getConfig(blurName); blurConfig->filterScale = 1.0f; - //blurConfig->setProperty("filterScale", 1.0f); } } diff --git a/libraries/task/src/task/Config.cpp b/libraries/task/src/task/Config.cpp index c0e9c41468..5e8e4b246d 100644 --- a/libraries/task/src/task/Config.cpp +++ b/libraries/task/src/task/Config.cpp @@ -41,7 +41,6 @@ void JobConfig::setPresetList(const QJsonObject& object) { void TaskConfig::connectChildConfig(QConfigPointer childConfig, const std::string& name) { childConfig->setParent(this); childConfig->setObjectName(name.c_str()); - // childConfig->propagateParentEnabled((_isParentEnabled ? _isEnabled : false)); // Connect loaded->refresh QObject::connect(childConfig.get(), SIGNAL(loaded()), this, SLOT(refresh())); @@ -69,8 +68,6 @@ void TaskConfig::transferChildrenConfigs(QConfigPointer source) { QObject::connect(child, SIGNAL(dirtyEnabled()), this, SLOT(refresh())); } } - - // propagateParentEnabledToSubs(); } void TaskConfig::refresh() { diff --git a/libraries/task/src/task/Config.h b/libraries/task/src/task/Config.h index ab3303110b..da9b95a274 100644 --- a/libraries/task/src/task/Config.h +++ b/libraries/task/src/task/Config.h @@ -125,7 +125,7 @@ public: // Running Time measurement // The new stats signal is emitted once per run time of a job when stats (cpu runtime) are updated - void setCPURunTime(const std::chrono::nanoseconds& runtime) { _msCPURunTime = std::chrono::duration(runtime).count(); /* emit newStats();*/ } + void setCPURunTime(const std::chrono::nanoseconds& runtime) { _msCPURunTime = std::chrono::duration(runtime).count(); emit newStats(); } double getCPURunTime() const { return _msCPURunTime; } // Describe the node graph data connections of the associated Job/Task diff --git a/libraries/task/src/task/Task.h b/libraries/task/src/task/Task.h index 0f4c67478e..fb7012b16c 100644 --- a/libraries/task/src/task/Task.h +++ b/libraries/task/src/task/Task.h @@ -164,7 +164,7 @@ public: void run(const ContextPointer& jobContext) override { jobContext->jobConfig = std::static_pointer_cast(Concept::_config); - if (/*jobContext->jobConfig->alwaysEnabled || */jobContext->jobConfig->isEnabled()) { + if (jobContext->jobConfig->isEnabled()) { jobRun(_data, jobContext, _input.get(), _output.edit()); } jobContext->jobConfig.reset(); diff --git a/scripts/developer/utilities/lib/jet/jet.js b/scripts/developer/utilities/lib/jet/jet.js index cb78e2cc3f..71fb3e1f70 100644 --- a/scripts/developer/utilities/lib/jet/jet.js +++ b/scripts/developer/utilities/lib/jet/jet.js @@ -172,7 +172,7 @@ function job_tree_model_functor(jobTreeModel, maxLevel, newNodeFunctor) { // Traverse the jobTreenode data structure created above function job_traverseTreeNode(root, functor, depth) { - // if (root.subNode.length) { + if (root.subNode.length) { depth++; for (var i = 0; i Date: Wed, 21 Nov 2018 13:31:54 -0800 Subject: [PATCH 054/109] Warnings from build --- interface/src/Application.cpp | 2 -- interface/src/Application.h | 1 - .../src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp | 2 +- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dae9e3dad2..61365f3625 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -324,8 +324,6 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI static const int ENTITY_SERVER_ADDED_TIMEOUT = 5000; static const int ENTITY_SERVER_CONNECTION_TIMEOUT = 5000; -static const uint32_t INVALID_FRAME = UINT32_MAX; - static const float INITIAL_QUERY_RADIUS = 10.0f; // priority radius for entities before physics enabled static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); diff --git a/interface/src/Application.h b/interface/src/Application.h index 2f23fc72d7..ead7231ffc 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -275,7 +275,6 @@ public: int getMaxOctreePacketsPerSecond() const; render::ScenePointer getMain3DScene() override { return _graphicsEngine.getRenderScene(); } - const render::ScenePointer& getMain3DScene() const { return _graphicsEngine.getRenderScene(); } render::EnginePointer getRenderEngine() override { return _graphicsEngine.getRenderEngine(); } gpu::ContextPointer getGPUContext() const { return _graphicsEngine.getGPUContext(); } diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index d8b8cbd54a..9d39a1968c 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -148,7 +148,7 @@ void Basic2DWindowOpenGLDisplayPlugin::compositeExtra() { batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(0, _virtualPadStickTexture); - batch.setModelTransform(stickTransform); + batch.setModelTransform(stickTransform);, batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(0, _virtualPadJumpBtnTexture); From 48f32dc36b9c737970eedece356629b274ecaec8 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Wed, 21 Nov 2018 13:35:36 -0800 Subject: [PATCH 055/109] Remove stuppid error --- .../src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 9d39a1968c..d8b8cbd54a 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -148,7 +148,7 @@ void Basic2DWindowOpenGLDisplayPlugin::compositeExtra() { batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(0, _virtualPadStickTexture); - batch.setModelTransform(stickTransform);, + batch.setModelTransform(stickTransform); batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(0, _virtualPadJumpBtnTexture); From 9ee35def3dc5aa5118d064919e3b8a1152e15e37 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Wed, 21 Nov 2018 15:42:35 -0800 Subject: [PATCH 056/109] trying to fix the include issue --- interface/src/graphics/RenderEventHandler.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/graphics/RenderEventHandler.h b/interface/src/graphics/RenderEventHandler.h index c566202b5b..93f8b548d0 100644 --- a/interface/src/graphics/RenderEventHandler.h +++ b/interface/src/graphics/RenderEventHandler.h @@ -10,9 +10,9 @@ #ifndef hifi_RenderEventHandler_h #define hifi_RenderEventHandler_h +#include +#include #include "gl/OffscreenGLCanvas.h" -#include -#include enum ApplicationEvent { // Execute a lambda function From 1e746e1b1c85233dcdf450250385e065ca76b799 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 21 Nov 2018 16:43:13 -0800 Subject: [PATCH 057/109] Swap key light directions in Create --- scripts/system/html/js/entityProperties.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 78e3cd4dc8..ce6fabd0c5 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -197,7 +197,7 @@ const GROUPS = [ multiplier: DEGREES_TO_RADIANS, decimals: 2, unit: "deg", - propertyID: "keyLight.direction.x", + propertyID: "keyLight.direction.y", showPropertyRule: { "keyLightMode": "enabled" }, }, { @@ -206,7 +206,7 @@ const GROUPS = [ multiplier: DEGREES_TO_RADIANS, decimals: 2, unit: "deg", - propertyID: "keyLight.direction.y", + propertyID: "keyLight.direction.x", showPropertyRule: { "keyLightMode": "enabled" }, }, { From 1362e7f3613949ea967b87306ed231bd5c0076b3 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 24 Nov 2018 08:26:54 +1300 Subject: [PATCH 058/109] Fix near parent grab entity tear away distance calc --- .../controllerModules/nearParentGrabEntity.js | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index f354067a77..e5d3b055bc 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -24,15 +24,6 @@ Script.include("/~/system/libraries/controllers.js"); // XXX this.ignoreIK = (grabbableData.ignoreIK !== undefined) ? grabbableData.ignoreIK : true; // XXX this.kinematicGrab = (grabbableData.kinematic !== undefined) ? grabbableData.kinematic : NEAR_GRABBING_KINEMATIC; - // this offset needs to match the one in libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp:378 - var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 }; // x = upward, y = forward, z = lateral - - function getGrabOffset(handController) { - var offset = getGrabPointSphereOffset(handController, true); - offset.y = -offset.y; - return Vec3.multiply(MyAvatar.sensorToWorldScale, offset); - } - function NearParentingGrabEntity(hand) { this.hand = hand; this.targetEntityID = null; @@ -178,8 +169,10 @@ Script.include("/~/system/libraries/controllers.js"); this.lastUnequipCheckTime = now; if (props.parentID === MyAvatar.SELF_ID) { var tearAwayDistance = TEAR_AWAY_DISTANCE * MyAvatar.sensorToWorldScale; - var controllerIndex = (this.hand === LEFT_HAND ? Controller.Standard.LeftHand : Controller.Standard.RightHand); - var controllerGrabOffset = getGrabOffset(controllerIndex); + var controllerIndex = + this.hand === LEFT_HAND ? Controller.Standard.LeftHand : Controller.Standard.RightHand; + var controllerGrabOffset = getGrabPointSphereOffset(controllerIndex, true); + controllerGrabOffset = Vec3.multiply(-1, controllerGrabOffset); var distance = distanceBetweenEntityLocalPositionAndBoundingBox(props, controllerGrabOffset); if (distance > tearAwayDistance) { this.autoUnequipCounter++; @@ -242,13 +235,15 @@ Script.include("/~/system/libraries/controllers.js"); // nearbyEntityProperties is already sorted by length from controller var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand]; var sensorScaleFactor = MyAvatar.sensorToWorldScale; + var tearAwayDistance = TEAR_AWAY_DISTANCE * sensorScaleFactor; + var nearGrabRadius = NEAR_GRAB_RADIUS * sensorScaleFactor; for (var i = 0; i < nearbyEntityProperties.length; i++) { var props = nearbyEntityProperties[i]; - var handPosition = controllerData.controllerLocations[this.hand].position; - var dist = distanceBetweenPointAndEntityBoundingBox(handPosition, props); - var distance = Vec3.distance(handPosition, props.position); - if ((dist > TEAR_AWAY_DISTANCE) || - (distance > NEAR_GRAB_RADIUS * sensorScaleFactor)) { + var grabPosition = controllerData.controllerLocations[this.hand].position; // Is offset from hand position. + var dist = distanceBetweenPointAndEntityBoundingBox(grabPosition, props); + var distance = Vec3.distance(grabPosition, props.position); + if ((dist > tearAwayDistance) || + (distance > nearGrabRadius)) { // Only smallish entities can be near grabbed. continue; } if (entityIsGrabbable(props) || entityIsCloneable(props)) { From f1dad3c465b3bcc07605470db8a6a75fca168733 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 24 Nov 2018 08:35:02 +1300 Subject: [PATCH 059/109] Add hystersis between near parent grabbing and tearing away --- .../controllers/controllerModules/nearParentGrabEntity.js | 7 ++++--- scripts/system/libraries/controllerDispatcherUtils.js | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index e5d3b055bc..db10fff69a 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -12,7 +12,8 @@ findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, findHandChildEntities, TEAR_AWAY_DISTANCE, MSECS_PER_SEC, TEAR_AWAY_CHECK_TIME, TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Uuid, highlightTargetEntity, unhighlightTargetEntity, - distanceBetweenEntityLocalPositionAndBoundingBox, getGrabbableData, getGrabPointSphereOffset, DISPATCHER_PROPERTIES + distanceBetweenEntityLocalPositionAndBoundingBox, getGrabbableData, getGrabPointSphereOffset, DISPATCHER_PROPERTIES, + NEAR_GRAB_DISTANCE */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -235,14 +236,14 @@ Script.include("/~/system/libraries/controllers.js"); // nearbyEntityProperties is already sorted by length from controller var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand]; var sensorScaleFactor = MyAvatar.sensorToWorldScale; - var tearAwayDistance = TEAR_AWAY_DISTANCE * sensorScaleFactor; + var nearGrabDistance = NEAR_GRAB_DISTANCE * sensorScaleFactor; var nearGrabRadius = NEAR_GRAB_RADIUS * sensorScaleFactor; for (var i = 0; i < nearbyEntityProperties.length; i++) { var props = nearbyEntityProperties[i]; var grabPosition = controllerData.controllerLocations[this.hand].position; // Is offset from hand position. var dist = distanceBetweenPointAndEntityBoundingBox(grabPosition, props); var distance = Vec3.distance(grabPosition, props.position); - if ((dist > tearAwayDistance) || + if ((dist > nearGrabDistance) || (distance > nearGrabRadius)) { // Only smallish entities can be near grabbed. continue; } diff --git a/scripts/system/libraries/controllerDispatcherUtils.js b/scripts/system/libraries/controllerDispatcherUtils.js index e9d5255d28..ab2801087e 100644 --- a/scripts/system/libraries/controllerDispatcherUtils.js +++ b/scripts/system/libraries/controllerDispatcherUtils.js @@ -53,6 +53,7 @@ TEAR_AWAY_DISTANCE:true, TEAR_AWAY_COUNT:true, TEAR_AWAY_CHECK_TIME:true, + NEAR_GRAB_DISTANCE: true, distanceBetweenPointAndEntityBoundingBox:true, entityIsEquipped:true, entityIsFarGrabbedByOther:true, @@ -99,6 +100,10 @@ NEAR_GRAB_RADIUS = 1.0; TEAR_AWAY_DISTANCE = 0.15; // ungrab an entity if its bounding-box moves this far from the hand TEAR_AWAY_COUNT = 2; // multiply by TEAR_AWAY_CHECK_TIME to know how long the item must be away TEAR_AWAY_CHECK_TIME = 0.15; // seconds, duration between checks + +NEAR_GRAB_DISTANCE = 0.14; // Grab an entity if its bounding box is within this distance. +// Smaller than TEAR_AWAY_DISTANCE for hysteresis. + DISPATCHER_HOVERING_LIST = "dispactherHoveringList"; DISPATCHER_HOVERING_STYLE = { isOutlineSmooth: true, From 29c268df5ae0e4c9bf03543d9b96047da74f8490 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 24 Nov 2018 11:38:54 +1300 Subject: [PATCH 060/109] Remove extraneous grab entity haptic pulses --- .../controllers/controllerModules/farParentGrabEntity.js | 6 ------ .../controllerModules/nearActionGrabEntity.js | 7 ------- .../controllerModules/nearParentGrabEntity.js | 9 --------- 3 files changed, 22 deletions(-) diff --git a/scripts/system/controllers/controllerModules/farParentGrabEntity.js b/scripts/system/controllers/controllerModules/farParentGrabEntity.js index f85869aa7f..4b85c6d046 100644 --- a/scripts/system/controllers/controllerModules/farParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farParentGrabEntity.js @@ -256,7 +256,6 @@ Script.include("/~/system/libraries/controllers.js"); }; this.endFarParentGrab = function (controllerData) { - this.hapticTargetID = null; // var endProps = controllerData.nearbyEntityPropertiesByID[this.targetEntityID]; var endProps = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES); if (this.thisFarGrabJointIsParent(endProps)) { @@ -410,11 +409,6 @@ Script.include("/~/system/libraries/controllers.js"); if (targetEntity) { var gtProps = Entities.getEntityProperties(targetEntity, DISPATCHER_PROPERTIES); if (entityIsGrabbable(gtProps)) { - // give haptic feedback - if (gtProps.id !== this.hapticTargetID) { - Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); - this.hapticTargetID = gtProps.id; - } // if we've attempted to grab a child, roll up to the root of the tree var groupRootProps = findGroupParent(controllerData, gtProps); if (entityIsGrabbable(groupRootProps)) { diff --git a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js index 5ced6080a2..1d1f89e2c7 100644 --- a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js @@ -24,7 +24,6 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); this.hand = hand; this.targetEntityID = null; this.actionID = null; // action this script created... - this.hapticTargetID = null; this.parameters = makeDispatcherModuleParameters( 500, @@ -171,10 +170,6 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); break; } if (entityIsGrabbable(props) || entityIsCloneable(props)) { - if (props.id !== this.hapticTargetID) { - Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); - this.hapticTargetID = props.id; - } if (!entityIsCloneable(props)) { // if we've attempted to grab a non-cloneable child, roll up to the root of the tree var groupRootProps = findGroupParent(controllerData, props); @@ -206,7 +201,6 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); return makeRunningValues(true, [this.targetEntityID], []); } } else { - this.hapticTargetID = null; return makeRunningValues(false, [], []); } }; @@ -216,7 +210,6 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); if (controllerData.triggerClicks[this.hand] < TRIGGER_OFF_VALUE && controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) { this.endNearGrabAction(); - this.hapticTargetID = null; return makeRunningValues(false, [], []); } diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index db10fff69a..3be6f602c2 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -32,7 +32,6 @@ Script.include("/~/system/libraries/controllers.js"); this.previousParentID = {}; this.previousParentJointIndex = {}; this.previouslyUnhooked = {}; - this.hapticTargetID = null; this.lastUnequipCheckTime = 0; this.autoUnequipCounter = 0; this.lastUnexpectedChildrenCheckTime = 0; @@ -138,7 +137,6 @@ Script.include("/~/system/libraries/controllers.js"); }; this.endNearParentingGrabEntity = function (controllerData) { - this.hapticTargetID = null; var props = controllerData.nearbyEntityPropertiesByID[this.targetEntityID]; if (this.thisHandIsParent(props) && !this.robbed) { Entities.editEntity(this.targetEntityID, { @@ -248,11 +246,6 @@ Script.include("/~/system/libraries/controllers.js"); continue; } if (entityIsGrabbable(props) || entityIsCloneable(props)) { - // give haptic feedback - if (props.id !== this.hapticTargetID) { - Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); - this.hapticTargetID = props.id; - } if (!entityIsCloneable(props)) { // if we've attempted to grab a non-cloneable child, roll up to the root of the tree var groupRootProps = findGroupParent(controllerData, props); @@ -295,7 +288,6 @@ Script.include("/~/system/libraries/controllers.js"); unhighlightTargetEntity(this.highlightedEntity); this.highlightedEntity = null; } - this.hapticTargetID = null; this.robbed = false; return makeRunningValues(false, [], []); } @@ -316,7 +308,6 @@ Script.include("/~/system/libraries/controllers.js"); this.highlightedEntity = null; this.grabbing = false; this.targetEntityID = null; - this.hapticTargetID = null; this.robbed = false; return makeRunningValues(false, [], []); } From f2abf8e398a733fbe804c1168b6011cf5095abbc Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 24 Nov 2018 11:43:05 +1300 Subject: [PATCH 061/109] Debounce haptic pulses at start of near parent grab --- .../controllerModules/farParentGrabEntity.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/system/controllers/controllerModules/farParentGrabEntity.js b/scripts/system/controllers/controllerModules/farParentGrabEntity.js index 4b85c6d046..230c4f06db 100644 --- a/scripts/system/controllers/controllerModules/farParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farParentGrabEntity.js @@ -61,6 +61,8 @@ Script.include("/~/system/libraries/controllers.js"); this.reticleMinY = MARGIN; this.reticleMaxY = 0; this.lastUnexpectedChildrenCheckTime = 0; + this.endedGrab = 0; + this.MIN_HAPTIC_PULSE_INTERVAL = 500; // ms var FAR_GRAB_JOINTS = [65527, 65528]; // FARGRAB_LEFTHAND_INDEX, FARGRAB_RIGHTHAND_INDEX @@ -144,7 +146,12 @@ Script.include("/~/system/libraries/controllers.js"); // compute the mass for the purpose of energy and how quickly to move object this.mass = this.getMass(grabbedProperties.dimensions, grabbedProperties.density); - Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); + // Debounce haptic pules. Can occur as near grab controller module vacillates between being ready or not due to + // changing positions and floating point rounding. + if (Date.now() - this.endedGrab > this.MIN_HAPTIC_PULSE_INTERVAL) { + Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); + } + unhighlightTargetEntity(this.targetEntityID); var message = { hand: this.hand, @@ -256,6 +263,7 @@ Script.include("/~/system/libraries/controllers.js"); }; this.endFarParentGrab = function (controllerData) { + this.endedGrab = Date.now(); // var endProps = controllerData.nearbyEntityPropertiesByID[this.targetEntityID]; var endProps = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES); if (this.thisFarGrabJointIsParent(endProps)) { From c96cd422e186180dde2b2ce95e4e2059ad38ad66 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 24 Nov 2018 11:58:40 +1300 Subject: [PATCH 062/109] Fix near parent grab tear away calc for avatar scale --- .../controllers/controllerModules/nearParentGrabEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index 3be6f602c2..433ad9ef53 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -171,7 +171,7 @@ Script.include("/~/system/libraries/controllers.js"); var controllerIndex = this.hand === LEFT_HAND ? Controller.Standard.LeftHand : Controller.Standard.RightHand; var controllerGrabOffset = getGrabPointSphereOffset(controllerIndex, true); - controllerGrabOffset = Vec3.multiply(-1, controllerGrabOffset); + controllerGrabOffset = Vec3.multiply(-MyAvatar.sensorToWorldScale, controllerGrabOffset); var distance = distanceBetweenEntityLocalPositionAndBoundingBox(props, controllerGrabOffset); if (distance > tearAwayDistance) { this.autoUnequipCounter++; From b3f646e9dc1fe3833e99325545ad1cb710498b80 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Sat, 24 Nov 2018 09:44:46 -0800 Subject: [PATCH 063/109] Updated to v1.1 --- tools/nitpick/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index e325be1f40..ce65fec64f 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -24,7 +24,7 @@ Nitpick is built as part of the High Fidelity build. 1. Check "Create SFX archive 1. Enter installer name (i.e. `nitpick-installer-v1.0.exe`) 1. Click "OK" -1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe: aws s3 cp nitpick-installer-v1.0.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.exe +1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.1.exe: aws s3 cp nitpick-installer-v1.0.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.exe #### Mac These steps assume the hifi repository has been cloned to `~/hifi`. 1. (First time) install create-dmg: @@ -49,7 +49,7 @@ These steps assume the hifi repository has been cloned to `~/hifi`. 1. Leave region name and ouput format as default [None] 1. Install the latest release of Boto3 via pip: `pip install boto3` -1. Download the installer by browsing to [here]() +1. Download the installer by browsing to [here]() 1. Double click on the installer and install to a convenient location ![](./setup_7z.PNG) @@ -69,7 +69,7 @@ $ python3 get-pip.py --user 1. Enter the secret key 1. Leave region name and ouput format as default [None] 1. Install the latest release of Boto3 via pip: pip3 install boto3 -1. Download the installer by browsing to [here](). +1. Download the installer by browsing to [here](). 1. Double-click on the downloaded image to mount it 1. Create a folder for the nitpick files (e.g. ~/nitpick) 1. Copy the downloaded files to the folder From f62fd97f09a7be1fa52984da8bb01f7865039ee9 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Sat, 24 Nov 2018 09:49:13 -0800 Subject: [PATCH 064/109] Updated to v1.1 --- tools/nitpick/README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index ce65fec64f..78b4866880 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -22,9 +22,9 @@ Nitpick is built as part of the High Fidelity build. 1. Select all, right-click and select 7-Zip->Add to archive... 1. Set Archive format to 7z 1. Check "Create SFX archive -1. Enter installer name (i.e. `nitpick-installer-v1.0.exe`) +1. Enter installer name (i.e. `nitpick-installer-v1.1.exe`) 1. Click "OK" -1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.1.exe: aws s3 cp nitpick-installer-v1.0.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.exe +1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.1.exe: aws s3 cp nitpick-installer-v1.1.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.exe #### Mac These steps assume the hifi repository has been cloned to `~/hifi`. 1. (First time) install create-dmg: @@ -39,7 +39,7 @@ These steps assume the hifi repository has been cloned to `~/hifi`. 1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.1.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.dmg` ### Installation #### Windows -1. (First time) download and install vc_redist.x64.exe (available at https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe) +1. (First time) download and install vc_redist.x64.exe (available at https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.1.exe) 1. (First time) download and install Python 3 from https://hifi-qa.s3.amazonaws.com/nitpick/Windows/python-3.7.0-amd64.exe (also located at https://www.python.org/downloads/) 1. After installation - create an environment variable called PYTHON_PATH and set it to the folder containing the Python executable. 1. (First time) download and install AWS CLI from https://hifi-qa.s3.amazonaws.com/nitpick/Windows/AWSCLI64PY3.msi (also available at https://aws.amazon.com/cli/ @@ -72,8 +72,9 @@ $ python3 get-pip.py --user 1. Download the installer by browsing to [here](). 1. Double-click on the downloaded image to mount it 1. Create a folder for the nitpick files (e.g. ~/nitpick) + If this folder exists then delete all it's contents. 1. Copy the downloaded files to the folder - `cp -r /Volumes/nitpick-installer-v1.0/* .` + `cp -r /Volumes/nitpick-installer-v1.1/* .` 1. __To run nitpick, cd to the folder that you copied to and run `./nitpick`__ #Use From bbbc358ccbfa31668ad2249f299f4e4326a4e850 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Sat, 24 Nov 2018 20:31:19 -0800 Subject: [PATCH 065/109] Restore AppData folder on Mac --- tools/nitpick/src/TestRunner.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/nitpick/src/TestRunner.cpp b/tools/nitpick/src/TestRunner.cpp index 9549dedb91..30740bd28a 100644 --- a/tools/nitpick/src/TestRunner.cpp +++ b/tools/nitpick/src/TestRunner.cpp @@ -582,15 +582,11 @@ void TestRunner::addBuildNumberToResults(QString zippedFolderName) { } void TestRunner::restoreHighFidelityAppDataFolder() { -#ifdef Q_OS_WIN _appDataFolder.removeRecursively(); if (_savedAppDataFolder != QDir()) { _appDataFolder.rename(_savedAppDataFolder.path(), _appDataFolder.path()); } -#elif defined Q_OS_MAC - // TODO: find Mac equivalent of AppData -#endif } // Copies a folder recursively From 26319e6d6fbd04e4e3ec5f3163b574601ded6556 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Sat, 24 Nov 2018 20:37:21 -0800 Subject: [PATCH 066/109] Remove all disk images --- tools/nitpick/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index 78b4866880..bdea4eb059 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -34,7 +34,7 @@ These steps assume the hifi repository has been cloned to `~/hifi`. `cp ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib .` 1. Change the loader instruction to find the dynamic library locally `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib libquazip5.1.dylib nitpick` -1. Delete any existing installer: `rm nitpick.dmg` +1. Delete any existing disk images: `rm *.dmg` 1. Create installer (note final period): `create-dmg --volname nitpick-installer-v1.1 nitpick-installer-v1.1.dmg .` 1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.1.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.dmg` ### Installation From e173b2968739e50e5ae7569b2a04ee283d6deebc Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Sat, 24 Nov 2018 20:43:13 -0800 Subject: [PATCH 067/109] Added warning --- tools/nitpick/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index bdea4eb059..ae8821c6be 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -36,6 +36,7 @@ These steps assume the hifi repository has been cloned to `~/hifi`. `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib libquazip5.1.dylib nitpick` 1. Delete any existing disk images: `rm *.dmg` 1. Create installer (note final period): `create-dmg --volname nitpick-installer-v1.1 nitpick-installer-v1.1.dmg .` + Make sure to wait for completion. 1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.1.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.dmg` ### Installation #### Windows From 6313ab8ed7d610dd269a45cd03589f1eb0d13f19 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Sun, 25 Nov 2018 20:10:01 -0800 Subject: [PATCH 068/109] Working on possible crash on Mac. --- tools/nitpick/src/Downloader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/nitpick/src/Downloader.cpp b/tools/nitpick/src/Downloader.cpp index de768398b0..3256e79601 100644 --- a/tools/nitpick/src/Downloader.cpp +++ b/tools/nitpick/src/Downloader.cpp @@ -12,12 +12,12 @@ #include Downloader::Downloader(QUrl fileURL, QObject *parent) : QObject(parent) { + _networkAccessManager.get(QNetworkRequest(fileURL)); + connect( &_networkAccessManager, SIGNAL (finished(QNetworkReply*)), this, SLOT (fileDownloaded(QNetworkReply*)) ); - - _networkAccessManager.get(QNetworkRequest(fileURL)); } void Downloader::fileDownloaded(QNetworkReply* reply) { From 2913d4f9841fd6ebd5f32767598b41d9b1700952 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 26 Nov 2018 08:25:07 -0800 Subject: [PATCH 069/109] Removed baaaaaad file. --- .../domain-server/AccountInfo.bin | Bin 1450 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tools/nitpick/AppDataHighFidelity/domain-server/AccountInfo.bin diff --git a/tools/nitpick/AppDataHighFidelity/domain-server/AccountInfo.bin b/tools/nitpick/AppDataHighFidelity/domain-server/AccountInfo.bin deleted file mode 100644 index 645e34895e5c2ae38571d19a60c21df84c880b12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1450 zcmaiuX*d)J9EbliWDyXqirx)88es;s{=7|CAKh> zBjk=;YebG7Q;j3-rehG<dt}>pTS1HE7EiYrSuWTvl;>I*HM&!jW zQF^;JC>UK&QL*QLl`~)>=6uz{euwwhQzNZxEK;lngD; zU}IlZ50Qdg_G#^+%-96}TyTChjkG3Sd77^{k@e0kQ(4Vxx>j52LE7599bdxF^k7DC zL5aEuJBJc_m)W{@eN^tj=SuDz_M?2p)e*;LO>w4!y3seywe_dxv279TT=%hO`%1;5 z{QQ#%I0aWS>(pnJ*3z}%xqBAZ`3?8BF4)LzUfSWZr(J$tuRjrbnu*w0=UIH%uL%u8 zTJ24?;^qZs|KOw=lD|QUx^(Nu{G?E%1OgDq1O$*eFUT-cx9jFeelbfGK9Q;n+!Q=1 zyksC@q2k6^sd9bIQJz);%J95I*2a;-KKXRp)YhJIGT%UBQQ?v73k+sD(dFr<+YJ@Z z&X)hCsJeToSbv17bEHO*+b`&D>^0#vN69K{$S^HZTcC%xXyLLJD_qe%QMX8>S#Qp@FLf+ z$qKKOuD6C(v}Rq&Rm@Sn!?W#d@h}#UksJ=pkd9>2H6{`|JOjp1VFxw23<)Qv80!#H zT$J0or(#;Cv?!D>lvA(kyVx@Mruf$Eg+ZJpt+<7UkaYKOU#9BuN_Q!9G3Ub5K6E51 zi;hcwDzrX!;MeCSEstp$sWH}SdYO%&{m!qp61Q6a@E-F?-n#0rp1_BnuOjUkXRG?H zVaRw(ToHHKP~`iFnm8+U$bl_TX)M)$sK(Oic=w@YHtc>V-$HVdOl%jOAOv=MemJ~_ z=>3~m7c6#ey&p#ky^*0^_2Mep!pfJYULMd?LW@nD&CpK#g3eDS$YX~@<3DCxdY?pP z2k$-^cLa5?GpQ8fpx%qFpMh~w+*RRSqWwZc3)4Ri4vk#5HwOsYT!ua+Uk<=oRf zEt__XDpen1TCzwTnbhn}QWBU!IY~P)v9tu|wbgL*(zdz`rnV<)KIack!@U0#8OdQI z343_VBs0Ct9k!8@?=|YZ<>E7v&$s(eZa@W7-WM1pUd6BR2auc!{$8zgVqK7hZ}ZdE zuZx=Fbq@A_!LW%^>de**+TrNI7M$x)$MczObLpX%@9R1n7Rn~8KYDx3`1%FPVWC3u zK@D`WW0gM3-rR1q2-`a3fa{$Yi?2J5&3FNvYH}2YGpJ< z?$-5)<(3e)O-1K7CaKDx5MG}rYGh10w3pSnr*!4hzQ2PzQ20s_DSC}0U@fCoAR00n*mQ!oQ_pa32$ Qfed)SeP24@fdT>l0D=~Uga7~l From 48fabf51f2847359320b4e9d2ba4ac6f58ccd4ac Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 26 Nov 2018 08:54:09 -0800 Subject: [PATCH 070/109] Corrected Linux compilation error. --- tools/nitpick/src/TestRunner.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/nitpick/src/TestRunner.cpp b/tools/nitpick/src/TestRunner.cpp index 30740bd28a..65358a0c3d 100644 --- a/tools/nitpick/src/TestRunner.cpp +++ b/tools/nitpick/src/TestRunner.cpp @@ -332,12 +332,11 @@ void TestRunner::verifyInstallationSucceeded() { } void TestRunner::saveExistingHighFidelityAppDataFolder() { -#ifdef Q_OS_WIN QString dataDirectory{ "NOT FOUND" }; - +#ifdef Q_OS_WIN dataDirectory = qgetenv("USERPROFILE") + "\\AppData\\Roaming"; #elif defined Q_OS_MAC - QString dataDirectory{ QDir::homePath() + "/Library/Application Support" }; + dataDirectory{ QDir::homePath() + "/Library/Application Support" }; #endif if (_runLatest->isChecked()) { _appDataFolder = dataDirectory + "/High Fidelity"; From a6e203e3e5a58f31e12a57827dd0575dfe8ba0ee Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 26 Nov 2018 10:55:42 -0800 Subject: [PATCH 071/109] Fix draggable inputs not being tabbable --- scripts/system/html/css/edit-style.css | 11 ++++---- scripts/system/html/js/draggableNumber.js | 32 ++++++++++++++++------ scripts/system/html/js/entityProperties.js | 2 +- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 5b5c9e057c..415d8e567f 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -916,7 +916,7 @@ div.refresh input[type="button"] { } .draggable-number div { height: 28px; - width: 92px; + width: 124px; } .draggable-number.text { display: inline-block; @@ -929,6 +929,7 @@ div.refresh input[type="button"] { height: 28px; width: 100%; line-height: 2; + box-sizing: border-box; } .draggable-number.text:hover { cursor: ew-resize; @@ -944,12 +945,12 @@ div.refresh input[type="button"] { cursor: default; } .draggable-number.left-arrow { - top: -5px; + top: 3px; left: 0px; transform: rotate(180deg); } .draggable-number.right-arrow { - top: -5px; + top: 3px; right: 0px; } .draggable-number input[type=number] { @@ -971,14 +972,14 @@ div.refresh input[type="button"] { left: 12px; } .draggable-number.fstuple + .draggable-number.fstuple { - padding-left: 28px; + margin-left: 28px; } .draggable-number.fstuple input { right: -10px; } .draggable-number.fstuple .sublabel { position: absolute; - top: 0; + top: 6px; left: -16px; font-family: FiraSans-SemiBold; font-size: 15px; diff --git a/scripts/system/html/js/draggableNumber.js b/scripts/system/html/js/draggableNumber.js index c08cac2ce4..951b123e67 100644 --- a/scripts/system/html/js/draggableNumber.js +++ b/scripts/system/html/js/draggableNumber.js @@ -23,6 +23,20 @@ function DraggableNumber(min, max, step, decimals, dragStart, dragEnd) { } DraggableNumber.prototype = { + showInput: function() { + this.elText.style.visibility = "hidden"; + this.elLeftArrow.style.visibility = "hidden"; + this.elRightArrow.style.visibility = "hidden"; + this.elInput.style.opacity = 1; + }, + + hideInput: function() { + this.elText.style.visibility = "visible"; + this.elLeftArrow.style.visibility = "visible"; + this.elRightArrow.style.visibility = "visible"; + this.elInput.style.opacity = 0; + }, + mouseDown: function(event) { if (event.target === this.elText) { this.initialMouseEvent = event; @@ -36,8 +50,8 @@ DraggableNumber.prototype = { if (event.target === this.elText && this.initialMouseEvent) { let dx = event.clientX - this.initialMouseEvent.clientX; if (Math.abs(dx) <= DELTA_X_FOCUS_THRESHOLD) { - this.elInput.style.visibility = "visible"; - this.elText.style.visibility = "hidden"; + this.showInput(); + this.elInput.focus(); } this.initialMouseEvent = null; } @@ -125,9 +139,8 @@ DraggableNumber.prototype = { this.setValue(this.elInput.value); }, - inputBlur: function() { - this.elInput.style.visibility = "hidden"; - this.elText.style.visibility = "visible"; + inputBlur: function(ev) { + this.hideInput(); }, initialize: function() { @@ -171,13 +184,14 @@ DraggableNumber.prototype = { if (this.step !== undefined) { this.elInput.setAttribute("step", this.step); } - this.elInput.style.visibility = "hidden"; + this.elInput.style.opacity = 0; this.elInput.addEventListener("change", this.onInputChange); this.elInput.addEventListener("blur", this.onInputBlur); + this.elInput.addEventListener("focus", this.showInput.bind(this)); - this.elText.appendChild(this.elLeftArrow); - this.elText.appendChild(this.elInput); - this.elText.appendChild(this.elRightArrow); + this.elDiv.appendChild(this.elLeftArrow); + this.elDiv.appendChild(this.elInput); + this.elDiv.appendChild(this.elRightArrow); this.elDiv.appendChild(this.elText); } }; diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 78e3cd4dc8..786df503df 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -2149,7 +2149,7 @@ function createTupleNumberInput(property, subLabel) { propertyData.decimals, dragStartFunction, dragEndFunction); elDraggableNumber.elInput.setAttribute("id", elementID); elDraggableNumber.elDiv.className += " fstuple"; - elDraggableNumber.elText.insertBefore(elLabel, elDraggableNumber.elLeftArrow); + elDraggableNumber.elDiv.insertBefore(elLabel, elDraggableNumber.elLeftArrow); return elDraggableNumber; } From 8df5db4239d9185e91d349d2805c41f28bdf2e9e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 26 Nov 2018 13:26:17 -0800 Subject: [PATCH 072/109] Allow scripts to open SendAsset screen with pre-filled info --- .../commerce/common/sendAsset/SendAsset.qml | 59 ++++++++++++++----- scripts/system/commerce/wallet.js | 5 ++ 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml b/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml index d6378f82ac..2a5211d174 100644 --- a/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml +++ b/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml @@ -39,7 +39,7 @@ Item { property string sendingPubliclyEffectImage; property var http; property var listModelName; - property var keyboardContainer: nil; + property var keyboardContainer; // This object is always used in a popup or full-screen Wallet section. // This MouseArea is used to prevent a user from being @@ -405,7 +405,7 @@ Item { HifiModels.PSFListModel { id: connectionsModel; http: root.http; - listModelName: root.listModelName; + listModelName: root.listModelName || ""; endpoint: "/api/v1/users?filter=connections"; itemsPerPage: 9; listView: connectionsList; @@ -853,7 +853,7 @@ Item { id: sendAssetStep; z: 996; - property string referrer; // either "connections" or "nearby" + property string referrer; // either "connections", "nearby", or "payIn" property string selectedRecipientNodeID; property string selectedRecipientDisplayName; property string selectedRecipientUserName; @@ -931,6 +931,7 @@ Item { height: 35; width: 100; text: "CHANGE"; + visible: sendAssetStep.referrer !== "payIn"; onClicked: { if (sendAssetStep.referrer === "connections") { root.nextActiveView = "chooseRecipientConnection"; @@ -970,6 +971,7 @@ Item { HifiControlsUit.TextField { id: amountTextField; + readOnly: sendAssetStep.referrer === "payIn"; text: root.assetName === "" ? "" : "1"; colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; inputMethodHints: Qt.ImhDigitsOnly; @@ -980,8 +982,8 @@ Item { height: 50; // Style leftPermanentGlyph: hifi.glyphs.hfc; - activeFocusOnPress: true; - activeFocusOnTab: true; + activeFocusOnPress: !amountTextField.readOnly; + activeFocusOnTab: !amountTextField.readOnly; validator: IntValidator { bottom: 0; } @@ -1071,6 +1073,7 @@ Item { TextArea { id: optionalMessage; + readOnly: sendAssetStep.referrer === "payIn"; property int maximumLength: 72; property string previousText: text; placeholderText: "Optional Public Message (" + maximumLength + " character limit)"; @@ -1081,10 +1084,10 @@ Item { // Style background: Rectangle { anchors.fill: parent; - color: root.assetName === "" ? (optionalMessage.activeFocus ? hifi.colors.black : hifi.colors.baseGrayShadow) : - (optionalMessage.activeFocus ? "#EFEFEF" : "#EEEEEE"); - border.width: optionalMessage.activeFocus ? 1 : 0; - border.color: optionalMessage.activeFocus ? hifi.colors.primaryHighlight : hifi.colors.textFieldLightBackground; + color: root.assetName === "" ? (optionalMessage.activeFocus && !optionalMessage.readOnly ? hifi.colors.black : hifi.colors.baseGrayShadow) : + (optionalMessage.activeFocus && !optionalMessage.readOnly ? "#EFEFEF" : "#EEEEEE"); + border.width: optionalMessage.activeFocus && !optionalMessage.readOnly ? 1 : 0; + border.color: optionalMessage.activeFocus && !optionalMessage.readOnly ? hifi.colors.primaryHighlight : hifi.colors.textFieldLightBackground; } color: root.assetName === "" ? hifi.colors.white : hifi.colors.black; textFormat: TextEdit.PlainText; @@ -1205,8 +1208,12 @@ Item { width: 100; text: "CANCEL"; onClicked: { - resetSendAssetData(); - root.nextActiveView = "sendAssetHome"; + if (sendAssetStep.referrer === "payIn") { + sendToScript({method: "closeSendAsset"}); + } else { + resetSendAssetData(); + root.nextActiveView = "sendAssetHome"; + } } } @@ -1236,7 +1243,7 @@ Item { root.isCurrentlySendingAsset = true; amountTextField.focus = false; optionalMessage.focus = false; - if (sendAssetStep.referrer === "connections") { + if (sendAssetStep.referrer === "connections" || sendAssetStep.referrer === "payIn") { Commerce.transferAssetToUsername(sendAssetStep.selectedRecipientUserName, root.assetCertID, parseInt(amountTextField.text), @@ -1364,10 +1371,14 @@ Item { parent.text = hifi.glyphs.close; } onClicked: { - root.nextActiveView = "sendAssetHome"; - resetSendAssetData(); - if (root.assetName !== "") { - sendSignalToParent({method: "closeSendAsset"}); + if (sendAssetStep.referrer === "payIn") { + sendToScript({method: "closeSendAsset"}); + } else { + root.nextActiveView = "sendAssetHome"; + resetSendAssetData(); + if (root.assetName !== "") { + sendSignalToParent({method: "closeSendAsset"}); + } } } } @@ -1866,11 +1877,27 @@ Item { case 'updateSelectedRecipientUsername': sendAssetStep.selectedRecipientUserName = message.userName; break; + case 'updateSendAssetQML': + root.assetName = message.assetName || ""; + root.assetCertID = message.assetCertID || ""; + amountTextField.text = message.amount || 1; + sendAssetStep.referrer = "payIn"; + sendAssetStep.selectedRecipientNodeID = ""; + sendAssetStep.selectedRecipientDisplayName = 'Secure Payment'; + sendAssetStep.selectedRecipientUserName = message.username; + optionalMessage.text = message.message || "No Message Provided"; + + root.nextActiveView = "sendAssetStep"; + break; + case 'inspectionCertificate_resetCert': + // NOP + break; default: console.log('SendAsset: Unrecognized message from wallet.js'); } } signal sendSignalToParent(var msg); + signal sendToScript(var message); // // FUNCTION DEFINITIONS END // diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index 5e0cdbb94b..d5365133b6 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -539,6 +539,9 @@ function fromQml(message) { case 'http.request': // Handled elsewhere, don't log. break; + case 'closeSendAsset': + ui.close(); + break; default: print('wallet.js: Unrecognized message from QML'); } @@ -663,6 +666,7 @@ function uninstallMarketplaceItemTester() { var BUTTON_NAME = "INVENTORY"; var WALLET_QML_SOURCE = "hifi/commerce/wallet/Wallet.qml"; +var SENDASSET_QML_SOURCE = "hifi/commerce/common/sendAsset/SendAsset.qml"; var NOTIFICATION_POLL_TIMEOUT = 300000; var ui; function startup() { @@ -686,6 +690,7 @@ function startup() { buttonName: BUTTON_NAME, sortOrder: 10, home: WALLET_QML_SOURCE, + additionalAppScreens: SENDASSET_QML_SOURCE, onOpened: walletOpened, onClosed: walletClosed, onMessage: fromQml, From 31f7d747c8eb9b35e2f424dfbbef0578b636f436 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 26 Nov 2018 15:48:49 -0800 Subject: [PATCH 073/109] Bugfixes; enable purchase asset from marketplace screen raise --- .../qml/hifi/commerce/checkout/Checkout.qml | 51 +++++-- .../commerce/common/sendAsset/SendAsset.qml | 139 ++++++++++-------- scripts/system/html/js/marketplacesInject.js | 23 +-- scripts/system/marketplaces/marketplaces.js | 6 +- 4 files changed, 124 insertions(+), 95 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index c2a4d47992..6320cd1675 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -19,6 +19,7 @@ import controlsUit 1.0 as HifiControlsUit import "../../../controls" as HifiControls import "../wallet" as HifiWallet import "../common" as HifiCommerceCommon +import "../.." as HifiCommon // references XXX from root context @@ -31,6 +32,7 @@ Rectangle { property bool ownershipStatusReceived: false; property bool balanceReceived: false; property bool availableUpdatesReceived: false; + property bool itemInfoReceived: false; property string baseItemName: ""; property string itemName; property string itemId; @@ -181,11 +183,14 @@ Rectangle { onItemIdChanged: { root.ownershipStatusReceived = false; + root.itemInfoReceived = false; Commerce.alreadyOwned(root.itemId); root.availableUpdatesReceived = false; root.currentUpdatesPage = 1; Commerce.getAvailableUpdates(root.itemId); - itemPreviewImage.source = "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/previews/" + itemId + "/thumbnail/hifi-mp-" + itemId + ".jpg"; + + var MARKETPLACE_API_URL = Account.metaverseServerURL + "/api/v1/marketplace/items/"; + http.request({uri: MARKETPLACE_API_URL + root.itemId}, updateCheckoutQMLFromHTTP); } onItemTypeChanged: { @@ -279,6 +284,7 @@ Rectangle { ownershipStatusReceived = false; balanceReceived = false; availableUpdatesReceived = false; + itemInfoReceived = false; Commerce.getWalletStatus(); } } @@ -355,7 +361,7 @@ Rectangle { Rectangle { id: loading; z: 997; - visible: !root.ownershipStatusReceived || !root.balanceReceived || !root.availableUpdatesReceived; + visible: !root.ownershipStatusReceived || !root.balanceReceived || !root.availableUpdatesReceived || !root.itemInfoReceived; anchors.fill: parent; color: hifi.colors.white; @@ -1063,10 +1069,27 @@ Rectangle { } } } + + + HifiCommon.RootHttpRequest { + id: http; + } // // FUNCTION DEFINITIONS START // + + function updateCheckoutQMLFromHTTP(error, result) { + root.itemInfoReceived = true; + root.itemName = result.data.title; + root.itemPrice = result.data.cost; + root.itemHref = Account.metaverseServerURL + result.data.path; + root.itemAuthor = result.data.creator; + root.itemType = result.data.item_type || "unknown"; + itemPreviewImage.source = result.data.thumbnail_url; + refreshBuyUI(); + } + // // Function Name: fromScript() // @@ -1080,18 +1103,24 @@ Rectangle { // Description: // Called when a message is received from a script. // + function fromScript(message) { switch (message.method) { - case 'updateCheckoutQML': - root.itemId = message.params.itemId; - root.itemName = message.params.itemName.trim(); - root.itemPrice = message.params.itemPrice; - root.itemHref = message.params.itemHref; - root.referrer = message.params.referrer; - root.itemAuthor = message.params.itemAuthor; + case 'updateCheckoutQMLItemID': + if (!message.params.itemId) { + console.log("A message with method 'updateCheckoutQMLItemID' was sent without an itemId!"); + return; + } + + // If we end up following the referrer (i.e. in case the wallet "isn't set up" or the user cancels), + // we want the user to be placed back on the individual item's page - thus we set the + // default of the referrer in this case to "itemPage". + root.referrer = message.params.referrer || "itemPage"; root.itemEdition = message.params.itemEdition || -1; - root.itemType = message.params.itemType || "unknown"; - refreshBuyUI(); + root.itemId = message.params.itemId; + break; + case 'http.response': + http.handleHttpResponse(message); break; default: console.log('Checkout.qml: Unrecognized message from marketplaces.js'); diff --git a/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml b/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml index 2a5211d174..a719ae6432 100644 --- a/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml +++ b/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml @@ -56,7 +56,7 @@ Item { // Background Rectangle { z: 1; - visible: root.assetName !== "" && sendAssetStep.visible; + visible: root.assetCertID !== "" && sendAssetStep.referrer !== "payIn" && sendAssetStep.visible; anchors.top: parent.top; anchors.topMargin: root.parentAppTitleBarHeight; anchors.left: parent.left; @@ -84,7 +84,6 @@ Item { if (sendPubliclyCheckbox.checked && sendAssetStep.referrer === "nearby") { sendSignalToParent({ method: 'sendAsset_sendPublicly', - assetName: root.assetName, recipient: sendAssetStep.selectedRecipientNodeID, amount: parseInt(amountTextField.text), effectImage: root.sendingPubliclyEffectImage @@ -155,7 +154,7 @@ Item { Item { id: userInfoContainer; - visible: root.assetName === ""; + visible: root.assetCertID === ""; anchors.top: parent.top; anchors.left: parent.left; anchors.right: parent.right; @@ -251,7 +250,7 @@ Item { LinearGradient { anchors.fill: parent; - visible: root.assetName === ""; + visible: root.assetCertID === ""; start: Qt.point(0, 0); end: Qt.point(0, height); gradient: Gradient { @@ -262,7 +261,7 @@ Item { RalewaySemiBold { id: sendAssetText; - text: root.assetName === "" ? "Send Money To:" : "Gift \"" + root.assetName + "\" To:"; + text: root.assetCertID === "" ? "Send Money To:" : "Gift \"" + root.assetName + "\" To:"; // Anchors anchors.top: parent.top; anchors.topMargin: 26; @@ -441,7 +440,7 @@ Item { HiFiGlyphs { id: closeGlyphButton_connections; text: hifi.glyphs.close; - color: root.assetName === "" ? hifi.colors.lightGrayText : hifi.colors.baseGray; + color: root.assetCertID === "" ? hifi.colors.lightGrayText : hifi.colors.baseGray; size: 26; anchors.top: parent.top; anchors.topMargin: 10; @@ -684,7 +683,7 @@ Item { HiFiGlyphs { id: closeGlyphButton_nearby; text: hifi.glyphs.close; - color: root.assetName === "" ? hifi.colors.lightGrayText : hifi.colors.baseGray; + color: root.assetCertID === "" ? hifi.colors.lightGrayText : hifi.colors.baseGray; size: 26; anchors.top: parent.top; anchors.topMargin: 10; @@ -760,7 +759,7 @@ Item { RalewaySemiBold { id: sendToText; - text: root.assetName === "" ? "Send to:" : "Gift to:"; + text: root.assetCertID === "" ? "Send to:" : "Gift to:"; // Anchors anchors.top: parent.top; anchors.topMargin: 36; @@ -865,7 +864,8 @@ Item { RalewaySemiBold { id: sendAssetText_sendAssetStep; - text: root.assetName === "" ? "Send Money" : "Gift \"" + root.assetName + "\""; + text: sendAssetStep.referrer === "payIn" && root.assetCertID !== "" ? "Send Item:" : + (root.assetCertID === "" ? "Send Money To:" : "Gift \"" + root.assetName + "\" To:"); // Anchors anchors.top: parent.top; anchors.topMargin: 26; @@ -878,7 +878,7 @@ Item { // Text size size: 22; // Style - color: root.assetName === "" ? hifi.colors.white : hifi.colors.black; + color: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colors.white : hifi.colors.black; } Item { @@ -893,7 +893,7 @@ Item { RalewaySemiBold { id: sendToText_sendAssetStep; - text: root.assetName === "" ? "Send to:" : "Gift to:"; + text: (root.assetCertID === "" || sendAssetStep.referrer === "payIn") ? "Send to:" : "Gift to:"; // Anchors anchors.top: parent.top; anchors.left: parent.left; @@ -902,7 +902,7 @@ Item { // Text size size: 18; // Style - color: root.assetName === "" ? hifi.colors.white : hifi.colors.black; + color: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colors.white : hifi.colors.black; verticalAlignment: Text.AlignVCenter; } @@ -912,7 +912,7 @@ Item { anchors.right: changeButton.left; anchors.rightMargin: 12; height: parent.height; - textColor: root.assetName === "" ? hifi.colors.white : hifi.colors.black; + textColor: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colors.white : hifi.colors.black; displayName: sendAssetStep.selectedRecipientDisplayName; userName: sendAssetStep.selectedRecipientUserName; @@ -924,7 +924,7 @@ Item { // "CHANGE" button HifiControlsUit.Button { id: changeButton; - color: root.assetName === "" ? hifi.buttons.none : hifi.buttons.white; + color: root.assetCertID === "" ? hifi.buttons.none : hifi.buttons.white; colorScheme: hifi.colorSchemes.dark; anchors.right: parent.right; anchors.verticalCenter: parent.verticalCenter; @@ -945,7 +945,7 @@ Item { Item { id: amountContainer; - visible: root.assetName === ""; + visible: root.assetCertID === ""; anchors.top: sendToContainer.bottom; anchors.topMargin: 2; anchors.left: parent.left; @@ -972,8 +972,8 @@ Item { HifiControlsUit.TextField { id: amountTextField; readOnly: sendAssetStep.referrer === "payIn"; - text: root.assetName === "" ? "" : "1"; - colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; + text: root.assetCertID === "" ? "" : "1"; + colorScheme: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; inputMethodHints: Qt.ImhDigitsOnly; // Anchors anchors.verticalCenter: parent.verticalCenter; @@ -1084,12 +1084,13 @@ Item { // Style background: Rectangle { anchors.fill: parent; - color: root.assetName === "" ? (optionalMessage.activeFocus && !optionalMessage.readOnly ? hifi.colors.black : hifi.colors.baseGrayShadow) : - (optionalMessage.activeFocus && !optionalMessage.readOnly ? "#EFEFEF" : "#EEEEEE"); + color: (root.assetCertID === "" || sendAssetStep.referrer === "payIn") ? + (optionalMessage.activeFocus && !optionalMessage.readOnly ? hifi.colors.black : hifi.colors.baseGrayShadow) : + (optionalMessage.activeFocus ? "#EFEFEF" : "#EEEEEE"); border.width: optionalMessage.activeFocus && !optionalMessage.readOnly ? 1 : 0; border.color: optionalMessage.activeFocus && !optionalMessage.readOnly ? hifi.colors.primaryHighlight : hifi.colors.textFieldLightBackground; } - color: root.assetName === "" ? hifi.colors.white : hifi.colors.black; + color: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colors.white : hifi.colors.black; textFormat: TextEdit.PlainText; wrapMode: TextEdit.Wrap; activeFocusOnPress: true; @@ -1125,7 +1126,8 @@ Item { // Text size size: 16; // Style - color: optionalMessage.text.length === optionalMessage.maximumLength ? "#ea89a5" : (root.assetName === "" ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight); + color: optionalMessage.text.length === optionalMessage.maximumLength ? "#ea89a5" : + (root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight); verticalAlignment: Text.AlignTop; horizontalAlignment: Text.AlignRight; } @@ -1170,7 +1172,7 @@ Item { parent.color = hifi.colors.blueAccent; } onClicked: { - lightboxPopup.titleText = (root.assetName === "" ? "Send Effect" : "Gift Effect"); + lightboxPopup.titleText = (root.assetCertID === "" ? "Send Effect" : "Gift Effect"); lightboxPopup.bodyImageSource = "sendAsset/images/send-money-effect-sm.jpg"; // Path relative to CommerceLightbox.qml lightboxPopup.bodyText = "Enabling this option will create a particle effect between you and " + "your recipient that is visible to everyone nearby."; @@ -1199,7 +1201,7 @@ Item { // "CANCEL" button HifiControlsUit.Button { id: cancelButton_sendAssetStep; - color: root.assetName === "" ? hifi.buttons.noneBorderlessWhite : hifi.buttons.noneBorderlessGray; + color: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.buttons.noneBorderlessWhite : hifi.buttons.noneBorderlessGray; colorScheme: hifi.colorSchemes.dark; anchors.right: sendButton.left; anchors.rightMargin: 24; @@ -1221,7 +1223,7 @@ Item { HifiControlsUit.Button { id: sendButton; color: hifi.buttons.blue; - colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; + colorScheme: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; anchors.right: parent.right; anchors.rightMargin: 0; anchors.verticalCenter: parent.verticalCenter; @@ -1229,11 +1231,11 @@ Item { width: 100; text: "SUBMIT"; onClicked: { - if (root.assetName === "" && parseInt(amountTextField.text) > parseInt(balanceText.text)) { + if (root.assetCertID === "" && parseInt(amountTextField.text) > parseInt(balanceText.text)) { amountTextField.focus = true; amountTextField.error = true; amountTextFieldError.text = "amount exceeds available funds"; - } else if (root.assetName === "" && (amountTextField.text === "" || parseInt(amountTextField.text) < 1)) { + } else if (root.assetCertID === "" && (amountTextField.text === "" || parseInt(amountTextField.text) < 1)) { amountTextField.focus = true; amountTextField.error = true; amountTextFieldError.text = "invalid amount"; @@ -1324,18 +1326,18 @@ Item { Rectangle { anchors.top: parent.top; - anchors.topMargin: root.assetName === "" ? 15 : 125; + anchors.topMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 125; anchors.left: parent.left; - anchors.leftMargin: root.assetName === "" ? 15 : 50; + anchors.leftMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 50; anchors.right: parent.right; - anchors.rightMargin: root.assetName === "" ? 15 : 50; + anchors.rightMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 50; anchors.bottom: parent.bottom; - anchors.bottomMargin: root.assetName === "" ? 15 : 125; + anchors.bottomMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 125; color: "#FFFFFF"; RalewaySemiBold { id: paymentSentText; - text: root.assetName === "" ? "Payment Sent" : "Gift Sent"; + text: root.assetCertID === "" ? "Payment Sent" : (sendAssetStep.referrer === "payIn" ? "Item Sent" : "Gift Sent"); // Anchors anchors.top: parent.top; anchors.topMargin: 26; @@ -1353,7 +1355,7 @@ Item { HiFiGlyphs { id: closeGlyphButton_paymentSuccess; - visible: root.assetName === ""; + visible: root.assetCertID === "" && sendAssetStep.referrer !== "payIn"; text: hifi.glyphs.close; color: hifi.colors.lightGrayText; size: 26; @@ -1427,7 +1429,7 @@ Item { Item { id: giftContainer_paymentSuccess; - visible: root.assetName !== ""; + visible: root.assetCertID !== "" && sendAssetStep.referrer !== "payIn"; anchors.top: sendToContainer_paymentSuccess.bottom; anchors.topMargin: 8; anchors.left: parent.left; @@ -1469,7 +1471,7 @@ Item { Item { id: amountContainer_paymentSuccess; - visible: root.assetName === ""; + visible: root.assetCertID === ""; anchors.top: sendToContainer_paymentSuccess.bottom; anchors.topMargin: 16; anchors.left: parent.left; @@ -1524,7 +1526,7 @@ Item { RalewaySemiBold { id: optionalMessage_paymentSuccess; - visible: root.assetName === ""; + visible: root.assetCertID === "" || sendAssetStep.referrer === "payIn"; text: optionalMessage.text; // Anchors anchors.top: amountContainer_paymentSuccess.visible ? amountContainer_paymentSuccess.bottom : sendToContainer_paymentSuccess.bottom; @@ -1546,18 +1548,22 @@ Item { HifiControlsUit.Button { id: closeButton; color: hifi.buttons.blue; - colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; + colorScheme: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom; - anchors.bottomMargin: root.assetName === "" ? 80 : 30; + anchors.bottomMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 80 : 30; height: 50; width: 120; text: "Close"; onClicked: { - root.nextActiveView = "sendAssetHome"; - resetSendAssetData(); - if (root.assetName !== "") { - sendSignalToParent({method: "closeSendAsset"}); + if (sendAssetStep.referrer === "payIn") { + sendToScript({method: "closeSendAsset"}); + } else { + root.nextActiveView = "sendAssetHome"; + resetSendAssetData(); + if (root.assetName !== "") { + sendSignalToParent({method: "closeSendAsset"}); + } } } } @@ -1585,18 +1591,18 @@ Item { Rectangle { anchors.top: parent.top; - anchors.topMargin: root.assetName === "" ? 15 : 150; + anchors.topMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 150; anchors.left: parent.left; - anchors.leftMargin: root.assetName === "" ? 15 : 50; + anchors.leftMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 50; anchors.right: parent.right; - anchors.rightMargin: root.assetName === "" ? 15 : 50; + anchors.rightMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 50; anchors.bottom: parent.bottom; - anchors.bottomMargin: root.assetName === "" ? 15 : 300; + anchors.bottomMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 300; color: "#FFFFFF"; RalewaySemiBold { id: paymentFailureText; - text: root.assetName === "" ? "Payment Failed" : "Failed"; + text: root.assetCertID === "" && sendAssetStep.referrer !== "payIn" ? "Payment Failed" : "Failed"; // Anchors anchors.top: parent.top; anchors.topMargin: 26; @@ -1614,7 +1620,7 @@ Item { HiFiGlyphs { id: closeGlyphButton_paymentFailure; - visible: root.assetName === ""; + visible: root.assetCertID === "" && sendAssetStep.referrer !== "payIn"; text: hifi.glyphs.close; color: hifi.colors.lightGrayText; size: 26; @@ -1643,7 +1649,8 @@ Item { RalewaySemiBold { id: paymentFailureDetailText; - text: "The recipient you specified was unable to receive your " + (root.assetName === "" ? "payment." : "gift."); + text: "The recipient you specified was unable to receive your " + + (root.assetCertID === "" ? "payment." : (sendAssetStep.referrer === "payIn" ? "item." : "gift.")); anchors.top: paymentFailureText.bottom; anchors.topMargin: 20; anchors.left: parent.left; @@ -1661,7 +1668,7 @@ Item { Item { id: sendToContainer_paymentFailure; - visible: root.assetName === ""; + visible: root.assetCertID === "" || sendAssetStep.referrer === "payIn"; anchors.top: paymentFailureDetailText.bottom; anchors.topMargin: 8; anchors.left: parent.left; @@ -1702,7 +1709,7 @@ Item { Item { id: amountContainer_paymentFailure; - visible: root.assetName === ""; + visible: root.assetCertID === ""; anchors.top: sendToContainer_paymentFailure.bottom; anchors.topMargin: 16; anchors.left: parent.left; @@ -1757,7 +1764,7 @@ Item { RalewaySemiBold { id: optionalMessage_paymentFailure; - visible: root.assetName === ""; + visible: root.assetCertID === "" || sendAssetStep.referrer === "payIn"; text: optionalMessage.text; // Anchors anchors.top: amountContainer_paymentFailure.visible ? amountContainer_paymentFailure.bottom : sendToContainer_paymentFailure.bottom; @@ -1779,19 +1786,23 @@ Item { HifiControlsUit.Button { id: closeButton_paymentFailure; color: hifi.buttons.noneBorderless; - colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; + colorScheme: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; anchors.right: retryButton_paymentFailure.left; anchors.rightMargin: 12; anchors.bottom: parent.bottom; - anchors.bottomMargin: root.assetName === "" ? 80 : 30; + anchors.bottomMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 80 : 30; height: 50; width: 120; text: "Cancel"; onClicked: { - root.nextActiveView = "sendAssetHome"; - resetSendAssetData(); - if (root.assetName !== "") { - sendSignalToParent({method: "closeSendAsset"}); + if (sendAssetStep.referrer === "payIn") { + sendToScript({method: "closeSendAsset"}); + } else { + root.nextActiveView = "sendAssetHome"; + resetSendAssetData(); + if (root.assetName !== "") { + sendSignalToParent({method: "closeSendAsset"}); + } } } } @@ -1800,17 +1811,17 @@ Item { HifiControlsUit.Button { id: retryButton_paymentFailure; color: hifi.buttons.blue; - colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; + colorScheme: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; anchors.right: parent.right; anchors.rightMargin: 12; anchors.bottom: parent.bottom; - anchors.bottomMargin: root.assetName === "" ? 80 : 30; + anchors.bottomMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 80 : 30; height: 50; width: 120; text: "Retry"; onClicked: { root.isCurrentlySendingAsset = true; - if (sendAssetStep.referrer === "connections") { + if (sendAssetStep.referrer === "connections" || sendAssetStep.referrer === "payIn") { Commerce.transferAssetToUsername(sendAssetStep.selectedRecipientUserName, root.assetCertID, parseInt(amountTextField.text), @@ -1878,9 +1889,13 @@ Item { sendAssetStep.selectedRecipientUserName = message.userName; break; case 'updateSendAssetQML': - root.assetName = message.assetName || ""; + root.assetName = ""; root.assetCertID = message.assetCertID || ""; - amountTextField.text = message.amount || 1; + if (root.assetCertID === "") { + amountTextField.text = message.amount || 1; + } else { + amountTextField.text = ""; + } sendAssetStep.referrer = "payIn"; sendAssetStep.selectedRecipientNodeID = ""; sendAssetStep.selectedRecipientDisplayName = 'Secure Payment'; diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index 1bfa9d4b20..e3da1c2577 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -219,17 +219,12 @@ }); } - function buyButtonClicked(id, name, author, price, href, referrer, edition, type) { + function buyButtonClicked(id, referrer, edition) { EventBridge.emitWebEvent(JSON.stringify({ type: "CHECKOUT", itemId: id, - itemName: name, - itemPrice: price ? parseInt(price, 10) : 0, - itemHref: href, referrer: referrer, - itemAuthor: author, - itemEdition: edition, - itemType: type.trim() + itemEdition: edition })); } @@ -313,13 +308,8 @@ return false; } buyButtonClicked($(this).closest('.grid-item').attr('data-item-id'), - $(this).closest('.grid-item').find('.item-title').text(), - $(this).closest('.grid-item').find('.creator').find('.value').text(), - $(this).closest('.grid-item').find('.item-cost').text(), - $(this).attr('data-href'), "mainPage", - -1, - $(this).closest('.grid-item').find('.item-type').text()); + -1); }); } @@ -427,13 +417,8 @@ purchaseButton.on('click', function () { if ('available' === availability || isUpdating) { buyButtonClicked(window.location.pathname.split("/")[3], - $('#top-center').find('h1').text(), - $('#creator').find('.value').text(), - cost, - href, "itemPage", - urlParams.get('edition'), - type); + urlParams.get('edition')); } }); } diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index be25d1265f..e4891a9bae 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -471,7 +471,7 @@ function onWebEventReceived(message) { wireQmlEventBridge(true); ui.open(MARKETPLACE_CHECKOUT_QML_PATH); ui.tablet.sendToQml({ - method: 'updateCheckoutQML', + method: 'updateCheckoutQMLItemID', params: message }); } else if (message.type === "REQUEST_SETTING") { @@ -649,8 +649,8 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) { case 'purchases_openGoTo': case 'purchases_itemInfoClicked': case 'purchases_itemCertificateClicked': - case 'clearShouldShowDotHistory': - case 'giftAsset': + case 'clearShouldShowDotHistory': + case 'giftAsset': break; default: print('marketplaces.js: Unrecognized message from Checkout.qml'); From e943504f608f5cb2d9129d3156be6c8441e65b5d Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 26 Nov 2018 15:59:08 -0800 Subject: [PATCH 074/109] Updated README.md --- tools/nitpick/README.md | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index ae8821c6be..fe027be227 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -12,7 +12,7 @@ Nitpick has 5 functions, separated into 4 tabs: 1. Evaluating the results of running tests 1. Web interface -## Build +## Build (for developers) Nitpick is built as part of the High Fidelity build. ### Creating installers #### Windows @@ -27,15 +27,17 @@ Nitpick is built as part of the High Fidelity build. 1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.1.exe: aws s3 cp nitpick-installer-v1.1.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.exe #### Mac These steps assume the hifi repository has been cloned to `~/hifi`. +1. (first time) Install brew + In a terminal: `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)` 1. (First time) install create-dmg: - `brew install create-dmg` -1. cd to the `build/tools/nitpick/Release` folder + In a terminal: `brew install create-dmg` +1. In a terminal: cd to the `build/tools/nitpick/Release` folder 1. Copy the quazip dynamic library (note final period): - `cp ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib .` + In a terminal: `cp ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib .` 1. Change the loader instruction to find the dynamic library locally - `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib libquazip5.1.dylib nitpick` -1. Delete any existing disk images: `rm *.dmg` -1. Create installer (note final period): `create-dmg --volname nitpick-installer-v1.1 nitpick-installer-v1.1.dmg .` + In a terminal: `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib libquazip5.1.dylib nitpick` +1. Delete any existing disk images. In a terminal: `rm *.dmg` +1. Create installer (note final period).In a terminal: `create-dmg --volname nitpick-installer-v1.1 nitpick-installer-v1.1.dmg .` Make sure to wait for completion. 1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.1.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.dmg` ### Installation @@ -56,16 +58,20 @@ These steps assume the hifi repository has been cloned to `~/hifi`. 1. __To run nitpick, double click **nitpick.exe**__ #### Mac +1. (first time) Install brew + In a terminal: `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)` +1. (First time) install Qt: + In a terminal: `brew install qt` 1. (First time) install Python from https://www.python.org/downloads/release/python-370/ (**macOS 64-bit installer** or **macOS 64-bit/32-bit installer**) - 1. After installation - run `open "/Applications/Python 3.6/Install Certificates.command"`. This is needed because the Mac Python supplied no longer links with the deprecated Apple-supplied system OpenSSL libraries but rather supplies a private copy of OpenSSL 1.0.2 which does not automatically access the system default root certificates. + 1. After installation - In a terminal: run `open "/Applications/Python 3.6/Install Certificates.command"`. This is needed because the Mac Python supplied no longer links with the deprecated Apple-supplied system OpenSSL libraries but rather supplies a private copy of OpenSSL 1.0.2 which does not automatically access the system default root certificates. 1. Verify that `/usr/local/bin/python3` exists. 1. (First time - AWS interface) Install pip with the script provided by the Python Packaging Authority: -$ curl -O https://bootstrap.pypa.io/get-pip.py -$ python3 get-pip.py --user +In a terminal: `curl -O https://bootstrap.pypa.io/get-pip.py` +In a terminal: `python3 get-pip.py --user` 1. Use pip to install the AWS CLI. - $ pip3 install awscli --upgrade --user + `pip3 install awscli --upgrade --user` This will install aws in your user. For user XXX, aws will be located in ~/Library/Python/3.7/bin - 1. Open a new command prompt and run `aws configure` + 1. Open a new command prompt and run `~/Library/Python/3.7/bin/aws configure` 1. Enter the AWS account number 1. Enter the secret key 1. Leave region name and ouput format as default [None] @@ -75,9 +81,11 @@ $ python3 get-pip.py --user 1. Create a folder for the nitpick files (e.g. ~/nitpick) If this folder exists then delete all it's contents. 1. Copy the downloaded files to the folder - `cp -r /Volumes/nitpick-installer-v1.1/* .` + In a terminal: + `cd ~/nitpick` + `cp -r /Volumes/nitpick-installer-v1.1/* .` -1. __To run nitpick, cd to the folder that you copied to and run `./nitpick`__ +1. __To run nitpick, cd to the folder that you copied to and run `./nitpick`__ #Use ## Create ![](./Create.PNG) From 2ade0078f45187f191fe4d94f14cf5cf852c0187 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 26 Nov 2018 16:02:22 -0800 Subject: [PATCH 075/109] Updated README.md --- tools/nitpick/README.md | 52 ++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index 3bbc4fbac1..fe027be227 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -12,7 +12,7 @@ Nitpick has 5 functions, separated into 4 tabs: 1. Evaluating the results of running tests 1. Web interface -## Build +## Build (for developers) Nitpick is built as part of the High Fidelity build. ### Creating installers #### Windows @@ -22,24 +22,27 @@ Nitpick is built as part of the High Fidelity build. 1. Select all, right-click and select 7-Zip->Add to archive... 1. Set Archive format to 7z 1. Check "Create SFX archive -1. Enter installer name (i.e. `nitpick-installer-v1.0.exe`) +1. Enter installer name (i.e. `nitpick-installer-v1.1.exe`) 1. Click "OK" -1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe: aws s3 cp nitpick-installer-v1.0.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.exe +1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.1.exe: aws s3 cp nitpick-installer-v1.1.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.exe #### Mac These steps assume the hifi repository has been cloned to `~/hifi`. +1. (first time) Install brew + In a terminal: `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)` 1. (First time) install create-dmg: - `brew install create-dmg` -1. cd to the `build/tools/nitpick/Release` folder + In a terminal: `brew install create-dmg` +1. In a terminal: cd to the `build/tools/nitpick/Release` folder 1. Copy the quazip dynamic library (note final period): - `cp ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib .` + In a terminal: `cp ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib .` 1. Change the loader instruction to find the dynamic library locally - `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib libquazip5.1.dylib nitpick` -1. Delete any existing installer: `rm nitpick.dmg` -1. Create installer (note final period): `create-dmg --volname nitpick-installer-v1.0 nitpick-installer-v1.0.dmg .` -1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.0.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.dmg` + In a terminal: `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib libquazip5.1.dylib nitpick` +1. Delete any existing disk images. In a terminal: `rm *.dmg` +1. Create installer (note final period).In a terminal: `create-dmg --volname nitpick-installer-v1.1 nitpick-installer-v1.1.dmg .` + Make sure to wait for completion. +1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.1.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.dmg` ### Installation #### Windows -1. (First time) download and install vc_redist.x64.exe (available at https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe) +1. (First time) download and install vc_redist.x64.exe (available at https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.1.exe) 1. (First time) download and install Python 3 from https://hifi-qa.s3.amazonaws.com/nitpick/Windows/python-3.7.0-amd64.exe (also located at https://www.python.org/downloads/) 1. After installation - create an environment variable called PYTHON_PATH and set it to the folder containing the Python executable. 1. (First time) download and install AWS CLI from https://hifi-qa.s3.amazonaws.com/nitpick/Windows/AWSCLI64PY3.msi (also available at https://aws.amazon.com/cli/ @@ -49,33 +52,40 @@ These steps assume the hifi repository has been cloned to `~/hifi`. 1. Leave region name and ouput format as default [None] 1. Install the latest release of Boto3 via pip: `pip install boto3` -1. Download the installer by browsing to [here]() +1. Download the installer by browsing to [here]() 1. Double click on the installer and install to a convenient location ![](./setup_7z.PNG) 1. __To run nitpick, double click **nitpick.exe**__ #### Mac -1. (Firat time) install Python from https://www.python.org/downloads/release/python-370/ (**macOS 64-bit installer** or **macOS 64-bit/32-bit installer**) - 1. After installation - run `open "/Applications/Python 3.6/Install Certificates.command"`. This is needed because the Mac Python supplied no longer links with the deprecated Apple-supplied system OpenSSL libraries but rather supplies a private copy of OpenSSL 1.0.2 which does not automatically access the system default root certificates. +1. (first time) Install brew + In a terminal: `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)` +1. (First time) install Qt: + In a terminal: `brew install qt` +1. (First time) install Python from https://www.python.org/downloads/release/python-370/ (**macOS 64-bit installer** or **macOS 64-bit/32-bit installer**) + 1. After installation - In a terminal: run `open "/Applications/Python 3.6/Install Certificates.command"`. This is needed because the Mac Python supplied no longer links with the deprecated Apple-supplied system OpenSSL libraries but rather supplies a private copy of OpenSSL 1.0.2 which does not automatically access the system default root certificates. 1. Verify that `/usr/local/bin/python3` exists. 1. (First time - AWS interface) Install pip with the script provided by the Python Packaging Authority: -$ curl -O https://bootstrap.pypa.io/get-pip.py -$ python3 get-pip.py --user +In a terminal: `curl -O https://bootstrap.pypa.io/get-pip.py` +In a terminal: `python3 get-pip.py --user` 1. Use pip to install the AWS CLI. - $ pip3 install awscli --upgrade --user + `pip3 install awscli --upgrade --user` This will install aws in your user. For user XXX, aws will be located in ~/Library/Python/3.7/bin - 1. Open a new command prompt and run `aws configure` + 1. Open a new command prompt and run `~/Library/Python/3.7/bin/aws configure` 1. Enter the AWS account number 1. Enter the secret key 1. Leave region name and ouput format as default [None] 1. Install the latest release of Boto3 via pip: pip3 install boto3 -1. Download the installer by browsing to [here](). +1. Download the installer by browsing to [here](). 1. Double-click on the downloaded image to mount it 1. Create a folder for the nitpick files (e.g. ~/nitpick) + If this folder exists then delete all it's contents. 1. Copy the downloaded files to the folder - `cp -r /Volumes/nitpick-installer-v1.0/* .` + In a terminal: + `cd ~/nitpick` + `cp -r /Volumes/nitpick-installer-v1.1/* .` -1. __To run nitpick, cd to the folder that you copied to and run `./nitpick`__ +1. __To run nitpick, cd to the folder that you copied to and run `./nitpick`__ #Use ## Create ![](./Create.PNG) From a9fd443f28ce203ccb0093275166d4653c7eb8bc Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 26 Nov 2018 16:03:07 -0800 Subject: [PATCH 076/109] 'improve' UI slightly --- .../hifi/commerce/common/sendAsset/RecipientDisplay.qml | 7 ++++--- .../qml/hifi/commerce/common/sendAsset/SendAsset.qml | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/common/sendAsset/RecipientDisplay.qml b/interface/resources/qml/hifi/commerce/common/sendAsset/RecipientDisplay.qml index 9e1a967d50..10756957d3 100644 --- a/interface/resources/qml/hifi/commerce/common/sendAsset/RecipientDisplay.qml +++ b/interface/resources/qml/hifi/commerce/common/sendAsset/RecipientDisplay.qml @@ -25,14 +25,15 @@ Item { id: root; - property bool isDisplayingNearby; // as opposed to 'connections' + // true when sending to 'nearby' or when a script raises the send asset dialog + property bool multiLineDisplay; property string displayName; property string userName; property string profilePic; property string textColor: hifi.colors.white; Item { - visible: root.isDisplayingNearby; + visible: root.multiLineDisplay; anchors.fill: parent; RalewaySemiBold { @@ -71,7 +72,7 @@ Item { } Item { - visible: !root.isDisplayingNearby; + visible: !root.multiLineDisplay; anchors.fill: parent; Image { diff --git a/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml b/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml index a719ae6432..ebb2a7f59c 100644 --- a/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml +++ b/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml @@ -918,7 +918,7 @@ Item { userName: sendAssetStep.selectedRecipientUserName; profilePic: sendAssetStep.selectedRecipientProfilePic !== "" ? ((0 === sendAssetStep.selectedRecipientProfilePic.indexOf("http")) ? sendAssetStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendAssetStep.selectedRecipientProfilePic)) : ""; - isDisplayingNearby: sendAssetStep.referrer === "nearby"; + multiLineDisplay: sendAssetStep.referrer === "nearby" || sendAssetStep.referrer === "payIn"; } // "CHANGE" button @@ -1422,7 +1422,7 @@ Item { userName: sendAssetStep.selectedRecipientUserName; profilePic: sendAssetStep.selectedRecipientProfilePic !== "" ? ((0 === sendAssetStep.selectedRecipientProfilePic.indexOf("http")) ? sendAssetStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendAssetStep.selectedRecipientProfilePic)) : ""; - isDisplayingNearby: sendAssetStep.referrer === "nearby"; + multiLineDisplay: sendAssetStep.referrer === "nearby" || sendAssetStep.referrer === "payIn"; } } @@ -1703,7 +1703,7 @@ Item { userName: sendAssetStep.selectedRecipientUserName; profilePic: sendAssetStep.selectedRecipientProfilePic !== "" ? ((0 === sendAssetStep.selectedRecipientProfilePic.indexOf("http")) ? sendAssetStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendAssetStep.selectedRecipientProfilePic)) : ""; - isDisplayingNearby: sendAssetStep.referrer === "nearby"; + multiLineDisplay: sendAssetStep.referrer === "nearby" || sendAssetStep.referrer === "payIn"; } } @@ -1898,7 +1898,7 @@ Item { } sendAssetStep.referrer = "payIn"; sendAssetStep.selectedRecipientNodeID = ""; - sendAssetStep.selectedRecipientDisplayName = 'Secure Payment'; + sendAssetStep.selectedRecipientDisplayName = "Determined by script:"; sendAssetStep.selectedRecipientUserName = message.username; optionalMessage.text = message.message || "No Message Provided"; From ebc7875f5ea7b58edadbf676dd1e390b9674a11b Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 26 Nov 2018 16:03:40 -0800 Subject: [PATCH 077/109] Updated README.md --- tools/nitpick/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index fe027be227..319d374a5d 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -86,7 +86,7 @@ In a terminal: `python3 get-pip.py --user` `cp -r /Volumes/nitpick-installer-v1.1/* .` 1. __To run nitpick, cd to the folder that you copied to and run `./nitpick`__ -#Use +# Usage ## Create ![](./Create.PNG) From c211dc363b4d41fbef1d729ff04441fbef295a9b Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 26 Nov 2018 16:05:49 -0800 Subject: [PATCH 078/109] Updated README.md --- tools/nitpick/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index fe027be227..319d374a5d 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -86,7 +86,7 @@ In a terminal: `python3 get-pip.py --user` `cp -r /Volumes/nitpick-installer-v1.1/* .` 1. __To run nitpick, cd to the folder that you copied to and run `./nitpick`__ -#Use +# Usage ## Create ![](./Create.PNG) From e587820de317fa337088fc686e0e02373a2f46bd Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 26 Nov 2018 16:18:43 -0800 Subject: [PATCH 079/109] Should be v1.0 --- tools/nitpick/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index 319d374a5d..ce43332c1b 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -22,9 +22,9 @@ Nitpick is built as part of the High Fidelity build. 1. Select all, right-click and select 7-Zip->Add to archive... 1. Set Archive format to 7z 1. Check "Create SFX archive -1. Enter installer name (i.e. `nitpick-installer-v1.1.exe`) +1. Enter installer name (i.e. `nitpick-installer-v1.0.exe`) 1. Click "OK" -1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.1.exe: aws s3 cp nitpick-installer-v1.1.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.exe +1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe: aws s3 cp nitpick-installer-v1.0.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.exe #### Mac These steps assume the hifi repository has been cloned to `~/hifi`. 1. (first time) Install brew @@ -37,12 +37,12 @@ These steps assume the hifi repository has been cloned to `~/hifi`. 1. Change the loader instruction to find the dynamic library locally In a terminal: `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib libquazip5.1.dylib nitpick` 1. Delete any existing disk images. In a terminal: `rm *.dmg` -1. Create installer (note final period).In a terminal: `create-dmg --volname nitpick-installer-v1.1 nitpick-installer-v1.1.dmg .` +1. Create installer (note final period).In a terminal: `create-dmg --volname nitpick-installer-v1.0 nitpick-installer-v1.0.dmg .` Make sure to wait for completion. -1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.1.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.dmg` +1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.0.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.0.dmg` ### Installation #### Windows -1. (First time) download and install vc_redist.x64.exe (available at https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.1.exe) +1. (First time) download and install vc_redist.x64.exe (available at https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.0.exe) 1. (First time) download and install Python 3 from https://hifi-qa.s3.amazonaws.com/nitpick/Windows/python-3.7.0-amd64.exe (also located at https://www.python.org/downloads/) 1. After installation - create an environment variable called PYTHON_PATH and set it to the folder containing the Python executable. 1. (First time) download and install AWS CLI from https://hifi-qa.s3.amazonaws.com/nitpick/Windows/AWSCLI64PY3.msi (also available at https://aws.amazon.com/cli/ @@ -52,7 +52,7 @@ These steps assume the hifi repository has been cloned to `~/hifi`. 1. Leave region name and ouput format as default [None] 1. Install the latest release of Boto3 via pip: `pip install boto3` -1. Download the installer by browsing to [here]() +1. Download the installer by browsing to [here]() 1. Double click on the installer and install to a convenient location ![](./setup_7z.PNG) @@ -76,14 +76,14 @@ In a terminal: `python3 get-pip.py --user` 1. Enter the secret key 1. Leave region name and ouput format as default [None] 1. Install the latest release of Boto3 via pip: pip3 install boto3 -1. Download the installer by browsing to [here](). +1. Download the installer by browsing to [here](). 1. Double-click on the downloaded image to mount it 1. Create a folder for the nitpick files (e.g. ~/nitpick) If this folder exists then delete all it's contents. 1. Copy the downloaded files to the folder In a terminal: `cd ~/nitpick` - `cp -r /Volumes/nitpick-installer-v1.1/* .` + `cp -r /Volumes/nitpick-installer-v1.0/* .` 1. __To run nitpick, cd to the folder that you copied to and run `./nitpick`__ # Usage From e7ab7094cd1acf473969e89283c87c567b4683e9 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 26 Nov 2018 16:42:48 -0800 Subject: [PATCH 080/109] Kill Hifi processes after evaluation. --- tools/nitpick/src/TestRunner.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/nitpick/src/TestRunner.cpp b/tools/nitpick/src/TestRunner.cpp index 30740bd28a..e3b8adca28 100644 --- a/tools/nitpick/src/TestRunner.cpp +++ b/tools/nitpick/src/TestRunner.cpp @@ -528,8 +528,6 @@ void TestRunner::runInterfaceWithTestScript() { } void TestRunner::interfaceExecutionComplete() { - killProcesses(); - QFileInfo testCompleted(QDir::toNativeSeparators(_snapshotFolder) +"/tests_completed.txt"); if (!testCompleted.exists()) { QMessageBox::critical(0, "Tests not completed", "Interface seems to have crashed before completion of the test scripts\nExisting images will be evaluated"); @@ -537,6 +535,8 @@ void TestRunner::interfaceExecutionComplete() { evaluateResults(); + killProcesses(); + // The High Fidelity AppData folder will be restored after evaluation has completed } From 5da6ecad121ee1111115e5109b9c3b1db1c199ea Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 26 Nov 2018 18:10:14 -0800 Subject: [PATCH 081/109] Compilation error. --- tools/nitpick/src/TestRunner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nitpick/src/TestRunner.cpp b/tools/nitpick/src/TestRunner.cpp index 7c2dfda1cd..12bdf87495 100644 --- a/tools/nitpick/src/TestRunner.cpp +++ b/tools/nitpick/src/TestRunner.cpp @@ -336,7 +336,7 @@ void TestRunner::saveExistingHighFidelityAppDataFolder() { #ifdef Q_OS_WIN dataDirectory = qgetenv("USERPROFILE") + "\\AppData\\Roaming"; #elif defined Q_OS_MAC - dataDirectory{ QDir::homePath() + "/Library/Application Support" }; + dataDirectory = QDir::homePath() + "/Library/Application Support"; #endif if (_runLatest->isChecked()) { _appDataFolder = dataDirectory + "/High Fidelity"; From aed947cb0a65ff3006054485503fe616fc45d4b1 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 26 Nov 2018 18:10:41 -0800 Subject: [PATCH 082/109] Minor cleanup. --- tools/nitpick/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index 319d374a5d..a02980ddfe 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -37,7 +37,7 @@ These steps assume the hifi repository has been cloned to `~/hifi`. 1. Change the loader instruction to find the dynamic library locally In a terminal: `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib libquazip5.1.dylib nitpick` 1. Delete any existing disk images. In a terminal: `rm *.dmg` -1. Create installer (note final period).In a terminal: `create-dmg --volname nitpick-installer-v1.1 nitpick-installer-v1.1.dmg .` +1. Create installer (note final period).In a terminal: `create-dmg --volname nitpick-installer-v1.1 nitpick-installer-v1.1.dmg .` Make sure to wait for completion. 1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.1.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.1.dmg` ### Installation From e10936ec3429bf9110c846b4f7d57dd08ea41a93 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 26 Nov 2018 18:26:25 -0800 Subject: [PATCH 083/109] Delete network query resources for failed queries --- libraries/avatars/src/AvatarData.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index d9d4b57c31..40555547e9 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2103,8 +2103,9 @@ void AvatarData::setJointMappingsFromNetworkReply() { // before we process this update, make sure that the skeleton model URL hasn't changed // since we made the FST request - if (networkReply->url() != _skeletonModelURL) { + if (networkReply->error() != QNetworkReply::NoError || networkReply->url() != _skeletonModelURL) { qCDebug(avatars) << "Refusing to set joint mappings for FST URL that does not match the current URL"; + networkReply->deleteLater(); return; } From 2bd66924efed418e8999965bb90dd6313aec3fa8 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 26 Nov 2018 18:27:13 -0800 Subject: [PATCH 084/109] Clear deleted avatar-entity list in mixer --- assignment-client/src/avatars/AvatarMixerClientData.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index 76cdf13986..5e36d8beaf 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -152,6 +152,8 @@ void AvatarMixerClientData::processSetTraitsMessage(ReceivedMessage& message, if (packetTraitVersion > instanceVersionRef) { if (traitSize == AvatarTraits::DELETED_TRAIT_SIZE) { _avatar->processDeletedTraitInstance(traitType, instanceID); + // Mixer doesn't need deleted IDs. + _avatar->getAndClearRecentlyDetachedIDs(); // to track a deleted instance but keep version information // the avatar mixer uses the negative value of the sent version From c4a9ca3445e3d499ae87e6417bc02b81722f9512 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 27 Nov 2018 09:32:37 -0800 Subject: [PATCH 085/109] fix interface crashing when reloading scripts --- libraries/script-engine/src/ScriptEngines.cpp | 39 ++++++++----------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 2cdfc20647..399ccf1919 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -191,7 +191,6 @@ void ScriptEngines::shutdownScripting() { // Gracefully stop the engine's scripting thread scriptEngine->stop(); - removeScriptEngine(scriptEngine); // We need to wait for the engine to be done running before we proceed, because we don't // want any of the scripts final "scriptEnding()" or pending "update()" methods from accessing @@ -370,13 +369,10 @@ QStringList ScriptEngines::getRunningScripts() { } void ScriptEngines::stopAllScripts(bool restart) { - QVector toReload; QReadLocker lock(&_scriptEnginesHashLock); if (_isReloading) { return; - } else { - _isReloading = true; } for (QHash::const_iterator it = _scriptEnginesHash.constBegin(); @@ -389,29 +385,27 @@ void ScriptEngines::stopAllScripts(bool restart) { // queue user scripts if restarting if (restart && scriptEngine->isUserLoaded()) { - toReload << it.key().toString(); + _isReloading = true; + bool lastScript = (it == _scriptEnginesHash.constEnd() - 1); + ScriptEngine::Type type = scriptEngine->getType(); + + connect(scriptEngine.data(), &ScriptEngine::finished, this, [this, type, lastScript] (QString scriptName) { + reloadScript(scriptName, true)->setType(type); + + if (lastScript) { + _isReloading = false; + } + }); } // stop all scripts scriptEngine->stop(); - removeScriptEngine(scriptEngine); } - // wait for engines to stop (ie: providing time for .scriptEnding cleanup handlers to run) before - // triggering reload of any Client scripts / Entity scripts - QTimer::singleShot(1000, this, [=]() { - for(const auto &scriptName : toReload) { - auto scriptEngine = getScriptEngine(scriptName); - if (scriptEngine && !scriptEngine->isFinished()) { - scriptEngine->waitTillDoneRunning(); - } - reloadScript(scriptName); - } - if (restart) { - qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading"; - emit scriptsReloading(); - } - _isReloading = false; - }); + + if (restart) { + qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading"; + emit scriptsReloading(); + } } bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { @@ -439,7 +433,6 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { } } scriptEngine->stop(); - removeScriptEngine(scriptEngine); stoppedScript = true; } } From 67dfccafec2a426efbe2aecc9cec0ce50eb11361 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 27 Nov 2018 10:19:14 -0800 Subject: [PATCH 086/109] Show item name when sending item --- .../commerce/common/sendAsset/SendAsset.qml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml b/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml index ebb2a7f59c..2d0bb2d87b 100644 --- a/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml +++ b/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml @@ -107,6 +107,14 @@ Item { root.nextActiveView = 'paymentFailure'; } } + + onCertificateInfoResult: { + if (result.status !== 'success') { + console.log("Failed to get certificate info", result.data.message); + } else { + root.assetName = result.data.marketplace_item_name; + } + } } Connections { @@ -864,7 +872,7 @@ Item { RalewaySemiBold { id: sendAssetText_sendAssetStep; - text: sendAssetStep.referrer === "payIn" && root.assetCertID !== "" ? "Send Item:" : + text: sendAssetStep.referrer === "payIn" && root.assetCertID !== "" ? "Send \"" + root.assetName + "\":" : (root.assetCertID === "" ? "Send Money To:" : "Gift \"" + root.assetName + "\" To:"); // Anchors anchors.top: parent.top; @@ -1429,7 +1437,7 @@ Item { Item { id: giftContainer_paymentSuccess; - visible: root.assetCertID !== "" && sendAssetStep.referrer !== "payIn"; + visible: root.assetCertID !== ""; anchors.top: sendToContainer_paymentSuccess.bottom; anchors.topMargin: 8; anchors.left: parent.left; @@ -1440,7 +1448,7 @@ Item { RalewaySemiBold { id: gift_paymentSuccess; - text: "Gift:"; + text: sendAssetStep.referrer === "payIn" ? "Item:" : "Gift:"; // Anchors anchors.top: parent.top; anchors.left: parent.left; @@ -1526,7 +1534,7 @@ Item { RalewaySemiBold { id: optionalMessage_paymentSuccess; - visible: root.assetCertID === "" || sendAssetStep.referrer === "payIn"; + visible: root.assetCertID === ""; text: optionalMessage.text; // Anchors anchors.top: amountContainer_paymentSuccess.visible ? amountContainer_paymentSuccess.bottom : sendToContainer_paymentSuccess.bottom; @@ -1895,6 +1903,7 @@ Item { amountTextField.text = message.amount || 1; } else { amountTextField.text = ""; + Commerce.certificateInfo(root.assetCertID); } sendAssetStep.referrer = "payIn"; sendAssetStep.selectedRecipientNodeID = ""; From 9cc896c4a884c6feaa7584560b30ee7f7bd92c6f Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 20 Nov 2018 09:13:07 -0800 Subject: [PATCH 087/109] fixing keyboard mallets dimensions --- interface/src/ui/Keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/Keyboard.cpp b/interface/src/ui/Keyboard.cpp index 6852691634..46a25a24a7 100644 --- a/interface/src/ui/Keyboard.cpp +++ b/interface/src/ui/Keyboard.cpp @@ -60,7 +60,7 @@ static const float MALLET_TOUCH_Y_OFFSET = 0.050f; static const float MALLET_Y_OFFSET = 0.160f; static const glm::quat MALLET_ROTATION_OFFSET{0.70710678f, 0.0f, -0.70710678f, 0.0f}; -static const glm::vec3 MALLET_MODEL_DIMENSIONS{0.03f, MALLET_LENGTH, 0.03f}; +static const glm::vec3 MALLET_MODEL_DIMENSIONS{0.01f, MALLET_LENGTH, 0.01f}; static const glm::vec3 MALLET_POSITION_OFFSET{0.0f, -MALLET_Y_OFFSET / 2.0f, 0.0f}; static const glm::vec3 MALLET_TIP_OFFSET{0.0f, MALLET_LENGTH - MALLET_TOUCH_Y_OFFSET, 0.0f}; From 3a4ec2cc270659113f346dbdb090c88f5a064ad8 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Tue, 27 Nov 2018 10:53:25 -0800 Subject: [PATCH 088/109] Update glowLine.slv --- libraries/render-utils/src/glowLine.slv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/glowLine.slv b/libraries/render-utils/src/glowLine.slv index ecb1152d52..3471bc2f98 100644 --- a/libraries/render-utils/src/glowLine.slv +++ b/libraries/render-utils/src/glowLine.slv @@ -53,9 +53,9 @@ void main(void) { // Add or subtract the orthogonal vector based on a different vertex ID // calculation - distanceFromCenter = mix(1.0, -1.0, float(gl_VertexID < 2)); + distanceFromCenter = 1.0 - 2.0 * float(gl_VertexID < 2); eye.xyz += distanceFromCenter * orthogonal; // Finally, put the eyespace vertex into clip space <$transformEyeToClipPos(cam, eye, gl_Position)$> -} \ No newline at end of file +} From 5ee803bf1d0a99db94be178c190239a302f887c3 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Tue, 27 Nov 2018 10:54:56 -0800 Subject: [PATCH 089/109] Update parabola.slv --- libraries/render-utils/src/parabola.slv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/parabola.slv b/libraries/render-utils/src/parabola.slv index f220c656aa..6032452d1d 100644 --- a/libraries/render-utils/src/parabola.slv +++ b/libraries/render-utils/src/parabola.slv @@ -49,7 +49,7 @@ void main(void) { normal = vec4(normalize(cross(_parabolaData.velocity, _parabolaData.acceleration)), 0); } - pos += 0.5 * _parabolaData.width * normal * mix(-1.0, 1.0, float(gl_VertexID % 2 == 0)); + pos += 0.5 * _parabolaData.width * normal * (-1.0 + 2.0 * float(gl_VertexID % 2 == 0)); <$transformModelToClipPos(cam, obj, pos, gl_Position)$> -} \ No newline at end of file +} From f728a8ba5a0084426079a4466100a91c2b1eaddb Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Tue, 27 Nov 2018 10:57:57 -0800 Subject: [PATCH 090/109] Update drawCellBounds.slv --- libraries/render/src/render/drawCellBounds.slv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render/src/render/drawCellBounds.slv b/libraries/render/src/render/drawCellBounds.slv index 4b5356741b..216f1ea299 100644 --- a/libraries/render/src/render/drawCellBounds.slv +++ b/libraries/render/src/render/drawCellBounds.slv @@ -51,7 +51,7 @@ void main(void) { vec4 pos = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]]; int cellIsEmpty = sign(inCellLocation.w); - ivec4 cellLocation = ivec4(inCellLocation.xyz, cellIsEmpty * inCellLocation.w); + ivec4 cellLocation = ivec4(inCellLocation.xyz, abs(inCellLocation.w)); vec4 cellBound = evalBound(cellLocation); pos.xyz = cellBound.xyz + vec3(cellBound.w) * pos.xyz; @@ -62,4 +62,4 @@ void main(void) { <$transformModelToClipPos(cam, obj, pos, gl_Position)$> varColor = vec4(colorWheel(fract(float(inCellLocation.w) / 5.0)), 0.8 + 0.2 * float(cellIsEmpty)); -} \ No newline at end of file +} From 29028386c8a60abebac6248ba6b1911a87f35d65 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 27 Nov 2018 11:56:07 -0800 Subject: [PATCH 091/109] Keyboard menu option in general settings --- interface/resources/qml/controlsUit/Keyboard.qml | 4 ++-- interface/src/Menu.cpp | 2 -- interface/src/Menu.h | 1 - .../src/scripting/KeyboardScriptingInterface.cpp | 4 ++++ interface/src/scripting/KeyboardScriptingInterface.h | 3 +++ interface/src/ui/Keyboard.cpp | 11 +++++++++++ interface/src/ui/Keyboard.h | 7 +++++++ interface/src/ui/PreferencesDialog.cpp | 7 +++++++ 8 files changed, 34 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/controlsUit/Keyboard.qml b/interface/resources/qml/controlsUit/Keyboard.qml index c38631ff79..a55523f34a 100644 --- a/interface/resources/qml/controlsUit/Keyboard.qml +++ b/interface/resources/qml/controlsUit/Keyboard.qml @@ -44,14 +44,14 @@ Rectangle { onPasswordChanged: { - var use3DKeyboard = (typeof MenuInterface === "undefined") ? false : MenuInterface.isOptionChecked("Use 3D Keyboard"); + var use3DKeyboard = (typeof KeyboardScriptingInterface === "undefined") ? false : KeyboardScriptingInterface.use3DKeyboard; if (use3DKeyboard) { KeyboardScriptingInterface.password = password; } } onRaisedChanged: { - var use3DKeyboard = (typeof MenuInterface === "undefined") ? false : MenuInterface.isOptionChecked("Use 3D Keyboard"); + var use3DKeyboard = (typeof KeyboardScriptingInterface === "undefined") ? false : KeyboardScriptingInterface.use3DKeyboard; if (!use3DKeyboard) { keyboardBase.height = raised ? raisedHeight : 0; keyboardBase.visible = raised; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 13c622627d..e9a44b1e87 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -364,8 +364,6 @@ Menu::Menu() { qApp->setHmdTabletBecomesToolbarSetting(action->isChecked()); }); - addCheckableActionToQMenuAndActionHash(uiOptionsMenu, MenuOption::Use3DKeyboard, 0, true); - // Developer > Render >>> MenuWrapper* renderOptionsMenu = developerMenu->addMenu("Render"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index d3d9e5e674..e0e48ff32c 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -213,7 +213,6 @@ namespace MenuOption { const QString TurnWithHead = "Turn using Head"; const QString UseAudioForMouth = "Use Audio for Mouth"; const QString UseCamera = "Use Camera"; - const QString Use3DKeyboard = "Use 3D Keyboard"; const QString VelocityFilter = "Velocity Filter"; const QString VisibleToEveryone = "Everyone"; const QString VisibleToFriends = "Friends"; diff --git a/interface/src/scripting/KeyboardScriptingInterface.cpp b/interface/src/scripting/KeyboardScriptingInterface.cpp index b26e1ec378..d86bb56e64 100644 --- a/interface/src/scripting/KeyboardScriptingInterface.cpp +++ b/interface/src/scripting/KeyboardScriptingInterface.cpp @@ -32,3 +32,7 @@ void KeyboardScriptingInterface::setPassword(bool password) { void KeyboardScriptingInterface::loadKeyboardFile(const QString& keyboardFile) { DependencyManager::get()->loadKeyboardFile(keyboardFile); } + +bool KeyboardScriptingInterface::getUse3DKeyboard() { + return DependencyManager::get()->getUse3DKeyboard(); +} diff --git a/interface/src/scripting/KeyboardScriptingInterface.h b/interface/src/scripting/KeyboardScriptingInterface.h index 1ab91ea7c3..709dfe01de 100644 --- a/interface/src/scripting/KeyboardScriptingInterface.h +++ b/interface/src/scripting/KeyboardScriptingInterface.h @@ -30,6 +30,7 @@ class KeyboardScriptingInterface : public QObject, public Dependency { Q_OBJECT Q_PROPERTY(bool raised READ isRaised WRITE setRaised) Q_PROPERTY(bool password READ isPassword WRITE setPassword) + Q_PROPERTY(bool use3DKeyboard READ getUse3DKeyboard); public: Q_INVOKABLE void loadKeyboardFile(const QString& string); @@ -39,5 +40,7 @@ private: bool isPassword(); void setPassword(bool password); + + bool getUse3DKeyboard(); }; #endif diff --git a/interface/src/ui/Keyboard.cpp b/interface/src/ui/Keyboard.cpp index 6852691634..74fd869b87 100644 --- a/interface/src/ui/Keyboard.cpp +++ b/interface/src/ui/Keyboard.cpp @@ -241,6 +241,17 @@ void Keyboard::registerKeyboardHighlighting() { selection->enableListToScene(KEY_PRESSED_HIGHLIGHT); } +bool Keyboard::getUse3DKeyboard() const { + return _use3DKeyboardLock.resultWithReadLock([&] { + return _use3DKeyboard.get(); + }); +} + +void Keyboard::setUse3DKeyboard(bool use) { + _use3DKeyboardLock.withWriteLock([&] { + _use3DKeyboard.set(use); + }); +} void Keyboard::createKeyboard() { auto pointerManager = DependencyManager::get(); diff --git a/interface/src/ui/Keyboard.h b/interface/src/ui/Keyboard.h index 18db38b2ae..9c0c8c40f2 100644 --- a/interface/src/ui/Keyboard.h +++ b/interface/src/ui/Keyboard.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "ui/overlays/Overlay.h" @@ -97,6 +98,9 @@ public: bool isPassword() const; void setPassword(bool password); + bool getUse3DKeyboard() const; + void setUse3DKeyboard(bool use); + void loadKeyboardFile(const QString& keyboardFile); QVector getKeysID(); @@ -143,6 +147,9 @@ private: SharedSoundPointer _keySound { nullptr }; std::shared_ptr _layerSwitchTimer { std::make_shared() }; + mutable ReadWriteLockable _use3DKeyboardLock; + Setting::Handle _use3DKeyboard { "use3DKeyboard", true }; + QString _typedCharacters; TextDisplay _textDisplay; Anchor _anchor; diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 5f8b191a4f..d1fbe02759 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -24,6 +24,7 @@ #include "Snapshot.h" #include "SnapshotAnimated.h" #include "UserActivityLogger.h" +#include "ui/Keyboard.h" void setupPreferences() { auto preferences = DependencyManager::get(); @@ -119,6 +120,12 @@ void setupPreferences() { preferences->addPreference(new CheckPreference(UI_CATEGORY, "Use reticle cursor instead of arrow", getter, setter)); } + { + auto getter = []()->bool { return DependencyManager::get()->getUse3DKeyboard(); }; + auto setter = [](bool value) { DependencyManager::get()->setUse3DKeyboard(value); }; + preferences->addPreference(new CheckPreference(UI_CATEGORY, "Use Virtual Keyboard", getter, setter)); + } + { auto getter = []()->bool { return qApp->getMiniTabletEnabled(); }; auto setter = [](bool value) { qApp->setMiniTabletEnabled(value); }; From a4175b042891b7b807273582b806d8ec364a60b7 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 27 Nov 2018 14:17:28 -0800 Subject: [PATCH 092/109] Error handling in checkout --- interface/resources/qml/hifi/commerce/checkout/Checkout.qml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 6320cd1675..7e17d20375 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -1080,6 +1080,12 @@ Rectangle { // function updateCheckoutQMLFromHTTP(error, result) { + if (error || (result.status !== 'success')) { + // The QML will display a loading spinner forever if the user is stuck here. + console.log("Error in Checkout.qml when getting marketplace item info!"); + return; + } + root.itemInfoReceived = true; root.itemName = result.data.title; root.itemPrice = result.data.cost; From fac27553d740edacc270122e43200209a6196183 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 23 Nov 2018 19:56:35 -0800 Subject: [PATCH 093/109] suppress 'No instance available' messages during shutdown. try a different way of shutting down AudioClient. --- interface/src/Application.cpp | 5 ++++- libraries/audio-client/src/AudioClient.cpp | 1 - libraries/shared/src/DependencyManager.h | 13 +++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 21af28ffcb..ed834a2cc5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2572,6 +2572,8 @@ void Application::cleanupBeforeQuit() { QString webengineRemoteDebugging = QProcessEnvironment::systemEnvironment().value("QTWEBENGINE_REMOTE_DEBUGGING", "false"); qCDebug(interfaceapp) << "QTWEBENGINE_REMOTE_DEBUGGING =" << webengineRemoteDebugging; + DependencyManager::prepareToExit(); + if (tracing::enabled()) { auto tracer = DependencyManager::get(); tracer->stopTracing(); @@ -2684,6 +2686,7 @@ void Application::cleanupBeforeQuit() { // destroy Audio so it and its threads have a chance to go down safely // this must happen after QML, as there are unexplained audio crashes originating in qtwebengine + QMetaObject::invokeMethod(DependencyManager::get().data(), "stop"); DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); @@ -2775,7 +2778,7 @@ Application::~Application() { // quit the thread used by the closure event sender closeEventSender->thread()->quit(); - // Can't log to file passed this point, FileLogger about to be deleted + // Can't log to file past this point, FileLogger about to be deleted qInstallMessageHandler(LogHandler::verboseMessageHandler); _renderEventHandler->deleteLater(); diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 92f7a27853..9bad7e2f45 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -302,7 +302,6 @@ void AudioClient::customDeleter() { #if defined(Q_OS_ANDROID) _shouldRestartInputSetup = false; #endif - stop(); deleteLater(); } diff --git a/libraries/shared/src/DependencyManager.h b/libraries/shared/src/DependencyManager.h index 978732fd50..bda1077990 100644 --- a/libraries/shared/src/DependencyManager.h +++ b/libraries/shared/src/DependencyManager.h @@ -74,6 +74,9 @@ public: #endif return hashCode; } + + static void prepareToExit() { manager()._exiting = true; } + private: static DependencyManager& manager(); @@ -84,6 +87,8 @@ private: QHash> _instanceHash; QHash _inheritanceHash; + + bool _exiting { false }; }; template @@ -95,9 +100,17 @@ QSharedPointer DependencyManager::get() { instance = qSharedPointerCast(manager().safeGet(hashCode)); #ifndef QT_NO_DEBUG + // debug builds... if (instance.isNull()) { qWarning() << "DependencyManager::get(): No instance available for" << typeid(T).name(); } +#else + // for non-debug builds, don't print "No instance available" during shutdown, because + // the act of printing this often causes crashes (because the LogHandler has-been/is-being + // deleted). + if (!manager()._exiting && instance.isNull()) { + qWarning() << "DependencyManager::get(): No instance available for" << typeid(T).name(); + } #endif } From 4effd365ed096e94d0c71077e4a1289129e1bdf5 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 27 Nov 2018 17:34:17 -0800 Subject: [PATCH 094/109] Change "Autotester" to "nitpick". --- tools/nitpick/src/Test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/nitpick/src/Test.cpp b/tools/nitpick/src/Test.cpp index 47458d00ee..2b862783a7 100644 --- a/tools/nitpick/src/Test.cpp +++ b/tools/nitpick/src/Test.cpp @@ -677,7 +677,7 @@ bool Test::createTestAutoScript(const QString& directory) { stream << "if (typeof PATH_TO_THE_REPO_PATH_UTILS_FILE === 'undefined') PATH_TO_THE_REPO_PATH_UTILS_FILE = 'https://raw.githubusercontent.com/highfidelity/hifi_tests/master/tests/utils/branchUtils.js';\n"; stream << "Script.include(PATH_TO_THE_REPO_PATH_UTILS_FILE);\n"; - stream << "var nitpick = createAutoTester(Script.resolvePath('.'));\n\n"; + stream << "var nitpick = createNitpick(Script.resolvePath('.'));\n\n"; stream << "nitpick.enableAuto();\n\n"; stream << "Script.include('./test.js?raw=true');\n"; @@ -758,7 +758,7 @@ void Test::createRecursiveScript(const QString& topLevelDirectory, bool interact "/tests/utils/branchUtils.js\";" << endl; textStream << "Script.include(PATH_TO_THE_REPO_PATH_UTILS_FILE);" << endl; - textStream << "var nitpick = createAutoTester(Script.resolvePath(\".\"));" << endl << endl; + textStream << "var nitpick = createNitpick(Script.resolvePath(\".\"));" << endl << endl; textStream << "var testsRootPath = nitpick.getTestsRootPath();" << endl << endl; From 59a030a16f3c2b89d47b1007e959dcf052ad546d Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 27 Nov 2018 17:41:00 -0800 Subject: [PATCH 095/109] Correct message to user. --- tools/nitpick/src/Test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/nitpick/src/Test.cpp b/tools/nitpick/src/Test.cpp index 2b862783a7..e17978d9d0 100644 --- a/tools/nitpick/src/Test.cpp +++ b/tools/nitpick/src/Test.cpp @@ -620,7 +620,7 @@ void Test::createTestAutoScript() { } if (createTestAutoScript(_testDirectory)) { - QMessageBox::information(0, "Success", "'nitpick.js` script has been created"); + QMessageBox::information(0, "Success", "'testAuto.js` script has been created"); } } @@ -748,9 +748,9 @@ void Test::createRecursiveScript(const QString& topLevelDirectory, bool interact QTextStream textStream(&allTestsFilename); - textStream << "// This is an automatically generated file, created by auto-tester" << endl; + textStream << "// This is an automatically generated file, created by nitpick" << endl; - // Include 'autoTest.js' + // Include 'nitpick.js' QString branch = nitpick->getSelectedBranch(); QString user = nitpick->getSelectedUser(); From 8be775c2b70239e0c5d046082b84b02eac3875d9 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 28 Nov 2018 10:54:39 -0800 Subject: [PATCH 096/109] don't save joint information for avatar entities --- interface/src/AvatarBookmarks.cpp | 40 +++++++++++++++++++------------ 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/interface/src/AvatarBookmarks.cpp b/interface/src/AvatarBookmarks.cpp index 534fb15d93..099171a427 100644 --- a/interface/src/AvatarBookmarks.cpp +++ b/interface/src/AvatarBookmarks.cpp @@ -247,25 +247,35 @@ QVariantMap AvatarBookmarks::getAvatarDataToBookmark() { bookmark.insert(ENTRY_AVATAR_URL, avatarUrl); bookmark.insert(ENTRY_AVATAR_SCALE, avatarScale); - QScriptEngine scriptEngine; QVariantList wearableEntities; auto treeRenderer = DependencyManager::get(); EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; - auto avatarEntities = myAvatar->getAvatarEntityData(); - for (auto entityID : avatarEntities.keys()) { - auto entity = entityTree->findEntityByID(entityID); - if (!entity || !isWearableEntity(entity)) { - continue; + + if (entityTree) { + QScriptEngine scriptEngine; + auto avatarEntities = myAvatar->getAvatarEntityData(); + for (auto entityID : avatarEntities.keys()) { + auto entity = entityTree->findEntityByID(entityID); + if (!entity || !isWearableEntity(entity)) { + continue; + } + + QVariantMap avatarEntityData; + + EncodeBitstreamParams params; + auto desiredProperties = entity->getEntityProperties(params); + desiredProperties += PROP_LOCAL_POSITION; + desiredProperties += PROP_LOCAL_ROTATION; + desiredProperties -= PROP_JOINT_ROTATIONS_SET; + desiredProperties -= PROP_JOINT_ROTATIONS; + desiredProperties -= PROP_JOINT_TRANSLATIONS_SET; + desiredProperties -= PROP_JOINT_TRANSLATIONS; + + EntityItemProperties entityProperties = entity->getProperties(desiredProperties); + QScriptValue scriptProperties = EntityItemPropertiesToScriptValue(&scriptEngine, entityProperties); + avatarEntityData["properties"] = scriptProperties.toVariant(); + wearableEntities.append(QVariant(avatarEntityData)); } - QVariantMap avatarEntityData; - EncodeBitstreamParams params; - auto desiredProperties = entity->getEntityProperties(params); - desiredProperties += PROP_LOCAL_POSITION; - desiredProperties += PROP_LOCAL_ROTATION; - EntityItemProperties entityProperties = entity->getProperties(desiredProperties); - QScriptValue scriptProperties = EntityItemPropertiesToScriptValue(&scriptEngine, entityProperties); - avatarEntityData["properties"] = scriptProperties.toVariant(); - wearableEntities.append(QVariant(avatarEntityData)); } bookmark.insert(ENTRY_AVATAR_ENTITIES, wearableEntities); return bookmark; From 1683179fe5fb75cd6d89bedb90614b283e971d45 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 29 Nov 2018 09:14:10 +1300 Subject: [PATCH 097/109] Remove unused constant --- interface/src/ModelSelector.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/ModelSelector.cpp b/interface/src/ModelSelector.cpp index 7e428a294d..3223e3ab9c 100644 --- a/interface/src/ModelSelector.cpp +++ b/interface/src/ModelSelector.cpp @@ -19,7 +19,6 @@ #include static const QString AVATAR_HEAD_AND_BODY_STRING = "Avatar Body with Head"; -static const QString AVATAR_ATTACHEMENT_STRING = "Avatar Attachment"; static const QString ENTITY_MODEL_STRING = "Entity Model"; ModelSelector::ModelSelector() { From c29f6346d8ad9a237d06a3cab2fb43add240ecc8 Mon Sep 17 00:00:00 2001 From: Clement Date: Wed, 28 Nov 2018 14:04:14 -0800 Subject: [PATCH 098/109] Clear mixing structures when we stop mixing for node --- assignment-client/src/audio/AudioMixerClientData.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 9a78ba31a2..90698bfac8 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -337,6 +337,13 @@ void AudioMixerClientData::removeAgentAvatarAudioStream() { if (it != _audioStreams.end()) { _audioStreams.erase(it); + + // Clear mixing structures so that they get recreated with up to date + // data if the stream comes back + setHasReceivedFirstMix(false); + _streams.skipped.clear(); + _streams.inactive.clear(); + _streams.active.clear(); } } From 11252a8f56d052b922004e5801cb7e54b5ce9771 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 28 Nov 2018 16:48:34 -0800 Subject: [PATCH 099/109] Fix UBSAN warning (left-shift of negative integer) when peak limiter is called with implausibly large (or NaN) audio values --- libraries/audio/src/AudioDynamics.h | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/libraries/audio/src/AudioDynamics.h b/libraries/audio/src/AudioDynamics.h index 8dbc7a75cc..6bfd249bc9 100644 --- a/libraries/audio/src/AudioDynamics.h +++ b/libraries/audio/src/AudioDynamics.h @@ -51,7 +51,7 @@ #include // convert float to int using round-to-nearest FORCEINLINE static int32_t floatToInt(float x) { - return _mm_cvt_ss2si(_mm_load_ss(&x)); + return _mm_cvt_ss2si(_mm_set_ss(x)); } #else @@ -150,7 +150,7 @@ static const int IEEE754_EXPN_BIAS = 127; // // Peak detection and -log2(x) for float input (mono) // x < 2^(31-LOG2_HEADROOM) returns 0x7fffffff -// x > 2^LOG2_HEADROOM undefined +// x > 2^LOG2_HEADROOM returns 0 // FORCEINLINE static int32_t peaklog2(float* input) { @@ -161,12 +161,12 @@ FORCEINLINE static int32_t peaklog2(float* input) { uint32_t peak = u & IEEE754_FABS_MASK; // split into e and x - 1.0 - int e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM; + int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM; int32_t x = (peak << IEEE754_EXPN_BITS) & 0x7fffffff; - // saturate - if (e > 31) { - return 0x7fffffff; + // saturate when e > 31 or e < 0 + if ((uint32_t)e > 31) { + return 0x7fffffff & ~(e >> 31); } int k = x >> (31 - LOG2_TABBITS); @@ -186,7 +186,7 @@ FORCEINLINE static int32_t peaklog2(float* input) { // // Peak detection and -log2(x) for float input (stereo) // x < 2^(31-LOG2_HEADROOM) returns 0x7fffffff -// x > 2^LOG2_HEADROOM undefined +// x > 2^LOG2_HEADROOM returns 0 // FORCEINLINE static int32_t peaklog2(float* input0, float* input1) { @@ -200,12 +200,12 @@ FORCEINLINE static int32_t peaklog2(float* input0, float* input1) { uint32_t peak = MAX(u0, u1); // split into e and x - 1.0 - int e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM; + int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM; int32_t x = (peak << IEEE754_EXPN_BITS) & 0x7fffffff; - // saturate - if (e > 31) { - return 0x7fffffff; + // saturate when e > 31 or e < 0 + if ((uint32_t)e > 31) { + return 0x7fffffff & ~(e >> 31); } int k = x >> (31 - LOG2_TABBITS); @@ -225,7 +225,7 @@ FORCEINLINE static int32_t peaklog2(float* input0, float* input1) { // // Peak detection and -log2(x) for float input (quad) // x < 2^(31-LOG2_HEADROOM) returns 0x7fffffff -// x > 2^LOG2_HEADROOM undefined +// x > 2^LOG2_HEADROOM returns 0 // FORCEINLINE static int32_t peaklog2(float* input0, float* input1, float* input2, float* input3) { @@ -243,12 +243,12 @@ FORCEINLINE static int32_t peaklog2(float* input0, float* input1, float* input2, uint32_t peak = MAX(MAX(u0, u1), MAX(u2, u3)); // split into e and x - 1.0 - int e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM; + int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM; int32_t x = (peak << IEEE754_EXPN_BITS) & 0x7fffffff; - // saturate - if (e > 31) { - return 0x7fffffff; + // saturate when e > 31 or e < 0 + if ((uint32_t)e > 31) { + return 0x7fffffff & ~(e >> 31); } int k = x >> (31 - LOG2_TABBITS); From 181f2b4263272fa0c4f99b5b1da57d12195e9b7d Mon Sep 17 00:00:00 2001 From: Clement Date: Wed, 28 Nov 2018 17:27:59 -0800 Subject: [PATCH 100/109] Fix Agent crash on shutdown --- assignment-client/src/avatars/ScriptableAvatar.cpp | 2 +- interface/src/avatar/MyAvatar.cpp | 2 +- libraries/avatars/src/AvatarData.h | 2 +- libraries/avatars/src/ClientTraitsHandler.cpp | 2 +- libraries/shared/src/SharedUtil.h | 7 +++++++ 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp index 51038a782f..bf5d87a6bf 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.cpp +++ b/assignment-client/src/avatars/ScriptableAvatar.cpp @@ -21,7 +21,7 @@ #include ScriptableAvatar::ScriptableAvatar() { - _clientTraitsHandler = std::unique_ptr(new ClientTraitsHandler(this)); + _clientTraitsHandler.reset(new ClientTraitsHandler(this)); } QByteArray ScriptableAvatar::toByteArrayStateful(AvatarDataDetail dataDetail, bool dropFaceTracking) { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index afebd0bb79..7196aa1a2c 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -139,7 +139,7 @@ MyAvatar::MyAvatar(QThread* thread) : _flyingHMDSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "flyingHMD", _flyingPrefHMD), _avatarEntityCountSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "avatarEntityData" << "size", 0) { - _clientTraitsHandler = std::unique_ptr(new ClientTraitsHandler(this)); + _clientTraitsHandler.reset(new ClientTraitsHandler(this)); // give the pointer to our head to inherited _headData variable from AvatarData _headData = new MyHead(this); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 36c6ed6c50..7d88cab209 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1490,7 +1490,7 @@ protected: bool _isClientAvatar { false }; // null unless MyAvatar or ScriptableAvatar sending traits data to mixer - std::unique_ptr _clientTraitsHandler; + std::unique_ptr _clientTraitsHandler; template T readLockWithNamedJointIndex(const QString& name, const T& defaultValue, F f) const { diff --git a/libraries/avatars/src/ClientTraitsHandler.cpp b/libraries/avatars/src/ClientTraitsHandler.cpp index f8247d9e52..a301341a8e 100644 --- a/libraries/avatars/src/ClientTraitsHandler.cpp +++ b/libraries/avatars/src/ClientTraitsHandler.cpp @@ -22,7 +22,7 @@ ClientTraitsHandler::ClientTraitsHandler(AvatarData* owningAvatar) : _owningAvatar(owningAvatar) { auto nodeList = DependencyManager::get(); - QObject::connect(nodeList.data(), &NodeList::nodeAdded, [this](SharedNodePointer addedNode){ + QObject::connect(nodeList.data(), &NodeList::nodeAdded, this, [this](SharedNodePointer addedNode) { if (addedNode->getType() == NodeType::AvatarMixer) { resetForNewMixer(); } diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index f36574bed6..709eeca9b2 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -113,6 +113,13 @@ void doEvery(quint64& lastReportUsecs, quint64 secs, F lamdba) { // Maximum accuracy in msecs float secTimestampNow(); +// Custom deleter for QObjects that calls deleteLater +struct LaterDeleter { + void operator()(QObject* ptr) { + ptr->deleteLater(); + } +}; + float randFloat(); int randIntInRange (int min, int max); float randFloatInRange (float min,float max); From aa749b0980e5649e974c499ea55de51a3b24ef6d Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 28 Nov 2018 21:46:13 -0800 Subject: [PATCH 101/109] adressing review comments --- .../utilities/lib/jet/qml/TaskListView.qml | 24 +------------------ .../lib/jet/qml/TaskTimeFrameView.qml | 1 - .../utilities/render/engineInspector.js | 14 ----------- .../utilities/render/engineInspector.qml | 2 +- 4 files changed, 2 insertions(+), 39 deletions(-) diff --git a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml index bc14404ee2..e2576fe783 100644 --- a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml +++ b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml @@ -26,30 +26,10 @@ Rectangle { Component.onCompleted: { - //var functor = Jet.job_tree_model_functor(jobsModel) var functor = Jet.job_tree_model_functor(jobsModel, 3, function(node) { node["cpuT"] = 0.0 }) Jet.task_traverseTree(rootConfig, functor); - - - - /* var tfunctor = Jet.job_tree_model_array_functor(jobsModel.engineJobItemModel, function(node) { - node["init"] = (node.level < 3) - node["fullpath"] = (node.path + "." + node.name) - node["cpuT"] = 0.0 - }) - - Jet.task_traverseTree(rootConfig, tfunctor); -*/ - // var currentParentStach = [] - // currentParentStach.push(jobsModel); - - - /* Jet.job_traverseTreeNodeRoot(jobsModel.engineJobItemModel[0], function(node, depth, index) { - print(node.name + depth + " - " + index) - return true - })*/ } @@ -95,15 +75,13 @@ Rectangle { HifiControls.Label { id: objLabel - // property var config: root.rootConfig.getConfig(model.path + "." + model.name); colorScheme: (root.rootConfig.getConfig(model.path + "." + model.name) ? hifi.colorSchemes.dark : hifi.colorSchemes.light) text: (objRecursiveColumn.children.length > 2 ? objRecursiveColumn.children[1].visible ? qsTr("- ") : qsTr("+ ") : qsTr(" ")) + model.name - // + " ms=" + config.cpuRunTime.toFixed(3) + " id=" + model.id } - } + } } Repeater { diff --git a/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml b/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml index e1d9bd7ce1..f3ca550e44 100644 --- a/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml +++ b/scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml @@ -166,7 +166,6 @@ Rectangle { function drawJob(ctx, depth, index, duration, timeOffset) { //print(root.jobsArray[index].cpuT) - // ctx.fillStyle = Qt.rgba(255, 255, 0, root.backgroundOpacity); ctx.fillStyle = ( depth % 2 ? ( index % 2 ? "blue" : "yellow") : ( index % 2 ? "green" : "red")) ctx.fillRect(getXFromTime(timeOffset), lineHeight * 2 * depth,getWFromDuration(duration), lineHeight); diff --git a/scripts/developer/utilities/render/engineInspector.js b/scripts/developer/utilities/render/engineInspector.js index 74e4231ff1..cd2b74f907 100644 --- a/scripts/developer/utilities/render/engineInspector.js +++ b/scripts/developer/utilities/render/engineInspector.js @@ -1,17 +1,3 @@ - /*function openEngineTaskView() { - // Set up the qml ui - var qml = Script.resolvePath('engineInspector.qml'); - var window = new OverlayWindow({ - title: 'Render Engine', - source: qml, - width: 500, - height: 100 - }); - window.setPosition(200, 50); - window.closed.connect(function() { Script.stop(); }); - } - openEngineTaskView();*/ - (function() { var TABLET_BUTTON_NAME = "Inspector"; var QMLAPP_URL = Script.resolvePath("./engineInspector.qml"); diff --git a/scripts/developer/utilities/render/engineInspector.qml b/scripts/developer/utilities/render/engineInspector.qml index 31283a4756..1e05605ac7 100644 --- a/scripts/developer/utilities/render/engineInspector.qml +++ b/scripts/developer/utilities/render/engineInspector.qml @@ -26,5 +26,5 @@ Item { Jet.TaskListView { rootConfig: root.rootConfig anchors.fill: root - } + } } \ No newline at end of file From 54fa4365b84d3a8d6e5cf0185b4b73611c517fff Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 28 Nov 2018 22:21:58 -0800 Subject: [PATCH 102/109] FIxing build issue doh... --- interface/src/Application.cpp | 6 ------ interface/src/Application_render.cpp | 3 --- 2 files changed, 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2e46043dba..d92eae5221 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5088,13 +5088,7 @@ void Application::init() { // Make sure Login state is up to date #if !defined(DISABLE_QML) DependencyManager::get()->toggleLoginDialog(); -<<<<<<< HEAD -======= #endif - if (!DISABLE_DEFERRED) { - DependencyManager::get()->init(); - } ->>>>>>> f4535e6784be56de3e3b0a21517280c12a434425 DependencyManager::get()->init(); _timerStart.start(); diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index 1e66953a49..5063f6118d 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -19,9 +19,6 @@ #include "Util.h" - - -<<<<<<< HEAD //void Application::paintGL() { // // Some plugins process message events, allowing paintGL to be called reentrantly. // From 88d935a28e755341de9ef34edb38602713d15539 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 29 Nov 2018 08:12:14 -0800 Subject: [PATCH 103/109] Fix the audio injector "pitch" property --- libraries/audio/src/AudioInjector.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 4af6e79caf..1581990e0c 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -447,9 +447,9 @@ AudioInjectorPointer AudioInjector::playSound(SharedSoundPointer sound, const A using AudioConstants::AudioSample; using AudioConstants::SAMPLE_RATE; const int standardRate = SAMPLE_RATE; - // limit to 4 octaves - const int pitch = glm::clamp(options.pitch, 1 / 16.0f, 16.0f); - const int resampledRate = SAMPLE_RATE / pitch; + // limit pitch to 4 octaves + const float pitch = glm::clamp(options.pitch, 1 / 16.0f, 16.0f); + const int resampledRate = glm::round(SAMPLE_RATE / pitch); auto audioData = sound->getAudioData(); auto numChannels = audioData->getNumChannels(); @@ -499,9 +499,9 @@ AudioInjectorPointer AudioInjector::playSound(AudioDataPointer audioData, const using AudioConstants::AudioSample; using AudioConstants::SAMPLE_RATE; const int standardRate = SAMPLE_RATE; - // limit to 4 octaves - const int pitch = glm::clamp(options.pitch, 1 / 16.0f, 16.0f); - const int resampledRate = SAMPLE_RATE / pitch; + // limit pitch to 4 octaves + const float pitch = glm::clamp(options.pitch, 1 / 16.0f, 16.0f); + const int resampledRate = glm::round(SAMPLE_RATE / pitch); auto numChannels = audioData->getNumChannels(); auto numFrames = audioData->getNumFrames(); From 59b7cdf318336ded6c26ea1b039cf7fa648c189d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 29 Nov 2018 13:10:15 -0800 Subject: [PATCH 104/109] Fix empty rgb field in Create going black --- scripts/system/html/js/colpick.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/system/html/js/colpick.js b/scripts/system/html/js/colpick.js index 505dd294d6..e4ad65dfb6 100644 --- a/scripts/system/html/js/colpick.js +++ b/scripts/system/html/js/colpick.js @@ -309,6 +309,9 @@ For usage and examples: colpick.com/plugin }, // Fix the values if the user enters a negative or high value fixHSB = function (hsb) { + hsb.h = isNaN(hsb.h) ? 0 : hsb.h; + hsb.s = isNaN(hsb.s) ? 0 : hsb.s; + hsb.b = isNaN(hsb.b) ? 0 : hsb.b; return { h: Math.min(360, Math.max(0, hsb.h)), s: Math.min(100, Math.max(0, hsb.s)), @@ -316,6 +319,9 @@ For usage and examples: colpick.com/plugin }; }, fixRGB = function (rgb) { + rgb.r = isNaN(rgb.r) ? 0 : rgb.r; + rgb.g = isNaN(rgb.g) ? 0 : rgb.g; + rgb.b = isNaN(rgb.b) ? 0 : rgb.b; return { r: Math.min(255, Math.max(0, rgb.r)), g: Math.min(255, Math.max(0, rgb.g)), From c53c52c7a018de4e9f36d807e5fa359a848e5054 Mon Sep 17 00:00:00 2001 From: Clement Date: Thu, 29 Nov 2018 17:42:04 -0800 Subject: [PATCH 105/109] Fix various Agent bugs --- assignment-client/src/Agent.cpp | 22 +++++++++++++++---- assignment-client/src/AssignmentClient.cpp | 15 +++++-------- .../src/scripts/EntityScriptServer.cpp | 20 ++++++++++++++--- libraries/recording/src/recording/Deck.cpp | 4 +--- 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 88897a0fed..bd368ef7c2 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -656,6 +656,8 @@ void Agent::queryAvatars() { ViewFrustum view; view.setPosition(scriptedAvatar->getWorldPosition()); view.setOrientation(scriptedAvatar->getHeadOrientation()); + view.setProjection(DEFAULT_FIELD_OF_VIEW_DEGREES, DEFAULT_ASPECT_RATIO, + DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP); view.calculate(); ConicalViewFrustum conicalView { view }; @@ -876,18 +878,30 @@ void Agent::aboutToFinish() { DependencyManager::destroy(); // destroy all other created dependencies - DependencyManager::destroy(); - DependencyManager::destroy(); DependencyManager::destroy(); - DependencyManager::destroy(); DependencyManager::destroy(); - DependencyManager::destroy(); + DependencyManager::destroy(); + DependencyManager::destroy(); + DependencyManager::destroy(); + DependencyManager::destroy(); + + DependencyManager::destroy(); + DependencyManager::destroy(); + DependencyManager::destroy(); + DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); + DependencyManager::destroy(); + DependencyManager::destroy(); + DependencyManager::destroy(); + DependencyManager::destroy(); + + DependencyManager::destroy(); + // drop our shared pointer to the script engine, then ask ScriptEngines to shutdown scripting // this ensures that the ScriptEngine goes down before ScriptEngines _scriptEngine.clear(); diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 76ff5ab2ed..c1943de2cc 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -129,17 +129,12 @@ void AssignmentClient::stopAssignmentClient() { QThread* currentAssignmentThread = _currentAssignment->thread(); // ask the current assignment to stop - BLOCKING_INVOKE_METHOD(_currentAssignment, "stop"); + QMetaObject::invokeMethod(_currentAssignment, "stop"); - // ask the current assignment to delete itself on its thread - _currentAssignment->deleteLater(); - - // when this thread is destroyed we don't need to run our assignment complete method - disconnect(currentAssignmentThread, &QThread::destroyed, this, &AssignmentClient::assignmentCompleted); - - // wait on the thread from that assignment - it will be gone once the current assignment deletes - currentAssignmentThread->quit(); - currentAssignmentThread->wait(); + auto PROCESS_EVENTS_INTERVAL_MS = 100; + while (!currentAssignmentThread->wait(PROCESS_EVENTS_INTERVAL_MS)) { + QCoreApplication::processEvents(); + } } } diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 272985093c..ef0c807bc4 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -583,15 +583,29 @@ void EntityScriptServer::handleOctreePacket(QSharedPointer mess void EntityScriptServer::aboutToFinish() { shutdownScriptEngine(); + DependencyManager::get()->setEntityTree(nullptr); + DependencyManager::get()->cleanup(); + + DependencyManager::destroy(); + DependencyManager::destroy(); + DependencyManager::destroy(); + DependencyManager::destroy(); + + DependencyManager::destroy(); + DependencyManager::destroy(); + + DependencyManager::destroy(); + DependencyManager::destroy(); + + DependencyManager::destroy(); + DependencyManager::destroy(); DependencyManager::destroy(); + DependencyManager::destroy(); - DependencyManager::get()->cleanup(); DependencyManager::destroy(); - DependencyManager::destroy(); - DependencyManager::destroy(); // cleanup the AudioInjectorManager (and any still running injectors) DependencyManager::destroy(); diff --git a/libraries/recording/src/recording/Deck.cpp b/libraries/recording/src/recording/Deck.cpp index 69a8587581..4d65f0eb1b 100644 --- a/libraries/recording/src/recording/Deck.cpp +++ b/libraries/recording/src/recording/Deck.cpp @@ -180,9 +180,7 @@ void Deck::processFrames() { #ifdef WANT_RECORDING_DEBUG qCDebug(recordingLog) << "Setting timer for next processing " << nextInterval; #endif - _timer.singleShot(nextInterval, [this] { - processFrames(); - }); + _timer.singleShot(nextInterval, this, &Deck::processFrames); } void Deck::removeClip(const ClipConstPointer& clip) { From 87c863584d4bc04af3a38b7d515ffb1ea5b3df25 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 29 Nov 2018 17:43:19 -0800 Subject: [PATCH 106/109] Just to remove conflict. --- tools/nitpick/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nitpick/README.md b/tools/nitpick/README.md index a02980ddfe..7d75d660d7 100644 --- a/tools/nitpick/README.md +++ b/tools/nitpick/README.md @@ -1,6 +1,6 @@ # nitpick -Nitpick is a stand alone application that provides a mechanism for regression testing. The general idea is simple: +Nitpick is a stand alone application that provides a mechanism for regression testing. The general idea is simple: * Each test folder has a script that produces a set of snapshots. * The snapshots are compared to a 'canonical' set of images that have been produced beforehand. * The result, if any test failed, is a zipped folder describing the failure. From 051b7cfbb8106007e81564a04545076f8214d8be Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 30 Nov 2018 16:12:21 -0800 Subject: [PATCH 107/109] Fix MS20117: Prevent HTML link from appearing in Wallet notification --- scripts/system/commerce/wallet.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index d5365133b6..3a8462c5cb 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -615,7 +615,9 @@ function notificationPollCallbackHistory(historyArray) { ui.notificationDisplayBanner(message); } else { for (var i = 0; i < notificationCount; i++) { - message = '"' + (historyArray[i].message) + '" ' + + var historyMessage = historyArray[i].message; + var sanitizedHistoryMessage = historyMessage.replace(/<\/?[^>]+(>|$)/g, ""); + message = '"' + sanitizedHistoryMessage + '" ' + "Open INVENTORY to see all activity."; ui.notificationDisplayBanner(message); } From c0bf832e393655d7e455c0c5789e7889673b5a65 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Sun, 2 Dec 2018 16:18:36 -0800 Subject: [PATCH 108/109] Head and Hand offsets for Vive Trackers now function as expected In the Settings > Controller... > Calibration menu, when using head or hand trackers The provided Y and Z offsets should function correctly now. This gives you the ability to adjust the offsets of the pucks to the hands/head. For example: this allows you to wear the hand pucks on your forearms rather then the backs of your palms. --- .../qml/hifi/tablet/OpenVrConfiguration.qml | 35 ++++++++++++------- plugins/openvr/src/ViveControllerManager.cpp | 32 +++++++---------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml index e18fdea444..46817e07cf 100644 --- a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml +++ b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml @@ -207,12 +207,12 @@ Flickable { width: 112 label: "Y Offset" suffix: " cm" - minimumValue: -10 + minimumValue: -50 + maximumValue: 50 realStepSize: 1 - realValue: -5 colorScheme: hifi.colorSchemes.dark - onEditingFinished: { + onRealValueChanged: { sendConfigurationSettings(); openVrConfiguration.forceActiveFocus(); } @@ -223,14 +223,14 @@ Flickable { id: headZOffset width: 112 label: "Z Offset" - minimumValue: -10 + minimumValue: -50 + maximumValue: 50 realStepSize: 1 decimals: 1 suffix: " cm" - realValue: -5 colorScheme: hifi.colorSchemes.dark - onEditingFinished: { + onRealValueChanged: { sendConfigurationSettings(); openVrConfiguration.forceActiveFocus(); } @@ -319,11 +319,12 @@ Flickable { width: 112 suffix: " cm" label: "Y Offset" - minimumValue: -10 + minimumValue: -30 + maximumValue: 30 realStepSize: 1 colorScheme: hifi.colorSchemes.dark - onEditingFinished: { + onRealValueChanged: { sendConfigurationSettings(); openVrConfiguration.forceActiveFocus(); } @@ -335,12 +336,13 @@ Flickable { width: 112 label: "Z Offset" suffix: " cm" - minimumValue: -10 + minimumValue: -30 + maximumValue: 30 realStepSize: 1 decimals: 1 colorScheme: hifi.colorSchemes.dark - onEditingFinished: { + onRealValueChanged: { sendConfigurationSettings(); openVrConfiguration.forceActiveFocus(); } @@ -574,7 +576,7 @@ Flickable { colorScheme: hifi.colorSchemes.dark realValue: 33.0 - onEditingFinished: { + onRealValueChanged: { sendConfigurationSettings(); openVrConfiguration.forceActiveFocus(); } @@ -592,7 +594,7 @@ Flickable { colorScheme: hifi.colorSchemes.dark realValue: 48 - onEditingFinished: { + onRealValueChanged: { sendConfigurationSettings(); openVrConfiguration.forceActiveFocus(); } @@ -771,7 +773,7 @@ Flickable { realStepSize: 1.0 colorScheme: hifi.colorSchemes.dark - onEditingFinished: { + onRealValueChanged: { calibrationTimer.interval = realValue * 1000; openVrConfiguration.countDown = realValue; numberAnimation.duration = calibrationTimer.interval; @@ -977,6 +979,13 @@ Flickable { var configurationType = settings["trackerConfiguration"]; displayTrackerConfiguration(configurationType); + // default offset for user wearing puck on the center of their forehead. + headYOffset.realValue = 4; // (cm), puck is above the head joint. + headZOffset.realValue = 8; // (cm), puck is in front of the head joint. + + // defaults for user wearing the pucks on the backs of their palms. + handYOffset.realValue = 8; // (cm), puck is past the the hand joint. (set this to zero if puck is on the wrist) + handZOffset.realValue = -4; // (cm), puck is on above hand joint. var HmdHead = settings["HMDHead"]; var viveController = settings["handController"]; diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index af4f4da18c..283556f86a 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -892,7 +892,7 @@ glm::mat4 ViveControllerManager::InputDevice::calculateDefaultToReferenceForHead glm::vec3 x = glm::normalize(glm::cross(Vectors::UNIT_Y, forward)); glm::vec3 z = glm::normalize(glm::cross(x, Vectors::UNIT_Y)); glm::mat3 centerEyeRotMat(x, Vectors::UNIT_Y, z); - glm::vec3 centerEyeTrans = headPuckPose.translation + centerEyeRotMat * glm::vec3(0.0f, _headPuckYOffset, _headPuckZOffset); + glm::vec3 centerEyeTrans = headPuckPose.translation + centerEyeRotMat * -glm::vec3(0.0f, _headPuckYOffset, _headPuckZOffset); glm::mat4 E_s(glm::vec4(centerEyeRotMat[0], 0.0f), glm::vec4(centerEyeRotMat[1], 0.0f), @@ -1056,7 +1056,7 @@ void ViveControllerManager::InputDevice::hapticsHelper(float deltaTime, bool lef float hapticTime = strength * MAX_HAPTIC_TIME; if (hapticTime < duration * 1000.0f) { _system->TriggerHapticPulse(deviceIndex, 0, hapticTime); - } + } float remainingHapticTime = duration - (hapticTime / 1000.0f + deltaTime * 1000.0f); // in milliseconds if (leftHand) { @@ -1077,23 +1077,20 @@ void ViveControllerManager::InputDevice::calibrateLeftHand(const glm::mat4& defa } // This allows the user to not have to match the t-pose exactly. We assume that the y facing of the hand lies in the plane of the puck. - // Where the plane of the puck is defined by the the local z-axis of the puck, which is facing out of the vive logo/power button. + // Where the plane of the puck is defined by the the local z-axis of the puck, which is pointing out of the camera mount on the bottom of the puck. glm::vec3 zPrime = handPoseZAxis; glm::vec3 xPrime = glm::normalize(glm::cross(referenceHandYAxis, handPoseZAxis)); glm::vec3 yPrime = glm::normalize(glm::cross(zPrime, xPrime)); glm::mat4 newHandMat = glm::mat4(glm::vec4(xPrime, 0.0f), glm::vec4(yPrime, 0.0f), glm::vec4(zPrime, 0.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); - glm::vec3 translationOffset = glm::vec3(0.0f, _handPuckYOffset, _handPuckZOffset); - glm::quat initialRotation = handPose.getRotation(); - glm::quat finalRotation = glmExtractRotation(newHandMat); - - glm::quat rotationOffset = glm::inverse(initialRotation) * finalRotation; - - glm::mat4 offsetMat = createMatFromQuatAndPos(rotationOffset, translationOffset); + glm::quat initialRot = handPose.getRotation(); + glm::quat postOffsetRot = glm::inverse(initialRot) * glmExtractRotation(newHandMat); + glm::vec3 postOffsetTrans = postOffsetRot * -glm::vec3(0.0f, _handPuckYOffset, _handPuckZOffset); + glm::mat4 postOffsetMat = createMatFromQuatAndPos(postOffsetRot, postOffsetTrans); _jointToPuckMap[controller::LEFT_HAND] = handPair.first; - _pucksPostOffset[handPair.first] = offsetMat; + _pucksPostOffset[handPair.first] = postOffsetMat; } void ViveControllerManager::InputDevice::calibrateRightHand(const glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration, PuckPosePair& handPair) { @@ -1113,16 +1110,13 @@ void ViveControllerManager::InputDevice::calibrateRightHand(const glm::mat4& def glm::mat4 newHandMat = glm::mat4(glm::vec4(xPrime, 0.0f), glm::vec4(yPrime, 0.0f), glm::vec4(zPrime, 0.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); - glm::vec3 translationOffset = glm::vec3(0.0f, _handPuckYOffset, _handPuckZOffset); - glm::quat initialRotation = handPose.getRotation(); - glm::quat finalRotation = glmExtractRotation(newHandMat); - - glm::quat rotationOffset = glm::inverse(initialRotation) * finalRotation; - - glm::mat4 offsetMat = createMatFromQuatAndPos(rotationOffset, translationOffset); + glm::quat initialRot = handPose.getRotation(); + glm::quat postOffsetRot = glm::inverse(initialRot) * glmExtractRotation(newHandMat); + glm::vec3 postOffsetTrans = postOffsetRot * -glm::vec3(0.0f, _handPuckYOffset, _handPuckZOffset); + glm::mat4 postOffsetMat = createMatFromQuatAndPos(postOffsetRot, postOffsetTrans); _jointToPuckMap[controller::RIGHT_HAND] = handPair.first; - _pucksPostOffset[handPair.first] = offsetMat; + _pucksPostOffset[handPair.first] = postOffsetMat; } From 541d0ab4d689b2cc50eecb00128210480576105b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 3 Dec 2018 17:33:04 -0800 Subject: [PATCH 109/109] work around menu-item name hash collision for Home --- interface/src/Menu.h | 2 +- libraries/ui/src/ui/Menu.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/interface/src/Menu.h b/interface/src/Menu.h index e0e48ff32c..7168b7294e 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -117,7 +117,7 @@ namespace MenuOption { const QString FrameTimer = "Show Timer"; const QString FullscreenMirror = "Mirror"; const QString Help = "Help..."; - const QString HomeLocation = "Home"; + const QString HomeLocation = "Home "; const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IndependentMode = "Independent Mode"; const QString ActionMotorControl = "Enable Default Motor Control"; diff --git a/libraries/ui/src/ui/Menu.h b/libraries/ui/src/ui/Menu.h index 2977a5330a..ec286b29ad 100644 --- a/libraries/ui/src/ui/Menu.h +++ b/libraries/ui/src/ui/Menu.h @@ -146,6 +146,11 @@ protected: int findPositionOfMenuItem(MenuWrapper* menu, const QString& searchMenuItem); int positionBeforeSeparatorIfNeeded(MenuWrapper* menu, int requestedPosition); + // There is a design flaw here -- _actionHash is system-wide and hashes the names of menu-items to their + // QActions. The path (parent submenu name etc) isn't included in the hash key. This generally works, + // but we add "Home" twice -- once for "go home" and once for "set startup location to home". Anytime + // a user bookmarks a place and gives it a name like an existing menu-item, something will go wrong. + // TODO: change the js api to require the full path when referring to a specific menu item. QHash _actionHash; bool isValidGrouping(const QString& grouping) const { return grouping == "Advanced" || grouping == "Developer"; }