From b6bf58d5be68ea42f55deda37dc30d293a11b14c Mon Sep 17 00:00:00 2001 From: Faye Li Date: Mon, 20 Mar 2017 15:28:30 -0700 Subject: [PATCH 01/21] rearrange layout of main tablet go to screen --- .../qml/hifi/tablet/TabletAddressDialog.qml | 209 +++++++++--------- 1 file changed, 104 insertions(+), 105 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index 952a1f7faa..3a6577f4c0 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -82,6 +82,107 @@ Item { } onMetaverseServerUrlChanged: updateLocationTextTimer.start(); + Rectangle { + id: navBar + width: 480 + height: 70 + + gradient: Gradient { + GradientStop { + position: 0 + color: "#c2ced8" + + } + + GradientStop { + position: 1 + color: "#c2ced8" + } + } + + anchors { + top: parent.top + right: parent.right + left: parent.left + } + + + ToolbarButton { + id: homeButton + imageURL: "../../../images/home.svg" + onClicked: { + addressBarDialog.loadHome(); + root.shown = false; + } + anchors { + left: parent.left + leftMargin: homeButton.width / 2 + verticalCenter: parent.verticalCenter + } + } + property int inputAreaHeight: 70 + property int inputAreaStep: (height - inputAreaHeight) / 2 + + HifiStyles.RalewayLight { + id: notice; + font.pixelSize: hifi.fonts.pixelSize * 0.50; + anchors { + top: parent.top + topMargin: parent.inputAreaStep + 12 + left: addressLine.left + right: addressLine.right + } + } + HifiStyles.FiraSansRegular { + id: location; + font.pixelSize: addressLine.font.pixelSize; + color: "gray"; + clip: true; + anchors.fill: addressLine; + visible: addressLine.text.length === 0 + } + + TextInput { + id: addressLine + focus: true + anchors { + bottom: parent.bottom + left: homeButton.right + right: parent.right + leftMargin: homeButton.width + rightMargin: homeButton.width / 2 + topMargin: parent.inputAreaStep + (2 * hifi.layout.spacing) + bottomMargin: parent.inputAreaStep + } + font.pixelSize: hifi.fonts.pixelSize * 0.75 + cursorVisible: false + onTextChanged: { + filterChoicesByText(); + updateLocationText(text.length > 0); + if (!isCursorVisible && text.length > 0) { + isCursorVisible = true; + cursorVisible = true; + } + } + onAccepted: { + addressBarDialog.keyboardEnabled = false; + } + onActiveFocusChanged: { + cursorVisible = isCursorVisible && focus; + } + MouseArea { + // If user clicks in address bar show cursor to indicate ability to enter address. + anchors.fill: parent + onClicked: { + isCursorVisible = true; + //parent.cursorVisible = true; + parent.forceActiveFocus(); + addressBarDialog.keyboardEnabled = HMD.active + tabletRoot.playButtonClickSound(); + } + } + } + } Rectangle { id: topBar height: 90 @@ -103,7 +204,7 @@ Item { anchors.left: parent.left anchors.leftMargin: 0 anchors.topMargin: 0 - anchors.top: parent.top + anchors.top: navBar.bottom Row { id: thing @@ -158,7 +259,7 @@ Item { } - anchors.bottom: backgroundImage.top + anchors.bottom: parent.keyboardEnabled ? keyboard.top : parent.bottom anchors.bottomMargin: 0 anchors.right: parent.right anchors.rightMargin: 0 @@ -210,109 +311,7 @@ Item { } } - Rectangle { - id: backgroundImage - width: 480 - height: 70 - - gradient: Gradient { - GradientStop { - position: 0 - color: "#c2ced8" - - } - - GradientStop { - position: 1 - color: "#c2ced8" - } - } - - anchors { - bottom: parent.keyboardEnabled ? keyboard.top : parent.bottom - right: parent.right - left: parent.left - } - - - ToolbarButton { - id: homeButton - imageURL: "../../../images/home.svg" - onClicked: { - addressBarDialog.loadHome(); - root.shown = false; - } - anchors { - left: parent.left - leftMargin: homeButton.width / 2 - verticalCenter: parent.verticalCenter - } - } - property int inputAreaHeight: 70 - property int inputAreaStep: (height - inputAreaHeight) / 2 - - HifiStyles.RalewayLight { - id: notice; - font.pixelSize: hifi.fonts.pixelSize * 0.50; - anchors { - top: parent.top - topMargin: parent.inputAreaStep + 12 - left: addressLine.left - right: addressLine.right - } - } - HifiStyles.FiraSansRegular { - id: location; - font.pixelSize: addressLine.font.pixelSize; - color: "gray"; - clip: true; - anchors.fill: addressLine; - visible: addressLine.text.length === 0 - } - - TextInput { - id: addressLine - focus: true - anchors { - bottom: parent.bottom - left: homeButton.right - right: parent.right - leftMargin: homeButton.width - rightMargin: homeButton.width / 2 - topMargin: parent.inputAreaStep + (2 * hifi.layout.spacing) - bottomMargin: parent.inputAreaStep - } - font.pixelSize: hifi.fonts.pixelSize * 0.75 - cursorVisible: false - onTextChanged: { - filterChoicesByText(); - updateLocationText(text.length > 0); - if (!isCursorVisible && text.length > 0) { - isCursorVisible = true; - cursorVisible = true; - } - } - onAccepted: { - addressBarDialog.keyboardEnabled = false; - } - onActiveFocusChanged: { - cursorVisible = isCursorVisible && focus; - } - MouseArea { - // If user clicks in address bar show cursor to indicate ability to enter address. - anchors.fill: parent - onClicked: { - isCursorVisible = true; - //parent.cursorVisible = true; - parent.forceActiveFocus(); - addressBarDialog.keyboardEnabled = HMD.active - tabletRoot.playButtonClickSound(); - } - } - } - } - - Timer { + Timer { // Delay updating location text a bit to avoid flicker of content and so that connection status is valid. id: updateLocationTextTimer running: false From 1d095b8158afa9f8bdd13c06b5a2f79c92b45879 Mon Sep 17 00:00:00 2001 From: Faye Li Date: Mon, 20 Mar 2017 15:57:59 -0700 Subject: [PATCH 02/21] added back forward and back button on nav bar --- .../qml/hifi/tablet/TabletAddressDialog.qml | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index 3a6577f4c0..d2af9a6999 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -87,26 +87,12 @@ Item { width: 480 height: 70 - gradient: Gradient { - GradientStop { - position: 0 - color: "#c2ced8" - - } - - GradientStop { - position: 1 - color: "#c2ced8" - } - } - anchors { top: parent.top right: parent.right left: parent.left } - ToolbarButton { id: homeButton imageURL: "../../../images/home.svg" @@ -120,10 +106,40 @@ Item { verticalCenter: parent.verticalCenter } } + ToolbarButton { + id: backArrow; + imageURL: "../../../images/backward.svg"; + onClicked: addressBarDialog.loadBack(); + anchors { + left: homeButton.right + verticalCenter: parent.verticalCenter + } + } + ToolbarButton { + id: forwardArrow; + imageURL: "../../../images/forward.svg"; + onClicked: addressBarDialog.loadForward(); + anchors { + left: backArrow.right + verticalCenter: parent.verticalCenter + } + } + } + + Rectangle { + id: addressBar + width: 480 + height: 70 + anchors { + top: navBar.bottom + right: parent.right + left: parent.left + } + property int inputAreaHeight: 70 property int inputAreaStep: (height - inputAreaHeight) / 2 - HifiStyles.RalewayLight { + HifiStyles.RalewayLight { id: notice; font.pixelSize: hifi.fonts.pixelSize * 0.50; anchors { @@ -147,10 +163,10 @@ Item { focus: true anchors { bottom: parent.bottom - left: homeButton.right + left: parent.left right: parent.right - leftMargin: homeButton.width - rightMargin: homeButton.width / 2 + leftMargin: 0 + rightMargin: 0 topMargin: parent.inputAreaStep + (2 * hifi.layout.spacing) bottomMargin: parent.inputAreaStep } @@ -204,7 +220,7 @@ Item { anchors.left: parent.left anchors.leftMargin: 0 anchors.topMargin: 0 - anchors.top: navBar.bottom + anchors.top: addressBar.bottom Row { id: thing From 9cab8b6c4a93f3c7f6959a655f7dcfec3ff4fcca Mon Sep 17 00:00:00 2001 From: Faye Li Date: Mon, 20 Mar 2017 17:04:29 -0700 Subject: [PATCH 03/21] end of day commit --- interface/resources/qml/hifi/tablet/TabletAddressDialog.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index d2af9a6999..8054c90603 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -90,7 +90,9 @@ Item { anchors { top: parent.top right: parent.right + rightMargin: 0 left: parent.left + leftMargin: 0 } ToolbarButton { @@ -102,7 +104,6 @@ Item { } anchors { left: parent.left - leftMargin: homeButton.width / 2 verticalCenter: parent.verticalCenter } } @@ -133,7 +134,9 @@ Item { anchors { top: navBar.bottom right: parent.right + rightMargin: 16 left: parent.left + leftMargin: 16 } property int inputAreaHeight: 70 From a078121c464325d0b52deacc6e37a424f43345e5 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 24 Mar 2017 00:23:13 +0100 Subject: [PATCH 04/21] saving work --- interface/resources/qml/hifi/Card.qml | 73 ++++++++++--------- .../resources/qml/hifi/TabletTextButton.qml | 64 ++++++++++++++++ .../qml/hifi/tablet/TabletAddressDialog.qml | 55 +++++--------- scripts/defaultScripts.js | 2 +- 4 files changed, 124 insertions(+), 70 deletions(-) create mode 100644 interface/resources/qml/hifi/TabletTextButton.qml diff --git a/interface/resources/qml/hifi/Card.qml b/interface/resources/qml/hifi/Card.qml index f6f7e88d0c..781149c1b3 100644 --- a/interface/resources/qml/hifi/Card.qml +++ b/interface/resources/qml/hifi/Card.qml @@ -153,44 +153,49 @@ Rectangle { margins: textPadding; } } - Row { - FiraSansRegular { - id: users; - visible: isConcurrency; - text: onlineUsers; - size: textSize; - color: messageColor; - anchors.verticalCenter: message.verticalCenter; - } - Image { - id: icon; - source: "../../images/snap-icon.svg" - width: 40; - height: 40; - visible: action === 'snapshot'; - } - RalewayRegular { - id: message; - text: isConcurrency ? ((onlineUsers === 1) ? "person" : "people") : (drillDownToPlace ? "snapshots" : ("by " + userName)); - size: textSizeSmall; - color: messageColor; - elide: Text.ElideRight; // requires a width to be specified` - width: root.width - textPadding - - (users.visible ? users.width + parent.spacing : 0) - - (icon.visible ? icon.width + parent.spacing : 0) - - (actionIcon.width + (2 * smallMargin)); + + Rectangle { + radius: 20 + color: "transparent" + Row { + FiraSansRegular { + id: users; + visible: isConcurrency; + text: onlineUsers; + size: textSize; + color: messageColor; + anchors.verticalCenter: message.verticalCenter; + } + Image { + id: icon; + source: "../../images/snap-icon.svg" + width: 40; + height: 40; + visible: action === 'snapshot'; + } + RalewayRegular { + id: message; + text: isConcurrency ? ((onlineUsers === 1) ? "person" : "people") : (drillDownToPlace ? "snapshots" : ("by " + userName)); + size: textSizeSmall; + color: messageColor; + elide: Text.ElideRight; // requires a width to be specified` + width: root.width - textPadding + - (users.visible ? users.width + parent.spacing : 0) + - (icon.visible ? icon.width + parent.spacing : 0) + - (actionIcon.width + (2 * smallMargin)); + anchors { + bottom: parent.bottom; + bottomMargin: parent.spacing; + } + } + spacing: textPadding; + height: messageHeight; anchors { bottom: parent.bottom; - bottomMargin: parent.spacing; + left: parent.left; + leftMargin: textPadding; } } - spacing: textPadding; - height: messageHeight; - anchors { - bottom: parent.bottom; - left: parent.left; - leftMargin: textPadding; - } } // These two can be supplied to provide hover behavior. // For example, AddressBarDialog provides functions that set the current list view item diff --git a/interface/resources/qml/hifi/TabletTextButton.qml b/interface/resources/qml/hifi/TabletTextButton.qml new file mode 100644 index 0000000000..20f30f002c --- /dev/null +++ b/interface/resources/qml/hifi/TabletTextButton.qml @@ -0,0 +1,64 @@ +// +// TabletTextButton.qml +// +// Created by Dante Ruiz on 2017/3/23 +// 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 +// + +import Hifi 1.0 +import QtQuick 2.4 +import "../styles-uit" + +Rectangle { + property alias text: label.text + property alias pixelSize: label.font.pixelSize; + property bool selected: false + property int spacing: 2 + property var action: function () {} + property string highlightColor: hifi.colors.blueHighlight; + width: label.width + 64 + height: 32 + color: hifi.colors.white + HifiConstants { id: hifi } + RalewaySemiBold { + id: label; + color: hifi.colors.blueHighlight; + font.pixelSize: 15; + anchors { + horizontalCenter: parent.horizontalCenter; + verticalCenter: parent.verticalCenter; + } + } + + /*Rectangle { + anchors.fill: parent + border.width: 3 + border.color: clickArea.containMouse ? highlightColor : "transparent" + color: "transparent" + }*/ + + Rectangle { + id: indicator + width: parent.width + height: 3 + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + color: hifi.colors.blueHighlight + visible: parent.selected + } + + MouseArea { + id: clickArea; + anchors.fill: parent; + acceptedButtons: Qt.LeftButton; + onClicked: action(parent); + hoverEnabled: true; + } +} + diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index 8054c90603..9e68d3435a 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -28,7 +28,7 @@ Item { height: parent.height property var allStories: []; - property int cardWidth: 370; + property int cardWidth: 460; property int cardHeight: 320; property string metaverseBase: addressBarDialog.metaverseServerUrl + "/api/v1/"; @@ -86,7 +86,7 @@ Item { id: navBar width: 480 height: 70 - + color: hifi.colors.white anchors { top: parent.top right: parent.right @@ -201,22 +201,17 @@ Item { } } } + + Rectangle { + anchors.fill: addressLine + color: hifiStyleConstants.colors.baseGray + opacity: 0.1 + } } Rectangle { id: topBar - height: 90 - gradient: Gradient { - GradientStop { - position: 0 - color: "#2b2b2b" - - } - - GradientStop { - position: 1 - color: "#1e1e1e" - } - } + height: 37 + color: hifi.colors.white anchors.right: parent.right anchors.rightMargin: 0 @@ -227,14 +222,15 @@ Item { Row { id: thing - spacing: 2 * hifi.layout.spacing + spacing: 5 * hifi.layout.spacing anchors { top: parent.top; left: parent.left + leftMargin: 25 } - TextButton { + TabletTextButton { id: allTab; text: "ALL"; property string includeActions: 'snapshot, concurrency'; @@ -242,7 +238,7 @@ Item { action: tabSelect; } - TextButton { + TabletTextButton { id: placeTab; text: "PLACES"; property string includeActions: 'concurrency'; @@ -251,7 +247,7 @@ Item { } - TextButton { + TabletTextButton { id: snapTab; text: "SNAP"; property string includeActions: 'snapshot'; @@ -264,20 +260,7 @@ Item { Rectangle { id: bgMain - gradient: Gradient { - GradientStop { - position: 0 - color: "#2b2b2b" - - } - - GradientStop { - position: 1 - color: "#0f212e" - } - } - - + color: hifi.colors.white anchors.bottom: parent.keyboardEnabled ? keyboard.top : parent.bottom anchors.bottomMargin: 0 anchors.right: parent.right @@ -292,7 +275,7 @@ Item { ListView { id: scroll - property int stackedCardShadowHeight: 10; + property int stackedCardShadowHeight: 0; clip: true spacing: 14 anchors { @@ -300,7 +283,9 @@ Item { top: parent.top left: parent.left right: parent.right - leftMargin: 50 + leftMargin: 10 + verticalCenter: parent.verticalCenter; + horizontalCenter: parent.horizontalCenter; } model: suggestions orientation: ListView.Vertical diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index aba2f35e6b..109b92d33a 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -21,7 +21,7 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/snapshot.js", "system/help.js", "system/pal.js", // "system/mod.js", // older UX, if you prefer - "system/goto.js", + "system/tablet-goto.js", "system/marketplaces/marketplaces.js", "system/edit.js", "system/tablet-users.js", From 618344fe98aa712871c1513a92c7a6e571fef9be Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 23 Mar 2017 18:10:09 -0700 Subject: [PATCH 05/21] Fixing the bug regarding the numMIps allocated by GLBackend and breaking the HalfRezDepthTexture --- .../gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp | 2 +- .../gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp | 6 ++++-- libraries/gpu/src/gpu/Texture.h | 13 +++++-------- libraries/gpu/src/gpu/Texture_ktx.cpp | 2 +- .../render-utils/src/AmbientOcclusionEffect.cpp | 5 +++-- libraries/render-utils/src/SurfaceGeometryPass.cpp | 2 +- tests/render-texture-load/src/main.cpp | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 8dbef09f06..46672b3b65 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -72,7 +72,7 @@ GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& incrementTextureGPUCount(); withPreservedTexture([&] { GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), _gpuObject.getStoredMipFormat()); - auto numMips = _gpuObject.evalNumMips(); + auto numMips = _gpuObject.getNumMipLevels(); for (uint16_t mipLevel = 0; mipLevel < numMips; ++mipLevel) { // Get the mip level dimensions, accounting for the downgrade level Vec3u dimensions = _gpuObject.evalMipDimensions(mipLevel); diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 36aaf75e81..c82c13c57c 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -186,8 +186,10 @@ GL45FixedAllocationTexture::~GL45FixedAllocationTexture() { void GL45FixedAllocationTexture::allocateStorage() const { const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); const auto dimensions = _gpuObject.getDimensions(); - const auto mips = _gpuObject.evalNumMips(); + const auto mips = _gpuObject.getNumMipLevels(); + glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); + glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0); } void GL45FixedAllocationTexture::syncSampler() const { @@ -214,7 +216,7 @@ GL45AttachmentTexture::~GL45AttachmentTexture() { using GL45StrictResourceTexture = GL45Backend::GL45StrictResourceTexture; GL45StrictResourceTexture::GL45StrictResourceTexture(const std::weak_ptr& backend, const Texture& texture) : GL45FixedAllocationTexture(backend, texture) { - auto mipLevels = _gpuObject.evalNumMips(); + auto mipLevels = _gpuObject.getNumMipLevels(); for (uint16_t sourceMip = 0; sourceMip < mipLevels; ++sourceMip) { uint16_t targetMip = sourceMip; size_t maxFace = GLTexture::getFaceCount(_target); diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index f7297b3280..ce71b41b77 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -418,8 +418,8 @@ public: uint32 evalTotalSize(uint16 startingMip = 0) const { uint32 size = 0; - uint16 minMipLevel = std::max(minMip(), startingMip); - uint16 maxMipLevel = maxMip(); + uint16 minMipLevel = std::max(getMinMip(), startingMip); + uint16 maxMipLevel = getMaxMip(); for (uint16 l = minMipLevel; l <= maxMipLevel; l++) { size += evalMipSize(l); } @@ -429,12 +429,9 @@ public: // max mip is in the range [ 0 if no sub mips, log2(max(width, height, depth))] // if autoGenerateMip is on => will provide the maxMIp level specified // else provide the deepest mip level provided through assignMip - uint16 maxMip() const { return _maxMip; } - - uint16 minMip() const { return _minMip; } - - uint16 mipLevels() const { return _maxMip + 1; } - + uint16 getMaxMip() const { return _maxMip; } + uint16 getMinMip() const { return _minMip; } + uint16 getNumMipLevels() const { return _maxMip + 1; } uint16 usedMipLevels() const { return (_maxMip - _minMip) + 1; } const std::string& source() const { return _source; } diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 5f0ededee7..ab5be7475a 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -121,7 +121,7 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) { } // Number level of mips coming - header.numberOfMipmapLevels = texture.maxMip() + 1; + header.numberOfMipmapLevels = texture.getNumMipLevels(); ktx::Images images; for (uint32_t level = 0; level < header.numberOfMipmapLevels; level++) { diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index 4a8f4d1dbc..b50b85fa39 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -74,11 +74,12 @@ void AmbientOcclusionFramebuffer::allocate() { auto width = _frameSize.x; auto height = _frameSize.y; - _occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + // _occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _occlusionTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusion")); _occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture); - _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusionBlurred")); _occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture); } diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index 3a23e70664..a9c0b79704 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -83,7 +83,7 @@ void LinearDepthFramebuffer::allocate() { gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _halfLinearDepthTexture->autoGenerateMips(5); - _halfNormalTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB), _halfFrameSize.x, _halfFrameSize.y, + _halfNormalTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, _halfFrameSize.x, _halfFrameSize.y, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _downsampleFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("halfLinearDepth")); diff --git a/tests/render-texture-load/src/main.cpp b/tests/render-texture-load/src/main.cpp index d924f76232..f426cd8024 100644 --- a/tests/render-texture-load/src/main.cpp +++ b/tests/render-texture-load/src/main.cpp @@ -456,7 +456,7 @@ protected: return; } auto texture = _textures[_currentTextureIndex]; - texture->setMinMip(texture->minMip() + 1); + texture->setMinMip(texture->getMinMip() + 1); } void loadTexture() { From 022e91b35dedfa3420e8b094909a4ad4bdd5c2c8 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Fri, 24 Mar 2017 00:26:14 -0700 Subject: [PATCH 06/21] Clean comments and pixel format used --- libraries/gpu-gl/src/gpu/gl/GLTexture.cpp | 2 +- .../gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp | 10 +++++----- libraries/render-utils/src/AmbientOcclusionEffect.cpp | 5 ++--- libraries/render-utils/src/SurfaceGeometryPass.cpp | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp index 1de820e1df..c93c6d98ee 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp @@ -8,7 +8,7 @@ #include "GLTexture.h" -#include +//#include #include "GLBackend.h" diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp index d54ad1ea4b..188fff9979 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp @@ -461,10 +461,10 @@ void GL45ResourceTexture::allocateStorage(uint16 allocatedMip) { _allocatedMip = allocatedMip; const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); const auto dimensions = _gpuObject.evalMipDimensions(_allocatedMip); - const auto totalMips = _gpuObject.evalNumMips(); + const auto totalMips = _gpuObject.getNumMipLevels(); const auto mips = totalMips - _allocatedMip; glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); - auto mipLevels = _gpuObject.evalNumMips(); + auto mipLevels = _gpuObject.getNumMipLevels(); _size = 0; for (uint16_t mip = _allocatedMip; mip < mipLevels; ++mip) { _size += _gpuObject.evalMipSize(mip); @@ -474,7 +474,7 @@ void GL45ResourceTexture::allocateStorage(uint16 allocatedMip) { } void GL45ResourceTexture::copyMipsFromTexture() { - auto mipLevels = _gpuObject.evalNumMips(); + auto mipLevels = _gpuObject.getNumMipLevels(); size_t maxFace = GLTexture::getFaceCount(_target); for (uint16_t sourceMip = _populatedMip; sourceMip < mipLevels; ++sourceMip) { uint16_t targetMip = sourceMip - _allocatedMip; @@ -499,7 +499,7 @@ void GL45ResourceTexture::promote() { uint16_t oldAllocatedMip = _allocatedMip; // allocate storage for new level allocateStorage(_allocatedMip - std::min(_allocatedMip, 2)); - uint16_t mips = _gpuObject.evalNumMips(); + uint16_t mips = _gpuObject.getNumMipLevels(); // copy pre-existing mips for (uint16_t mip = _populatedMip; mip < mips; ++mip) { auto mipDimensions = _gpuObject.evalMipDimensions(mip); @@ -532,7 +532,7 @@ void GL45ResourceTexture::demote() { const_cast(_id) = allocate(_gpuObject); allocateStorage(_allocatedMip + 1); _populatedMip = std::max(_populatedMip, _allocatedMip); - uint16_t mips = _gpuObject.evalNumMips(); + uint16_t mips = _gpuObject.getNumMipLevels(); // copy pre-existing mips for (uint16_t mip = _populatedMip; mip < mips; ++mip) { auto mipDimensions = _gpuObject.evalMipDimensions(mip); diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index b50b85fa39..3bacf85273 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -73,12 +73,11 @@ void AmbientOcclusionFramebuffer::allocate() { auto width = _frameSize.x; auto height = _frameSize.y; - - // _occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _occlusionTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusion")); _occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture); - + _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusionBlurred")); _occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture); diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index a9c0b79704..f713e3ce75 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -72,14 +72,14 @@ void LinearDepthFramebuffer::allocate() { auto height = _frameSize.y; // For Linear Depth: - _linearDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), width, height, + _linearDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RED), width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("linearDepth")); _linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture); _linearDepthFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat()); // For Downsampling: - _halfLinearDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), _halfFrameSize.x, _halfFrameSize.y, + _halfLinearDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RED), _halfFrameSize.x, _halfFrameSize.y, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _halfLinearDepthTexture->autoGenerateMips(5); From 13b3809fe325e031b48c62542d2e6be5a7d5d305 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 24 Mar 2017 11:04:52 -0700 Subject: [PATCH 07/21] removing includes if possible --- libraries/gpu-gl/src/gpu/gl/GLTexture.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp index c93c6d98ee..65c5788227 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp @@ -8,8 +8,6 @@ #include "GLTexture.h" -//#include - #include "GLBackend.h" using namespace gpu; From d9046a1982c1b760edf4e3a3e66a9390e9caa1a6 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 24 Mar 2017 23:54:54 +0100 Subject: [PATCH 08/21] goto on the tablet --- interface/resources/qml/hifi/Card.qml | 84 +++++------ .../qml/hifi/tablet/TabletAddressDialog.qml | 26 ++-- .../qml/hifi/tablet/TabletStoryCard.qml | 132 ++++++++++++++++++ 3 files changed, 190 insertions(+), 52 deletions(-) create mode 100644 interface/resources/qml/hifi/tablet/TabletStoryCard.qml diff --git a/interface/resources/qml/hifi/Card.qml b/interface/resources/qml/hifi/Card.qml index 781149c1b3..01a5441380 100644 --- a/interface/resources/qml/hifi/Card.qml +++ b/interface/resources/qml/hifi/Card.qml @@ -129,7 +129,7 @@ Rectangle { property int dropSamples: 9; property int dropSpread: 0; DropShadow { - visible: showPlace && (desktop ? desktop.gradientsSupported : false) + visible: true;//showPlace && (desktop ? desktop.gradientsSupported : false) source: place; anchors.fill: place; horizontalOffset: dropHorizontalOffset; @@ -139,12 +139,12 @@ Rectangle { color: hifi.colors.black; spread: dropSpread; } - RalewaySemiBold { + RalewayLight { id: place; visible: showPlace; text: placeName; color: hifi.colors.white; - size: textSize; + size: 38; elide: Text.ElideRight; // requires constrained width anchors { top: parent.top; @@ -154,48 +154,44 @@ Rectangle { } } - Rectangle { - radius: 20 - color: "transparent" - Row { - FiraSansRegular { - id: users; - visible: isConcurrency; - text: onlineUsers; - size: textSize; - color: messageColor; - anchors.verticalCenter: message.verticalCenter; - } - Image { - id: icon; - source: "../../images/snap-icon.svg" - width: 40; - height: 40; - visible: action === 'snapshot'; - } - RalewayRegular { - id: message; - text: isConcurrency ? ((onlineUsers === 1) ? "person" : "people") : (drillDownToPlace ? "snapshots" : ("by " + userName)); - size: textSizeSmall; - color: messageColor; - elide: Text.ElideRight; // requires a width to be specified` - width: root.width - textPadding - - (users.visible ? users.width + parent.spacing : 0) - - (icon.visible ? icon.width + parent.spacing : 0) - - (actionIcon.width + (2 * smallMargin)); - anchors { - bottom: parent.bottom; - bottomMargin: parent.spacing; - } - } - spacing: textPadding; - height: messageHeight; + Row { + FiraSansRegular { + id: users; + visible: isConcurrency; + text: onlineUsers; + size: textSize; + color: messageColor; + anchors.verticalCenter: message.verticalCenter; + } + Image { + id: icon; + source: "../../images/snap-icon.svg" + width: 40; + height: 40; + visible: action === 'snapshot'; + } + RalewayRegular { + id: message; + text: isConcurrency ? ((onlineUsers === 1) ? "person" : "people") : (drillDownToPlace ? "snapshots" : ("by " + userName)); + size: textSizeSmall; + color: messageColor; + elide: Text.ElideRight; // requires a width to be specified` + width: root.width - textPadding + - (users.visible ? users.width + parent.spacing : 0) + - (icon.visible ? icon.width + parent.spacing : 0) + - (actionIcon.width + (2 * smallMargin)); anchors { bottom: parent.bottom; - left: parent.left; - leftMargin: textPadding; + bottomMargin: parent.spacing; } } + spacing: textPadding; + height: messageHeight; + anchors { + bottom: parent.bottom; + left: parent.left; + leftMargin: textPadding; + } } // These two can be supplied to provide hover behavior. // For example, AddressBarDialog provides functions that set the current list view item @@ -221,6 +217,12 @@ Rectangle { margins: smallMargin; } } + DropShadow { + anchors.fill: actionIcon + radius: 8.0 + color: "#80000000" + source: actionIcon + } MouseArea { id: messageArea; width: parent.width; diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index 9e68d3435a..bfecf5457b 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -1,7 +1,7 @@ // // TabletAddressDialog.qml // -// Created by Dante Ruiz on 2016/07/16 +// Created by Dante Ruiz on 2017/03/16 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -9,7 +9,8 @@ // import Hifi 1.0 -import QtQuick 2.4 +import QtQuick 2.5 +import QtQuick.Controls 1.4 import QtGraphicalEffects 1.0 import "../../controls" import "../../styles" @@ -19,11 +20,11 @@ import "../toolbars" import "../../styles-uit" as HifiStyles import "../../controls-uit" as HifiControls -Item { +StackView { id: root HifiConstants { id: hifi } HifiStyles.HifiConstants { id: hifiStyleConstants } - + initialItem: addressBarDialog width: parent.width height: parent.height @@ -32,7 +33,7 @@ Item { property int cardHeight: 320; property string metaverseBase: addressBarDialog.metaverseServerUrl + "/api/v1/"; - + Component { id: tabletStoryCard; TabletStoryCard {} } Component.onCompleted: { fillDestinations(); updateLocationText(); @@ -42,7 +43,7 @@ Item { Component.onDestruction: { root.parentChanged.disconnect(center); } - + function center() { // Explicitly center in order to avoid warnings at shutdown anchors.centerIn = parent; @@ -54,6 +55,9 @@ Item { } function goCard(targetString) { if (0 !== targetString.indexOf('hifi://')) { + var card = tabletStoryCard.createObject(); + card.setUrl(addressBarDialog.metaverseServerUrl + targetString); + root.push(card); return; } addressLine.text = targetString; @@ -86,7 +90,7 @@ Item { id: navBar width: 480 height: 70 - color: hifi.colors.white + color: hifiStyleConstants.colors.white anchors { top: parent.top right: parent.right @@ -194,7 +198,7 @@ Item { anchors.fill: parent onClicked: { isCursorVisible = true; - //parent.cursorVisible = true; + parent.cursorVisible = true; parent.forceActiveFocus(); addressBarDialog.keyboardEnabled = HMD.active tabletRoot.playButtonClickSound(); @@ -204,14 +208,14 @@ Item { Rectangle { anchors.fill: addressLine - color: hifiStyleConstants.colors.baseGray + color: hifiStyleConstants.colors.lightGray opacity: 0.1 } } Rectangle { id: topBar height: 37 - color: hifi.colors.white + color: hifiStyleConstants.colors.white anchors.right: parent.right anchors.rightMargin: 0 @@ -260,7 +264,7 @@ Item { Rectangle { id: bgMain - color: hifi.colors.white + color: hifiStyleConstants.colors.white anchors.bottom: parent.keyboardEnabled ? keyboard.top : parent.bottom anchors.bottomMargin: 0 anchors.right: parent.right diff --git a/interface/resources/qml/hifi/tablet/TabletStoryCard.qml b/interface/resources/qml/hifi/tablet/TabletStoryCard.qml new file mode 100644 index 0000000000..ea6a23cb10 --- /dev/null +++ b/interface/resources/qml/hifi/tablet/TabletStoryCard.qml @@ -0,0 +1,132 @@ +// +// TabletAddressDialog.qml +// +// Created by Dante Ruiz on 2017/04/24 +// 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 +// + +import Hifi 1.0 +import QtQuick 2.4 +import QtGraphicalEffects 1.0 +import "../../controls" +import "../../styles" +import "../../windows" +import "../" +import "../toolbars" +import "../../styles-uit" as HifiStyles +import "../../controls-uit" as HifiControls + + +Rectangle { + id: cardRoot + HifiStyles.HifiConstants { id: hifi } + width: parent.width + height: parent.height + property string address: "" + + function setUrl(url) { + cardRoot.address = url; + webview.url = url; + } + + function goBack() { + } + + function visit() { + } + + Rectangle { + id: header + anchors { + left: parent.left + right: parent.right + top: parent.top + } + + width: parent.width + height: 50 + color: hifi.colors.white + + Row { + anchors.fill: parent + spacing: 80 + + Item { + id: backButton + anchors { + top: parent.top + left: parent.left + leftMargin: 100 + } + height: parent.height + width: parent.height + + HifiStyles.FiraSansSemiBold { + text: "BACK" + elide: Text.ElideRight + anchors.fill: parent + size: 16 + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + + color: hifi.colors.lightGray + + MouseArea { + id: backButtonMouseArea + anchors.fill: parent + hoverEnabled: enabled + + onClicked: { + webview.goBack(); + } + } + } + } + + Item { + id: closeButton + anchors { + top: parent.top + right: parent.right + rightMargin: 100 + } + height: parent.height + width: parent.height + + HifiStyles.FiraSansSemiBold { + text: "CLOSE" + elide: Text.ElideRight + anchors.fill: parent + size: 16 + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + + color: hifi.colors.lightGray + + MouseArea { + id: closeButtonMouseArea + anchors.fill: parent + hoverEnabled: enabled + + onClicked: root.pop(); + } + } + } + } + } + + HifiControls.WebView { + id: webview + anchors { + top: header.bottom + right: parent.right + left: parent.left + bottom: parent.bottom + } + } +} From 9e2768cc84b98ae24436d594d1750c11bb292c0e Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Sat, 25 Mar 2017 01:06:21 +0100 Subject: [PATCH 09/21] saving work --- interface/resources/qml/hifi/tablet/TabletRoot.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index febb2793ec..8037c1280e 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -31,7 +31,8 @@ Item { Component { id: customInputDialogBuilder; TabletCustomQueryDialog { } } function customInputDialog(properties) { - return customInputDialogBuilder.createObject(tabletRoot, properties); + openModal = customInputDialogBuilder.createObject(tabletRoot, properties); + return openModal; } Component { id: fileDialogBuilder; TabletFileDialog { } } From 2a59139c7691e8e0e39945d4d6bbeb72fa06946a Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Sat, 25 Mar 2017 01:17:37 +0100 Subject: [PATCH 10/21] trying to fix focus issue --- interface/resources/qml/hifi/tablet/TabletAddressDialog.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index bfecf5457b..e19f8ef72b 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -35,6 +35,8 @@ StackView { Component { id: tabletStoryCard; TabletStoryCard {} } Component.onCompleted: { + root.currentItem.focus = true; + root.currentItem.forceActiveFocus(); fillDestinations(); updateLocationText(); root.parentChanged.connect(center); @@ -199,6 +201,7 @@ StackView { onClicked: { isCursorVisible = true; parent.cursorVisible = true; + parent.focus = true; parent.forceActiveFocus(); addressBarDialog.keyboardEnabled = HMD.active tabletRoot.playButtonClickSound(); From c21b8b4eacb52ece02c655fb15cf72543364b727 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 26 Mar 2017 08:48:08 -0700 Subject: [PATCH 11/21] raise max mesh count for static collision entities from 500 to 1000 --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index e94e5df9cb..487a3e1e56 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -812,7 +812,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { auto& meshes = _model->getGeometry()->getMeshes(); int32_t numMeshes = (int32_t)(meshes.size()); - const int MAX_ALLOWED_MESH_COUNT = 500; + const int MAX_ALLOWED_MESH_COUNT = 1000; if (numMeshes > MAX_ALLOWED_MESH_COUNT) { // too many will cause the deadlock timer to throw... shapeInfo.setParams(SHAPE_TYPE_BOX, 0.5f * dimensions); From b8eac7abef903c6f65206db6ff8106a74eb25620 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 27 Mar 2017 16:17:50 +0100 Subject: [PATCH 12/21] revoming useless code --- interface/resources/qml/hifi/Card.qml | 2 +- interface/resources/qml/hifi/TabletTextButton.qml | 6 ------ interface/resources/qml/hifi/tablet/TabletAddressDialog.qml | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/interface/resources/qml/hifi/Card.qml b/interface/resources/qml/hifi/Card.qml index 01a5441380..3d1ae0e64b 100644 --- a/interface/resources/qml/hifi/Card.qml +++ b/interface/resources/qml/hifi/Card.qml @@ -129,7 +129,7 @@ Rectangle { property int dropSamples: 9; property int dropSpread: 0; DropShadow { - visible: true;//showPlace && (desktop ? desktop.gradientsSupported : false) + visible: true; source: place; anchors.fill: place; horizontalOffset: dropHorizontalOffset; diff --git a/interface/resources/qml/hifi/TabletTextButton.qml b/interface/resources/qml/hifi/TabletTextButton.qml index 20f30f002c..12e53eb217 100644 --- a/interface/resources/qml/hifi/TabletTextButton.qml +++ b/interface/resources/qml/hifi/TabletTextButton.qml @@ -33,12 +33,6 @@ Rectangle { } } - /*Rectangle { - anchors.fill: parent - border.width: 3 - border.color: clickArea.containMouse ? highlightColor : "transparent" - color: "transparent" - }*/ Rectangle { id: indicator diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index e19f8ef72b..623054f233 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -45,7 +45,7 @@ StackView { Component.onDestruction: { root.parentChanged.disconnect(center); } - + function center() { // Explicitly center in order to avoid warnings at shutdown anchors.centerIn = parent; From f4255735a9fa1448af9690094ad25fca775dad89 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 27 Mar 2017 18:03:38 +0100 Subject: [PATCH 13/21] make login screen show up on the tablet on startup --- interface/src/ui/LoginDialog.cpp | 10 +++++----- .../script-engine/src/TabletScriptingInterface.cpp | 14 ++++++++++++++ .../script-engine/src/TabletScriptingInterface.h | 4 ++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index dce76eb661..1fe09e7cec 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -47,11 +47,11 @@ void LoginDialog::showWithSelection() if (tablet->getToolbarMode()) { LoginDialog::show(); } else { - if (!hmd->getShouldShowTablet() && !qApp->isHMDMode()) { - LoginDialog::show(); - } else { - static const QUrl url("../../dialogs/TabletLoginDialog.qml"); - tablet->pushOntoStack(url); + static const QUrl url("../../dialogs/TabletLoginDialog.qml"); + qDebug() << "[DR] -> Push login onto the tablet"; + tablet->initialScreen(url); + if (!hmd->getShouldShowTablet()) { + hmd->openTablet(); } } } diff --git a/libraries/script-engine/src/TabletScriptingInterface.cpp b/libraries/script-engine/src/TabletScriptingInterface.cpp index 054cf83744..c287fbcfe7 100644 --- a/libraries/script-engine/src/TabletScriptingInterface.cpp +++ b/libraries/script-engine/src/TabletScriptingInterface.cpp @@ -250,6 +250,15 @@ static QString getUsername() { } } +void TabletProxy::initialScreen(const QVariant& url) { + if (getQmlTablet()) { + pushOntoStack(url); + } else { + _initialScreen = true; + _initialPath = url; + } +} + bool TabletProxy::isMessageDialogOpen() { if (_qmlTabletRoot) { QVariant result; @@ -299,6 +308,11 @@ void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscr QMetaObject::invokeMethod(_qmlTabletRoot, "setUsername", Q_ARG(const QVariant&, QVariant(getUsername()))); } }); + + if (_initialScreen) { + pushOntoStack(_initialPath); + _initialScreen = false; + } } else { removeButtonsFromHomeScreen(); _state = State::Uninitialized; diff --git a/libraries/script-engine/src/TabletScriptingInterface.h b/libraries/script-engine/src/TabletScriptingInterface.h index acc53653f8..2e7b91fa4c 100644 --- a/libraries/script-engine/src/TabletScriptingInterface.h +++ b/libraries/script-engine/src/TabletScriptingInterface.h @@ -97,6 +97,8 @@ public: bool getToolbarMode() const { return _toolbarMode; } void setToolbarMode(bool toolbarMode); + void initialScreen(const QVariant& url); + /**jsdoc * transition to the home screen * @function TabletProxy#gotoHomeScreen @@ -213,6 +215,8 @@ protected: void addButtonsToToolbar(); void removeButtonsFromToolbar(); + bool _initialScreen { false }; + QVariant _initialPath { "" }; QString _name; std::mutex _mutex; std::vector> _tabletButtonProxies; From 5796cbc898b3c82a02718339f6b25704e7d3af01 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 27 Mar 2017 10:26:33 -0700 Subject: [PATCH 14/21] Bug-fix for touching deleted entities or overlays. --- .../system/controllers/handControllerGrab.js | 51 ++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index c8b78b4d08..c93a721248 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -28,7 +28,7 @@ Script.include("/~/system/libraries/controllers.js"); // var WANT_DEBUG = false; -var WANT_DEBUG_STATE = true; +var WANT_DEBUG_STATE = false; var WANT_DEBUG_SEARCH_NAME = null; var FORCE_IGNORE_IK = false; @@ -670,12 +670,12 @@ function sendTouchMoveEventToStylusTarget(hand, stylusTarget) { } } +// will return undefined if entity does not exist. function calculateStylusTargetFromEntity(stylusTip, entityID) { var props = entityPropertiesCache.getProps(entityID); - - // entity could have been deleted. - if (props === undefined) { - return undefined; + if (props.rotation === undefined) { + // if rotation is missing from props object, then this entity has probably been deleted. + return; } // project stylus tip onto entity plane. @@ -706,16 +706,18 @@ function calculateStylusTargetFromEntity(stylusTip, entityID) { }; } +// will return undefined if overlayID does not exist. function calculateStylusTargetFromOverlay(stylusTip, overlayID) { var overlayPosition = Overlays.getProperty(overlayID, "position"); - - // overlay could have been deleted. if (overlayPosition === undefined) { - return undefined; + return; } // project stylusTip onto overlay plane. var overlayRotation = Overlays.getProperty(overlayID, "rotation"); + if (overlayRotation === undefined) { + return; + } var normal = Vec3.multiplyQbyV(overlayRotation, {x: 0, y: 0, z: 1}); var distance = Vec3.dot(Vec3.subtract(stylusTip.position, overlayPosition), normal); var position = Vec3.subtract(stylusTip.position, Vec3.multiply(normal, distance)); @@ -724,16 +726,28 @@ function calculateStylusTargetFromOverlay(stylusTip, overlayID) { var invRot = Quat.inverse(overlayRotation); var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, overlayPosition)); var dpi = Overlays.getProperty(overlayID, "dpi"); + if (dpi === undefined) { + return; + } var dimensions; if (dpi) { // Calculate physical dimensions for web3d overlay from resolution and dpi; "dimensions" property is used as a scale. var resolution = Overlays.getProperty(overlayID, "resolution"); + if (resolution === undefined) { + return; + } resolution.z = 1; // Circumvent divide-by-zero. var scale = Overlays.getProperty(overlayID, "dimensions"); + if (scale === undefined) { + return; + } scale.z = 0.01; // overlay dimensions are 2D, not 3D. dimensions = Vec3.multiplyVbyV(Vec3.multiply(resolution, INCHES_TO_METERS / dpi), scale); } else { dimensions = Overlays.getProperty(overlayID, "dimensions"); + if (dimensions === undefined) { + return; + } if (!dimensions.z) { dimensions.z = 0.01; // sometimes overlay dimensions are 2D, not 3D. } @@ -1631,22 +1645,31 @@ function MyController(hand) { var stylusTargets = []; var candidateEntities = Entities.findEntities(tipPosition, WEB_DISPLAY_STYLUS_DISTANCE); entityPropertiesCache.addEntities(candidateEntities); - var i, props; + var i, props, stylusTarget; for (i = 0; i < candidateEntities.length; i++) { props = entityPropertiesCache.getProps(candidateEntities[i]); if (props && (props.type === "Web" || this.isTablet(candidateEntities[i]))) { - stylusTargets.push(calculateStylusTargetFromEntity(this.stylusTip, candidateEntities[i])); + stylusTarget = calculateStylusTargetFromEntity(this.stylusTip, candidateEntities[i]); + if (stylusTarget) { + stylusTargets.push(stylusTarget); + } } } // add the tabletScreen, if it is valid if (HMD.tabletScreenID && HMD.tabletScreenID !== NULL_UUID && Overlays.getProperty(HMD.tabletScreenID, "visible")) { - stylusTargets.push(calculateStylusTargetFromOverlay(this.stylusTip, HMD.tabletScreenID)); + stylusTarget = calculateStylusTargetFromOverlay(this.stylusTip, HMD.tabletScreenID); + if (stylusTarget) { + stylusTargets.push(stylusTarget); + } } // add the tablet home button. if (HMD.homeButtonID && HMD.homeButtonID !== NULL_UUID && Overlays.getProperty(HMD.homeButtonID, "visible")) { - stylusTargets.push(calculateStylusTargetFromOverlay(this.stylusTip, HMD.homeButtonID)); + stylusTarget = calculateStylusTargetFromOverlay(this.stylusTip, HMD.homeButtonID); + if (stylusTarget) { + stylusTargets.push(stylusTarget); + } } var TABLET_MIN_HOVER_DISTANCE = 0.01; @@ -3582,6 +3605,10 @@ function MyController(hand) { this.stylusTouchingExit = function () { + if (this.stylusTarget === undefined) { + return; + } + // special case to handle home button. if (this.stylusTarget.overlayID === HMD.homeButtonID) { Messages.sendLocalMessage("home", this.stylusTarget.overlayID); From cba7adf32a3f0f8a3f37740f2e7306b06bc56d29 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 27 Mar 2017 19:08:41 +0100 Subject: [PATCH 15/21] removed qDebug --- interface/src/ui/LoginDialog.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index 1fe09e7cec..10783afd23 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -48,7 +48,6 @@ void LoginDialog::showWithSelection() LoginDialog::show(); } else { static const QUrl url("../../dialogs/TabletLoginDialog.qml"); - qDebug() << "[DR] -> Push login onto the tablet"; tablet->initialScreen(url); if (!hmd->getShouldShowTablet()) { hmd->openTablet(); From a0c42bacdba585c06423078ab1ab6e2649bda401 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 27 Mar 2017 14:26:17 -0700 Subject: [PATCH 16/21] Fix problem with ContextMenu triggering on button up and button down. This is fixed by clearing the ButtonPressedMap in the KeyboardMouseDevice every update. Previously, this button would never be cleared, causing other controller actions mapped to the same button to have the incorrect state. In this case, ContextMenu action would become 2 when pressed and 1 when released, anytime after the right mouse button was pressed. --- .../input-plugins/src/input-plugins/KeyboardMouseDevice.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index ddb2f482a1..b5a2fc6b3c 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -25,6 +25,7 @@ void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputC auto userInputMapper = DependencyManager::get(); userInputMapper->withLock([&, this]() { _inputDevice->update(deltaTime, inputCalibrationData); + eraseMouseClicked(); _inputDevice->_axisStateMap[MOUSE_AXIS_X] = _lastCursor.x(); _inputDevice->_axisStateMap[MOUSE_AXIS_Y] = _lastCursor.y(); @@ -78,8 +79,6 @@ void KeyboardMouseDevice::mousePressEvent(QMouseEvent* event) { _mousePressPos = event->pos(); _clickDeadspotActive = true; - - eraseMouseClicked(); } void KeyboardMouseDevice::mouseReleaseEvent(QMouseEvent* event) { @@ -122,7 +121,6 @@ void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event) { const int CLICK_EVENT_DEADSPOT = 6; // pixels if (_clickDeadspotActive && (_mousePressPos - currentPos).manhattanLength() > CLICK_EVENT_DEADSPOT) { - eraseMouseClicked(); _clickDeadspotActive = false; } } From 018138f422bb639652fb492ced76e3cdf4edbada Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 27 Mar 2017 22:46:06 +0100 Subject: [PATCH 17/21] fixed some issues with tablet help --- .../resources/html/img/tablet-help-oculus.jpg | Bin 255457 -> 258949 bytes interface/resources/html/tabletHelp.html | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/html/img/tablet-help-oculus.jpg b/interface/resources/html/img/tablet-help-oculus.jpg index 26f1672405322c1a6e0333be6b2a058575bcf0f2..b4f54396e08e01406ac844216590f765b2e1bb7f 100644 GIT binary patch literal 258949 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