diff --git a/android/app/CMakeLists.txt b/android/app/CMakeLists.txt index 4411b7b1bb..5682611151 100644 --- a/android/app/CMakeLists.txt +++ b/android/app/CMakeLists.txt @@ -11,7 +11,7 @@ link_hifi_libraries( physics audio audio-client ui midi controllers pointers - model model-networking fbx animation + graphics model-networking fbx animation entities entities-renderer avatars avatars-renderer ui-plugins input-plugins diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index e657587a7a..acdc1cbc53 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -11,7 +11,7 @@ setup_memory_debugger() # link in the shared libraries link_hifi_libraries( - audio avatars octree gpu model fbx entities + audio avatars octree gpu graphics fbx entities networking animation recording shared script-engine embedded-webserver controllers physics plugins midi image ) diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index acd9be0702..7a7210a0e8 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -116,8 +116,9 @@ public: void setLastOtherAvatarEncodeTime(const QUuid& otherAvatar, const uint64_t& time); QVector& getLastOtherAvatarSentJoints(QUuid otherAvatar) { - _lastOtherAvatarSentJoints[otherAvatar].resize(_avatar->getJointCount()); - return _lastOtherAvatarSentJoints[otherAvatar]; + auto& lastOtherAvatarSentJoints = _lastOtherAvatarSentJoints[otherAvatar]; + lastOtherAvatarSentJoints.resize(_avatar->getJointCount()); + return lastOtherAvatarSentJoints; } void queuePacket(QSharedPointer message, SharedNodePointer node); diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 6b78826d75..21225756b4 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -201,7 +201,7 @@ endif() # link required hifi libraries link_hifi_libraries( - shared octree ktx gpu gl procedural model render + shared octree ktx gpu gl procedural graphics render pointers recording fbx networking model-networking entities avatars trackers audio audio-client animation script-engine physics diff --git a/interface/resources/meshes/tablet-with-home-button.fbx b/interface/resources/meshes/tablet-with-home-button.fbx index 70b8008bad..37247022f6 100644 Binary files a/interface/resources/meshes/tablet-with-home-button.fbx and b/interface/resources/meshes/tablet-with-home-button.fbx differ diff --git a/interface/resources/qml/ToolWindow.qml b/interface/resources/qml/ToolWindow.qml deleted file mode 100644 index b1120058f9..0000000000 --- a/interface/resources/qml/ToolWindow.qml +++ /dev/null @@ -1,256 +0,0 @@ -// -// ToolWindow.qml -// -// Created by Bradley Austin Davis on 12 Jan 2016 -// Copyright 2016 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.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import QtWebEngine 1.1 -import QtWebChannel 1.0 -import Qt.labs.settings 1.0 - -import "windows" -import "controls-uit" -import "styles-uit" - - -ScrollingWindow { - id: toolWindow - resizable: true - objectName: "ToolWindow" - destroyOnCloseButton: false - destroyOnHidden: false - closable: true - shown: false - title: "Edit" - property alias tabView: tabView - implicitWidth: 520; implicitHeight: 695 - minSize: Qt.vector2d(456, 500) - - HifiConstants { id: hifi } - - onParentChanged: { - if (parent) { - x = 120; - y = 120; - } - } - - onShownChanged: { - keyboardEnabled = HMD.active; - } - - Settings { - category: "ToolWindow.Position" - property alias x: toolWindow.x - property alias y: toolWindow.y - } - - Item { - id: toolWindowTabViewItem - height: pane.scrollHeight - width: pane.contentWidth - anchors.left: parent.left - anchors.top: parent.top - - TabView { - id: tabView - width: pane.contentWidth - // Pane height so that don't use Window's scrollbars otherwise tabs may be scrolled out of view. - height: pane.scrollHeight - property int tabCount: 0 - - Repeater { - model: 4 - Tab { - // Force loading of the content even if the tab is not visible - // (required for letting the C++ code access the webview) - active: true - enabled: false - property string originalUrl: "" - - WebView { - id: webView - anchors.fill: parent - enabled: false - Component.onCompleted: { - webChannel.registerObject("eventBridge", eventBridge); - webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper); - } - - onEnabledChanged: toolWindow.updateVisiblity() - } - } - } - - style: TabViewStyle { - - frame: Rectangle { // Background shown before content loads. - anchors.fill: parent - color: hifi.colors.baseGray - } - - frameOverlap: 0 - - tab: Rectangle { - implicitWidth: text.width - implicitHeight: 3 * text.height - color: styleData.selected ? hifi.colors.black : hifi.colors.tabBackgroundDark - - RalewayRegular { - id: text - text: styleData.title - font.capitalization: Font.AllUppercase - size: hifi.fontSizes.tabName - width: tabView.tabCount > 1 ? styleData.availableWidth / tabView.tabCount : implicitWidth + 2 * hifi.dimensions.contentSpacing.x - elide: Text.ElideRight - color: styleData.selected ? hifi.colors.primaryHighlight : hifi.colors.lightGrayText - horizontalAlignment: Text.AlignHCenter - anchors.centerIn: parent - } - - Rectangle { // Separator. - width: 1 - height: parent.height - color: hifi.colors.black - anchors.left: parent.left - anchors.top: parent.top - visible: styleData.index > 0 - - Rectangle { - width: 1 - height: 1 - color: hifi.colors.baseGray - anchors.left: parent.left - anchors.bottom: parent.bottom - } - } - - Rectangle { // Active underline. - width: parent.width - (styleData.index > 0 ? 1 : 0) - height: 1 - anchors.right: parent.right - anchors.bottom: parent.bottom - color: styleData.selected ? hifi.colors.primaryHighlight : hifi.colors.baseGray - } - } - - tabOverlap: 0 - } - } - } - - function updateVisiblity() { - if (visible) { - for (var i = 0; i < tabView.count; ++i) { - if (tabView.getTab(i).enabled) { - return; - } - } - shown = false; - } - } - - function findIndexForUrl(source) { - for (var i = 0; i < tabView.count; ++i) { - var tab = tabView.getTab(i); - if (tab.originalUrl === source) { - return i; - } - } - return -1; - } - - function findTabForUrl(source) { - var index = findIndexForUrl(source); - if (index < 0) { - return; - } - return tabView.getTab(index); - } - - function showTabForUrl(source, newVisible) { - var index = findIndexForUrl(source); - if (index < 0) { - return; - } - - var tab = tabView.getTab(index); - if (newVisible) { - toolWindow.shown = true - tab.enabled = true - } else { - tab.enabled = false; - updateVisiblity(); - } - } - - function findFreeTab() { - for (var i = 0; i < tabView.count; ++i) { - var tab = tabView.getTab(i); - if (tab && (!tab.originalUrl || tab.originalUrl === "")) { - return i; - } - } - return -1; - } - - function removeTabForUrl(source) { - var index = findIndexForUrl(source); - if (index < 0) { - return; - } - - var tab = tabView.getTab(index); - tab.title = ""; - tab.enabled = false; - tab.originalUrl = ""; - tab.item.url = "about:blank"; - tab.item.enabled = false; - tabView.tabCount--; - } - - function addWebTab(properties) { - if (!properties.source) { - console.warn("Attempted to open Web Tool Pane without URL"); - return; - } - - var existingTabIndex = findIndexForUrl(properties.source); - if (existingTabIndex >= 0) { - var tab = tabView.getTab(existingTabIndex); - return tab.item; - } - - var freeTabIndex = findFreeTab(); - if (freeTabIndex === -1) { - console.warn("Unable to add new tab"); - return; - } - - if (properties.width) { - tabView.width = Math.min(Math.max(tabView.width, properties.width), toolWindow.maxSize.x); - } - - if (properties.height) { - tabView.height = Math.min(Math.max(tabView.height, properties.height), toolWindow.maxSize.y); - } - - var tab = tabView.getTab(freeTabIndex); - tab.title = properties.title || "Unknown"; - tab.enabled = true; - tab.originalUrl = properties.source; - - var result = tab.item; - result.enabled = true; - tabView.tabCount++; - result.url = properties.source; - return result; - } -} diff --git a/interface/resources/qml/controls-uit/TextField.qml b/interface/resources/qml/controls-uit/TextField.qml index e636bfc27f..b942c8b4ab 100644 --- a/interface/resources/qml/controls-uit/TextField.qml +++ b/interface/resources/qml/controls-uit/TextField.qml @@ -27,10 +27,12 @@ TextField { property bool hasRoundedBorder: false property bool error: false; property bool hasClearButton: false; + property string leftPlaceholderGlyph: ""; placeholderText: textField.placeholderText FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } + FontLoader { id: hifiGlyphs; source: "../../fonts/hifi-glyphs.ttf"; } font.family: firaSansSemiBold.name font.pixelSize: hifi.fontSizes.textFieldInput font.italic: textField.text == "" @@ -54,6 +56,7 @@ TextField { } style: TextFieldStyle { + id: style; textColor: { if (isLightColorScheme) { if (textField.activeFocus) { @@ -102,6 +105,16 @@ TextField { border.width: textField.activeFocus || hasRoundedBorder || textField.error ? 1 : 0 radius: isSearchField ? textField.height / 2 : (hasRoundedBorder ? 4 : 0) + HiFiGlyphs { + text: textField.leftPlaceholderGlyph; + color: textColor; + size: hifi.fontSizes.textFieldSearchIcon; + anchors.left: parent.left; + anchors.verticalCenter: parent.verticalCenter; + anchors.leftMargin: hifi.dimensions.textPadding - 2; + visible: text; + } + HiFiGlyphs { text: hifi.glyphs.search color: textColor @@ -132,7 +145,7 @@ TextField { placeholderTextColor: isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray selectedTextColor: hifi.colors.black selectionColor: hifi.colors.primaryHighlight - padding.left: (isSearchField ? textField.height - 2 : 0) + hifi.dimensions.textPadding + padding.left: ((isSearchField || textField.leftPlaceholderGlyph !== "") ? textField.height - 2 : 0) + hifi.dimensions.textPadding padding.right: (hasClearButton ? textField.height - 2 : 0) + hifi.dimensions.textPadding } diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index 896b3cf10e..8c732aac40 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -22,10 +22,6 @@ OriginalDesktop.Desktop { acceptedButtons: Qt.NoButton } - // The tool window, one instance - property alias toolWindow: toolWindow - ToolWindow { id: toolWindow } - Action { text: "Open Browser" shortcut: "Ctrl+B" diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml index 3f5cad655d..e08fdc53ff 100644 --- a/interface/resources/qml/hifi/NameCard.qml +++ b/interface/resources/qml/hifi/NameCard.qml @@ -50,7 +50,7 @@ Item { id: avatarImage visible: profileUrl !== "" && userName !== ""; // Size - height: isMyCard ? 70 : 42; + height: isMyCard ? 84 : 42; width: visible ? height : 0; anchors.top: parent.top; anchors.topMargin: isMyCard ? 0 : 8; @@ -520,7 +520,7 @@ Item { Slider { id: gainSlider // Size - width: thisNameCard.width; + width: isMyCard ? thisNameCard.width - 20 : thisNameCard.width; height: 14 // Anchors anchors.verticalCenter: nameCardVUMeter.verticalCenter; diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index 64f61f0d69..02971cc984 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -28,7 +28,7 @@ Rectangle { // Properties property bool debug: false; property int myCardWidth: width - upperRightInfoContainer.width; - property int myCardHeight: 80; + property int myCardHeight: 100; property int rowHeight: 60; property int actionButtonWidth: 55; property int locationColumnWidth: 170; diff --git a/interface/resources/qml/hifi/commerce/wallet/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/SendMoney.qml deleted file mode 100644 index 11a6c99b0c..0000000000 --- a/interface/resources/qml/hifi/commerce/wallet/SendMoney.qml +++ /dev/null @@ -1,73 +0,0 @@ -// -// SendMoney.qml -// qml/hifi/commerce/wallet -// -// SendMoney -// -// Created by Zach Fox on 2017-08-18 -// 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 -// - -import Hifi 1.0 as Hifi -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import "../../../styles-uit" -import "../../../controls-uit" as HifiControlsUit -import "../../../controls" as HifiControls - -// references XXX from root context - -Item { - HifiConstants { id: hifi; } - - id: root; - - Connections { - target: Commerce; - } - - // "Unavailable" - RalewayRegular { - text: "You currently cannot send money to other High Fidelity users."; - // Anchors - anchors.fill: parent; - // Text size - size: 24; - // Style - color: hifi.colors.faintGray; - wrapMode: Text.WordWrap; - // Alignment - horizontalAlignment: Text.AlignHCenter; - verticalAlignment: Text.AlignVCenter; - } - - // - // FUNCTION DEFINITIONS START - // - // - // Function Name: fromScript() - // - // Relevant Variables: - // None - // - // Arguments: - // message: The message sent from the JavaScript. - // Messages are in format "{method, params}", like json-rpc. - // - // Description: - // Called when a message is received from a script. - // - function fromScript(message) { - switch (message.method) { - default: - console.log('Unrecognized message from wallet.js:', JSON.stringify(message)); - } - } - signal sendSignalToWallet(var msg); - // - // FUNCTION DEFINITIONS END - // -} diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index ef2b007dc8..da67569bc3 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -19,8 +19,7 @@ import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls import "../common" as HifiCommerceCommon - -// references XXX from root context +import "./sendMoney" Rectangle { HifiConstants { id: hifi; } @@ -316,18 +315,29 @@ Rectangle { Connections { onSendSignalToWallet: { - sendToScript(msg); + if (msg.method === 'transactionHistory_usernameLinkClicked') { + userInfoViewer.url = msg.usernameLink; + userInfoViewer.visible = true; + } else { + sendToScript(msg); + } } } } SendMoney { id: sendMoney; + z: 997; visible: root.activeView === "sendMoney"; - anchors.top: titleBarContainer.bottom; - anchors.bottom: tabButtonsContainer.top; - anchors.left: parent.left; - anchors.right: parent.right; + anchors.fill: parent; + parentAppTitleBarHeight: titleBarContainer.height; + parentAppNavBarHeight: tabButtonsContainer.height; + + Connections { + onSendSignalToWallet: { + sendToScript(msg); + } + } } Security { @@ -497,7 +507,7 @@ Rectangle { Rectangle { id: sendMoneyButtonContainer; visible: !walletSetup.visible; - color: hifi.colors.black; + color: root.activeView === "sendMoney" ? hifi.colors.blueAccent : hifi.colors.black; anchors.top: parent.top; anchors.left: exchangeMoneyButtonContainer.right; anchors.bottom: parent.bottom; @@ -513,7 +523,7 @@ Rectangle { anchors.top: parent.top; anchors.topMargin: -2; // Style - color: hifi.colors.lightGray50; + color: root.activeView === "sendMoney" || sendMoneyTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight; } RalewaySemiBold { @@ -528,12 +538,24 @@ Rectangle { anchors.right: parent.right; anchors.rightMargin: 4; // Style - color: hifi.colors.lightGray50; + color: root.activeView === "sendMoney" || sendMoneyTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight; wrapMode: Text.WordWrap; // Alignment horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignTop; } + + MouseArea { + id: sendMoneyTabMouseArea; + anchors.fill: parent; + hoverEnabled: enabled; + onClicked: { + root.activeView = "sendMoney"; + tabButtonsContainer.resetTabButtonColors(); + } + onEntered: parent.color = hifi.colors.blueHighlight; + onExited: parent.color = root.activeView === "sendMoney" ? hifi.colors.blueAccent : hifi.colors.black; + } } // "SECURITY" tab button @@ -665,9 +687,16 @@ Rectangle { // TAB BUTTONS END // + HifiControls.TabletWebView { + id: userInfoViewer; + z: 998; + anchors.fill: parent; + visible: false; + } + Item { id: keyboardContainer; - z: 998; + z: 999; visible: keyboard.raised; property bool punctuationMode: false; anchors { @@ -713,6 +742,13 @@ Rectangle { case 'inspectionCertificate_resetCert': // NOP break; + case 'updateConnections': + sendMoney.updateConnections(message.connections); + break; + case 'selectRecipient': + case 'updateSelectedRecipientUsername': + sendMoney.fromScript(message); + break; default: console.log('Unrecognized message from wallet.js:', JSON.stringify(message)); } diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml index 780e08caf8..81d38bc0dd 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml @@ -19,8 +19,6 @@ import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls -// references XXX from root context - Item { HifiConstants { id: hifi; } @@ -32,6 +30,20 @@ Item { property int currentHistoryPage: 1; property var pagesAlreadyAdded: new Array(); + onVisibleChanged: { + if (visible) { + transactionHistoryModel.clear(); + Commerce.balance(); + initialHistoryReceived = false; + root.currentHistoryPage = 1; + root.noMoreHistoryData = false; + root.historyRequestPending = true; + Commerce.history(root.currentHistoryPage); + } else { + refreshTimer.stop(); + } + } + Connections { target: Commerce; @@ -189,20 +201,6 @@ Item { color: hifi.colors.white; // Alignment verticalAlignment: Text.AlignVCenter; - - onVisibleChanged: { - if (visible) { - transactionHistoryModel.clear(); - Commerce.balance(); - initialHistoryReceived = false; - root.currentHistoryPage = 1; - root.noMoreHistoryData = false; - root.historyRequestPending = true; - Commerce.history(root.currentHistoryPage); - } else { - refreshTimer.stop(); - } - } } // "balance" text below field @@ -384,8 +382,8 @@ Item { height: visible ? parent.height : 0; AnonymousProRegular { - id: dateText; - text: model.created_at ? getFormattedDate(model.created_at * 1000) : ""; + id: hfcText; + text: model.hfc_text || ''; // Style size: 18; anchors.left: parent.left; @@ -393,28 +391,33 @@ Item { anchors.topMargin: 15; width: 118; height: paintedHeight; - color: hifi.colors.blueAccent; wrapMode: Text.WordWrap; + font.bold: true; // Alignment horizontalAlignment: Text.AlignRight; } AnonymousProRegular { id: transactionText; - text: model.text ? (model.status === "invalidated" ? ("INVALIDATED: " + model.text) : model.text) : ""; + text: model.transaction_text ? (model.status === "invalidated" ? ("INVALIDATED: " + model.transaction_text) : model.transaction_text) : ""; size: 18; anchors.top: parent.top; anchors.topMargin: 15; - anchors.left: dateText.right; + anchors.left: hfcText.right; anchors.leftMargin: 20; anchors.right: parent.right; height: paintedHeight; color: model.status === "invalidated" ? hifi.colors.redAccent : hifi.colors.baseGrayHighlight; + linkColor: hifi.colors.blueAccent; wrapMode: Text.WordWrap; font.strikeout: model.status === "invalidated"; onLinkActivated: { - sendSignalToWallet({method: 'transactionHistory_linkClicked', marketplaceLink: link}); + if (link.indexOf("users/") !== -1) { + sendSignalToWallet({method: 'transactionHistory_usernameLinkClicked', usernameLink: link}); + } else { + sendSignalToWallet({method: 'transactionHistory_linkClicked', marketplaceLink: link}); + } } } diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml new file mode 100644 index 0000000000..c2d9ef3b19 --- /dev/null +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml @@ -0,0 +1,128 @@ +// +// ConnectionItem.qml +// qml/hifi/commerce/wallet/sendMoney +// +// ConnectionItem +// +// Created by Zach Fox on 2018-01-09 +// 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 Hifi 1.0 as Hifi +import QtQuick 2.5 +import QtGraphicalEffects 1.0 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import "../../../../styles-uit" +import "../../../../controls-uit" as HifiControlsUit +import "../../../../controls" as HifiControls +import "../../wallet" as HifiWallet + +Item { + HifiConstants { id: hifi; } + + id: root; + property bool isSelected: false; + property string userName; + property string profilePicUrl; + + height: 65; + width: parent.width; + + Rectangle { + id: mainContainer; + // Style + color: root.isSelected ? hifi.colors.faintGray : hifi.colors.white; + // Size + anchors.left: parent.left; + anchors.right: parent.right; + anchors.top: parent.top; + height: root.height; + + Item { + id: avatarImage; + visible: profileUrl !== "" && userName !== ""; + // Size + anchors.verticalCenter: parent.verticalCenter; + anchors.left: parent.left; + anchors.leftMargin: 36; + height: root.height - 15; + width: visible ? height : 0; + clip: true; + Image { + id: userImage; + source: root.profilePicUrl !== "" ? ((0 === root.profilePicUrl.indexOf("http")) ? + root.profilePicUrl : (Account.metaverseServerURL + root.profilePicUrl)) : ""; + mipmap: true; + // Anchors + anchors.fill: parent + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Item { + width: userImage.width; + height: userImage.height; + Rectangle { + anchors.centerIn: parent; + width: userImage.width; // This works because userImage is square + height: width; + radius: width; + } + } + } + } + AnimatedImage { + source: "../../../../../icons/profilePicLoading.gif" + anchors.fill: parent; + visible: userImage.status != Image.Ready; + } + } + + RalewaySemiBold { + id: userName; + anchors.left: avatarImage.right; + anchors.leftMargin: 16; + anchors.top: parent.top; + anchors.bottom: parent.bottom; + anchors.right: chooseButton.visible ? chooseButton.left : parent.right; + anchors.rightMargin: chooseButton.visible ? 10 : 0; + // Text size + size: 20; + // Style + color: hifi.colors.baseGray; + text: root.userName; + elide: Text.ElideRight; + // Alignment + horizontalAlignment: Text.AlignLeft; + verticalAlignment: Text.AlignVCenter; + } + + // "Choose" button + HifiControlsUit.Button { + id: chooseButton; + visible: root.isSelected; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.verticalCenter: parent.verticalCenter; + anchors.right: parent.right; + anchors.rightMargin: 24; + height: root.height - 20; + width: 110; + text: "CHOOSE"; + onClicked: { + var msg = { method: 'chooseConnection', userName: root.userName, profilePicUrl: root.profilePicUrl }; + sendToSendMoney(msg); + } + } + } + + // + // FUNCTION DEFINITIONS START + // + signal sendToSendMoney(var msg); + // + // FUNCTION DEFINITIONS END + // +} diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml new file mode 100644 index 0000000000..267cf0ed51 --- /dev/null +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml @@ -0,0 +1,116 @@ +// +// RecipientDisplay.qml +// qml/hifi/commerce/wallet/sendMoney +// +// RecipientDisplay +// +// Created by Zach Fox on 2018-01-11 +// 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 Hifi 1.0 as Hifi +import QtQuick 2.6 +import QtQuick.Controls 2.2 +import QtGraphicalEffects 1.0 +import "../../../../styles-uit" +import "../../../../controls-uit" as HifiControlsUit +import "../../../../controls" as HifiControls +import "../../common" as HifiCommerceCommon + +Item { + HifiConstants { id: hifi; } + + id: root; + + property bool isDisplayingNearby; // as opposed to 'connections' + property string displayName; + property string userName; + property string profilePic; + + Item { + visible: root.isDisplayingNearby; + anchors.fill: parent; + + RalewaySemiBold { + id: recipientDisplayName; + text: root.displayName; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.right: parent.right; + anchors.rightMargin: 12; + height: parent.height/2; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignBottom; + elide: Text.ElideRight; + } + + RalewaySemiBold { + text: root.userName; + // Anchors + anchors.bottom: parent.bottom; + anchors.left: recipientDisplayName.anchors.left; + anchors.leftMargin: recipientDisplayName.anchors.leftMargin; + anchors.right: recipientDisplayName.anchors.right; + anchors.rightMargin: recipientDisplayName.anchors.rightMargin; + height: parent.height/2; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignTop; + elide: Text.ElideRight; + } + } + + Item { + visible: !root.isDisplayingNearby; + anchors.fill: parent; + + Image { + id: userImage; + source: root.profilePic; + mipmap: true; + // Anchors + anchors.left: parent.left; + anchors.verticalCenter: parent.verticalCenter; + height: parent.height - 36; + width: height; + layer.enabled: true; + layer.effect: OpacityMask { + maskSource: Item { + width: userImage.width; + height: userImage.height; + Rectangle { + anchors.centerIn: parent; + width: userImage.width; // This works because userImage is square + height: width; + radius: width; + } + } + } + } + + RalewaySemiBold { + text: root.userName; + // Anchors + anchors.left: userImage.right; + anchors.leftMargin: 8; + anchors.right: parent.right; + anchors.verticalCenter: parent.verticalCenter; + height: parent.height - 4; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + elide: Text.ElideRight; + } + } +} diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml new file mode 100644 index 0000000000..9164ba7a8c --- /dev/null +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -0,0 +1,1502 @@ +// +// SendMoney.qml +// qml/hifi/commerce/wallet/sendMoney +// +// SendMoney +// +// Created by Zach Fox on 2018-01-09 +// 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 Hifi 1.0 as Hifi +import QtQuick 2.6 +import QtQuick.Controls 2.2 +import QtGraphicalEffects 1.0 +import "../../../../styles-uit" +import "../../../../controls-uit" as HifiControlsUit +import "../../../../controls" as HifiControls +import "../../common" as HifiCommerceCommon + +Item { + HifiConstants { id: hifi; } + + id: root; + + property int parentAppTitleBarHeight; + property int parentAppNavBarHeight; + property string currentActiveView: "sendMoneyHome"; + property string nextActiveView: ""; + property bool isCurrentlyFullScreen: chooseRecipientConnection.visible || + chooseRecipientNearby.visible || sendMoneyStep.visible || paymentSuccess.visible || paymentFailure.visible; + property bool isCurrentlySendingMoney: false; + + // This object is always used in a popup or full-screen Wallet section. + // This MouseArea is used to prevent a user from being + // able to click on a button/mouseArea underneath the popup/section. + MouseArea { + x: 0; + y: root.isCurrentlyFullScreen ? 0 : root.parentAppTitleBarHeight; + width: parent.width; + height: root.isCurrentlyFullScreen ? parent.height : parent.height - root.parentAppTitleBarHeight - root.parentAppNavBarHeight; + propagateComposedEvents: false; + } + + Connections { + target: Commerce; + + onBalanceResult : { + balanceText.text = result.data.balance; + } + + onTransferHfcToNodeResult: { + root.isCurrentlySendingMoney = false; + + if (result.status === 'success') { + root.nextActiveView = 'paymentSuccess'; + } else { + root.nextActiveView = 'paymentFailure'; + } + } + + onTransferHfcToUsernameResult: { + root.isCurrentlySendingMoney = false; + + if (result.status === 'success') { + root.nextActiveView = 'paymentSuccess'; + } else { + root.nextActiveView = 'paymentFailure'; + } + } + } + + Connections { + target: GlobalServices + onMyUsernameChanged: { + usernameText.text = Account.username; + } + } + + Component.onCompleted: { + Commerce.balance(); + } + + onNextActiveViewChanged: { + if (root.currentActiveView === 'chooseRecipientNearby') { + sendSignalToWallet({method: 'disable_ChooseRecipientNearbyMode'}); + } + + root.currentActiveView = root.nextActiveView; + + if (root.currentActiveView === 'chooseRecipientConnection') { + // Refresh connections model + connectionsLoading.visible = false; + connectionsLoading.visible = true; + sendSignalToWallet({method: 'refreshConnections'}); + } else if (root.currentActiveView === 'sendMoneyHome') { + Commerce.balance(); + } else if (root.currentActiveView === 'chooseRecipientNearby') { + sendSignalToWallet({method: 'enable_ChooseRecipientNearbyMode'}); + } + } + + // Send Money Home BEGIN + Item { + id: sendMoneyHome; + visible: root.currentActiveView === "sendMoneyHome"; + anchors.fill: parent; + anchors.topMargin: root.parentAppTitleBarHeight; + anchors.bottomMargin: root.parentAppNavBarHeight; + + // Username Text + RalewayRegular { + id: usernameText; + text: Account.username; + // Text size + size: 24; + // Style + color: hifi.colors.white; + elide: Text.ElideRight; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: parent.width/2; + height: 80; + } + + // HFC Balance Container + Item { + id: hfcBalanceContainer; + // Anchors + anchors.top: parent.top; + anchors.right: parent.right; + anchors.leftMargin: 20; + width: parent.width/2; + height: 80; + + // "HFC" balance label + HiFiGlyphs { + id: balanceLabel; + text: hifi.glyphs.hfc; + // Size + size: 40; + // Anchors + anchors.left: parent.left; + anchors.top: parent.top; + anchors.bottom: parent.bottom; + // Style + color: hifi.colors.white; + } + + // Balance Text + FiraSansRegular { + id: balanceText; + text: "--"; + // Text size + size: 28; + // Anchors + anchors.top: balanceLabel.top; + anchors.bottom: balanceLabel.bottom; + anchors.left: balanceLabel.right; + anchors.leftMargin: 10; + anchors.right: parent.right; + anchors.rightMargin: 4; + // Style + color: hifi.colors.white; + // Alignment + verticalAlignment: Text.AlignVCenter; + } + + // "balance" text below field + RalewayRegular { + text: "BALANCE (HFC)"; + // Text size + size: 14; + // Anchors + anchors.top: balanceLabel.top; + anchors.topMargin: balanceText.paintedHeight + 20; + anchors.bottom: balanceLabel.bottom; + anchors.left: balanceText.left; + anchors.right: balanceText.right; + height: paintedHeight; + // Style + color: hifi.colors.white; + } + } + + // Send Money + Rectangle { + id: sendMoneyContainer; + anchors.left: parent.left; + anchors.right: parent.right; + anchors.bottom: parent.bottom; + height: 440; + + RalewaySemiBold { + id: sendMoneyText; + text: "Send Money To:"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + } + + Item { + id: connectionButton; + // Anchors + anchors.top: sendMoneyText.bottom; + anchors.topMargin: 40; + anchors.left: parent.left; + anchors.leftMargin: 75; + height: 95; + width: 95; + + Image { + anchors.top: parent.top; + source: "../images/wallet-bg.jpg"; + height: 60; + width: parent.width; + fillMode: Image.PreserveAspectFit; + horizontalAlignment: Image.AlignHCenter; + verticalAlignment: Image.AlignTop; + } + + RalewaySemiBold { + text: "Connection"; + // Anchors + anchors.bottom: parent.bottom; + height: 15; + width: parent.width; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + horizontalAlignment: Text.AlignHCenter; + } + + MouseArea { + anchors.fill: parent; + onClicked: { + root.nextActiveView = "chooseRecipientConnection"; + } + } + } + + Item { + id: nearbyButton; + // Anchors + anchors.top: sendMoneyText.bottom; + anchors.topMargin: connectionButton.anchors.topMargin; + anchors.right: parent.right; + anchors.rightMargin: connectionButton.anchors.leftMargin; + height: connectionButton.height; + width: connectionButton.width; + + Image { + anchors.top: parent.top; + source: "../images/wallet-bg.jpg"; + height: 60; + width: parent.width; + fillMode: Image.PreserveAspectFit; + horizontalAlignment: Image.AlignHCenter; + verticalAlignment: Image.AlignTop; + } + + RalewaySemiBold { + text: "Someone Nearby"; + // Anchors + anchors.bottom: parent.bottom; + height: 15; + width: parent.width; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + horizontalAlignment: Text.AlignHCenter; + } + + MouseArea { + anchors.fill: parent; + onClicked: { + root.nextActiveView = "chooseRecipientNearby"; + } + } + } + } + } + // Send Money Home END + + // Choose Recipient Connection BEGIN + Rectangle { + id: chooseRecipientConnection; + visible: root.currentActiveView === "chooseRecipientConnection"; + anchors.fill: parent; + color: "#AAAAAA"; + + ListModel { + id: connectionsModel; + } + ListModel { + id: filteredConnectionsModel; + } + + Rectangle { + anchors.centerIn: parent; + width: parent.width - 30; + height: parent.height - 30; + + RalewaySemiBold { + id: chooseRecipientText_connections; + text: "Choose Recipient:"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + } + + HiFiGlyphs { + id: closeGlyphButton_connections; + text: hifi.glyphs.close; + size: 26; + anchors.top: parent.top; + anchors.topMargin: 10; + anchors.right: parent.right; + anchors.rightMargin: 10; + MouseArea { + anchors.fill: parent; + hoverEnabled: true; + onEntered: { + parent.text = hifi.glyphs.closeInverted; + } + onExited: { + parent.text = hifi.glyphs.close; + } + onClicked: { + root.nextActiveView = "sendMoneyHome"; + } + } + } + + // + // FILTER BAR START + // + Item { + id: filterBarContainer; + // Size + height: 40; + // Anchors + anchors.left: parent.left; + anchors.leftMargin: 16; + anchors.right: parent.right; + anchors.rightMargin: 16; + anchors.top: chooseRecipientText_connections.bottom; + anchors.topMargin: 12; + + HifiControlsUit.TextField { + id: filterBar; + colorScheme: hifi.colorSchemes.faintGray; + hasClearButton: true; + hasRoundedBorder: true; + anchors.fill: parent; + placeholderText: "filter recipients"; + + onTextChanged: { + buildFilteredConnectionsModel(); + } + + onAccepted: { + focus = false; + } + } + } + // + // FILTER BAR END + // + + Item { + id: connectionsContainer; + anchors.top: filterBarContainer.bottom; + anchors.topMargin: 16; + anchors.left: parent.left; + anchors.right: parent.right; + anchors.bottom: parent.bottom; + + AnimatedImage { + id: connectionsLoading; + source: "../../../../../icons/profilePicLoading.gif" + width: 120; + height: width; + anchors.top: parent.top; + anchors.topMargin: 185; + anchors.horizontalCenter: parent.horizontalCenter; + } + + ListView { + id: connectionsList; + ScrollBar.vertical: ScrollBar { + policy: connectionsList.contentHeight > parent.parent.height ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded; + parent: connectionsList.parent; + anchors.top: connectionsList.top; + anchors.right: connectionsList.right; + anchors.bottom: connectionsList.bottom; + width: 20; + } + visible: !connectionsLoading.visible; + clip: true; + model: filteredConnectionsModel; + snapMode: ListView.SnapToItem; + // Anchors + anchors.fill: parent; + delegate: ConnectionItem { + isSelected: connectionsList.currentIndex === index; + userName: model.userName; + profilePicUrl: model.profileUrl; + anchors.topMargin: 6; + anchors.bottomMargin: 6; + + Connections { + onSendToSendMoney: { + sendMoneyStep.referrer = "connections"; + sendMoneyStep.selectedRecipientNodeID = ''; + sendMoneyStep.selectedRecipientDisplayName = 'connection'; + sendMoneyStep.selectedRecipientUserName = msg.userName; + sendMoneyStep.selectedRecipientProfilePic = msg.profilePicUrl; + + root.nextActiveView = "sendMoneyStep"; + } + } + + MouseArea { + enabled: connectionsList.currentIndex !== index; + anchors.fill: parent; + propagateComposedEvents: false; + onClicked: { + connectionsList.currentIndex = index; + } + } + } + } + } + } + } + // Choose Recipient Connection END + + // Choose Recipient Nearby BEGIN + Rectangle { + id: chooseRecipientNearby; + + property string selectedRecipient; + + visible: root.currentActiveView === "chooseRecipientNearby"; + anchors.fill: parent; + color: "#AAAAAA"; + + Rectangle { + anchors.centerIn: parent; + width: parent.width - 30; + height: parent.height - 30; + + RalewaySemiBold { + text: "Choose Recipient:"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + } + + HiFiGlyphs { + id: closeGlyphButton_nearby; + text: hifi.glyphs.close; + size: 26; + anchors.top: parent.top; + anchors.topMargin: 10; + anchors.right: parent.right; + anchors.rightMargin: 10; + MouseArea { + anchors.fill: parent; + hoverEnabled: true; + onEntered: { + parent.text = hifi.glyphs.closeInverted; + } + onExited: { + parent.text = hifi.glyphs.close; + } + onClicked: { + root.nextActiveView = "sendMoneyHome"; + resetSendMoneyData(); + } + } + } + + Item { + id: selectionInstructionsContainer; + visible: chooseRecipientNearby.selectedRecipient === ""; + anchors.fill: parent; + + RalewaySemiBold { + id: selectionInstructions_deselected; + text: "Click/trigger on an avatar nearby to select them..."; + // Anchors + anchors.bottom: parent.bottom; + anchors.bottomMargin: 200; + anchors.left: parent.left; + anchors.leftMargin: 58; + anchors.right: parent.right; + anchors.rightMargin: anchors.leftMargin; + height: paintedHeight; + // Text size + size: 20; + // Style + color: hifi.colors.baseGray; + horizontalAlignment: Text.AlignHCenter; + wrapMode: Text.Wrap; + } + } + + Item { + id: selectionMadeContainer; + visible: !selectionInstructionsContainer.visible; + anchors.fill: parent; + + RalewaySemiBold { + id: sendToText; + text: "Send To:"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 120; + anchors.left: parent.left; + anchors.leftMargin: 12; + width: paintedWidth; + height: paintedHeight; + // Text size + size: 20; + // Style + color: hifi.colors.baseGray; + } + + RalewaySemiBold { + id: avatarDisplayName; + text: '"' + AvatarList.getAvatar(chooseRecipientNearby.selectedRecipient).sessionDisplayName + '"'; + // Anchors + anchors.top: sendToText.bottom; + anchors.topMargin: 60; + anchors.left: parent.left; + anchors.leftMargin: 30; + anchors.right: parent.right; + anchors.rightMargin: 30; + height: paintedHeight; + // Text size + size: 22; + // Style + horizontalAlignment: Text.AlignHCenter; + color: hifi.colors.baseGray; + } + + RalewaySemiBold { + id: avatarNodeID; + text: chooseRecipientNearby.selectedRecipient; + // Anchors + anchors.top: avatarDisplayName.bottom; + anchors.topMargin: 6; + anchors.left: parent.left; + anchors.leftMargin: 30; + anchors.right: parent.right; + anchors.rightMargin: 30; + height: paintedHeight; + // Text size + size: 14; + // Style + horizontalAlignment: Text.AlignHCenter; + color: hifi.colors.lightGrayText; + } + + RalewaySemiBold { + id: avatarUserName; + text: sendMoneyStep.selectedRecipientUserName; + // Anchors + anchors.top: avatarNodeID.bottom; + anchors.topMargin: 12; + anchors.left: parent.left; + anchors.leftMargin: 30; + anchors.right: parent.right; + anchors.rightMargin: 30; + height: paintedHeight; + // Text size + size: 22; + // Style + horizontalAlignment: Text.AlignHCenter; + color: hifi.colors.baseGray; + } + + RalewaySemiBold { + id: selectionInstructions_selected; + text: "Click/trigger on another avatar nearby to select them...\n\nor press 'Next' to continue."; + // Anchors + anchors.bottom: parent.bottom; + anchors.bottomMargin: 200; + anchors.left: parent.left; + anchors.leftMargin: 58; + anchors.right: parent.right; + anchors.rightMargin: anchors.leftMargin; + height: paintedHeight; + // Text size + size: 20; + // Style + color: hifi.colors.baseGray; + horizontalAlignment: Text.AlignHCenter; + wrapMode: Text.Wrap; + } + } + + // "Cancel" button + HifiControlsUit.Button { + id: cancelButton; + color: hifi.buttons.noneBorderless; + colorScheme: hifi.colorSchemes.dark; + anchors.left: parent.left; + anchors.leftMargin: 60; + anchors.bottom: parent.bottom; + anchors.bottomMargin: 80; + height: 50; + width: 120; + text: "Cancel"; + onClicked: { + root.nextActiveView = "sendMoneyHome"; + resetSendMoneyData(); + } + } + + // "Next" button + HifiControlsUit.Button { + id: nextButton; + enabled: chooseRecipientNearby.selectedRecipient !== ""; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.right: parent.right; + anchors.rightMargin: 60; + anchors.bottom: parent.bottom; + anchors.bottomMargin: 80; + height: 50; + width: 120; + text: "Next"; + onClicked: { + sendMoneyStep.referrer = "nearby"; + sendMoneyStep.selectedRecipientNodeID = chooseRecipientNearby.selectedRecipient; + chooseRecipientNearby.selectedRecipient = ""; + + root.nextActiveView = "sendMoneyStep"; + } + } + } + } + // Choose Recipient Nearby END + + // Send Money Screen BEGIN + Rectangle { + id: sendMoneyStep; + z: 997; + + property string referrer; // either "connections" or "nearby" + property string selectedRecipientNodeID; + property string selectedRecipientDisplayName; + property string selectedRecipientUserName; + property string selectedRecipientProfilePic; + + visible: root.currentActiveView === "sendMoneyStep"; + anchors.fill: parent; + color: "#AAAAAA"; + + Rectangle { + anchors.centerIn: parent; + width: parent.width - 30; + height: parent.height - 30; + + RalewaySemiBold { + id: sendMoneyText_sendMoneyStep; + text: "Send Money To:"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + } + + Item { + id: sendToContainer; + anchors.top: sendMoneyText_sendMoneyStep.bottom; + anchors.topMargin: 20; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: sendToText_sendMoneyStep; + text: "Send To:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + RecipientDisplay { + anchors.top: parent.top; + anchors.left: sendToText_sendMoneyStep.right; + anchors.right: changeButton.left; + anchors.rightMargin: 12; + height: parent.height; + + displayName: sendMoneyStep.selectedRecipientDisplayName; + userName: sendMoneyStep.selectedRecipientUserName; + profilePic: sendMoneyStep.selectedRecipientProfilePic !== "" ? ((0 === sendMoneyStep.selectedRecipientProfilePic.indexOf("http")) ? + sendMoneyStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendMoneyStep.selectedRecipientProfilePic)) : ""; + isDisplayingNearby: sendMoneyStep.referrer === "nearby"; + } + + // "CHANGE" button + HifiControlsUit.Button { + id: changeButton; + color: hifi.buttons.black; + colorScheme: hifi.colorSchemes.dark; + anchors.right: parent.right; + anchors.verticalCenter: parent.verticalCenter; + height: 35; + width: 120; + text: "CHANGE"; + onClicked: { + if (sendMoneyStep.referrer === "connections") { + root.nextActiveView = "chooseRecipientConnection"; + } else if (sendMoneyStep.referrer === "nearby") { + root.nextActiveView = "chooseRecipientNearby"; + } + resetSendMoneyData(); + } + } + } + + Item { + id: amountContainer; + anchors.top: sendToContainer.bottom; + anchors.topMargin: 2; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: amountText; + text: "Amount:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + HifiControlsUit.TextField { + id: amountTextField; + colorScheme: hifi.colorSchemes.light; + inputMethodHints: Qt.ImhDigitsOnly; + // Anchors + anchors.verticalCenter: parent.verticalCenter; + anchors.left: amountText.right; + anchors.right: parent.right; + height: 50; + // Style + leftPlaceholderGlyph: hifi.glyphs.hfc; + activeFocusOnPress: true; + activeFocusOnTab: true; + + validator: IntValidator { bottom: 0; } + + onAccepted: { + optionalMessage.focus = true; + } + } + + RalewaySemiBold { + id: amountTextFieldError; + // Anchors + anchors.top: amountTextField.bottom; + anchors.topMargin: 2; + anchors.left: amountTextField.left; + anchors.right: amountTextField.right; + height: 40; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignTop; + horizontalAlignment: Text.AlignRight; + } + } + + Item { + id: messageContainer; + anchors.top: amountContainer.bottom; + anchors.topMargin: 16; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 140; + + FontLoader { id: firaSansSemiBold; source: "../../../../../fonts/FiraSans-SemiBold.ttf"; } + TextArea { + id: optionalMessage; + property int maximumLength: 70; + property string previousText: text; + placeholderText: "Optional Message"; + font.family: firaSansSemiBold.name; + font.pixelSize: 20; + // Anchors + anchors.fill: parent; + // Style + background: Rectangle { + anchors.fill: parent; + color: optionalMessage.activeFocus ? hifi.colors.white : hifi.colors.textFieldLightBackground; + border.width: optionalMessage.activeFocus ? 1 : 0; + border.color: optionalMessage.activeFocus ? hifi.colors.primaryHighlight : hifi.colors.textFieldLightBackground; + } + color: hifi.colors.black; + textFormat: TextEdit.PlainText; + wrapMode: TextEdit.Wrap; + activeFocusOnPress: true; + activeFocusOnTab: true; + // Workaround for no max length on TextAreas + onTextChanged: { + if (text.length > maximumLength) { + var cursor = cursorPosition; + text = previousText; + if (cursor > text.length) { + cursorPosition = text.length; + } else { + cursorPosition = cursor-1; + } + } + previousText = text; + } + } + RalewaySemiBold { + id: optionalMessageCharacterCount; + text: optionalMessage.text.length + "/" + optionalMessage.maximumLength; + // Anchors + anchors.top: optionalMessage.bottom; + anchors.topMargin: 2; + anchors.right: optionalMessage.right; + height: paintedHeight; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignTop; + horizontalAlignment: Text.AlignRight; + } + } + + Item { + id: bottomBarContainer; + anchors.top: messageContainer.bottom; + anchors.topMargin: 30; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + HifiControlsUit.CheckBox { + id: sendPubliclyCheckbox; + visible: false; // FIXME ONCE PARTICLE EFFECTS ARE IN + text: "Send Publicly" + // Anchors + anchors.verticalCenter: parent.verticalCenter; + anchors.left: parent.left; + anchors.right: cancelButton_sendMoneyStep.left; + anchors.rightMargin: 16; + boxSize: 24; + } + + // "CANCEL" button + HifiControlsUit.Button { + id: cancelButton_sendMoneyStep; + color: hifi.buttons.noneBorderless; + colorScheme: hifi.colorSchemes.dark; + anchors.right: sendButton.left; + anchors.rightMargin: 16; + anchors.verticalCenter: parent.verticalCenter; + height: 35; + width: 100; + text: "CANCEL"; + onClicked: { + resetSendMoneyData(); + root.nextActiveView = "sendMoneyHome"; + } + } + + // "SEND" button + HifiControlsUit.Button { + id: sendButton; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.right: parent.right; + anchors.verticalCenter: parent.verticalCenter; + height: 35; + width: 100; + text: "SEND"; + onClicked: { + if (parseInt(amountTextField.text) > parseInt(balanceText.text)) { + amountTextField.focus = true; + amountTextField.error = true; + amountTextFieldError.text = "amount exceeds available funds"; + } else if (amountTextField.text === "" || parseInt(amountTextField.text) < 1) { + amountTextField.focus = true; + amountTextField.error = true; + amountTextFieldError.text = "invalid amount"; + } else { + amountTextFieldError.text = ""; + amountTextField.error = false; + root.isCurrentlySendingMoney = true; + amountTextField.focus = false; + optionalMessage.focus = false; + if (sendMoneyStep.referrer === "connections") { + Commerce.transferHfcToUsername(sendMoneyStep.selectedRecipientUserName, parseInt(amountTextField.text), optionalMessage.text); + } else if (sendMoneyStep.referrer === "nearby") { + Commerce.transferHfcToNode(sendMoneyStep.selectedRecipientNodeID, parseInt(amountTextField.text), optionalMessage.text); + } + } + } + } + } + } + } + // Send Money Screen END + + // Sending Money Overlay START + Rectangle { + id: sendingMoneyOverlay; + z: 998; + + visible: root.isCurrentlySendingMoney; + anchors.fill: parent; + color: Qt.rgba(0.0, 0.0, 0.0, 0.5); + + // This object is always used in a popup or full-screen Wallet section. + // This MouseArea is used to prevent a user from being + // able to click on a button/mouseArea underneath the popup/section. + MouseArea { + anchors.fill: parent; + propagateComposedEvents: false; + } + + AnimatedImage { + id: sendingMoneyImage; + source: "../../../../../icons/profilePicLoading.gif" + width: 160; + height: width; + anchors.top: parent.top; + anchors.topMargin: 185; + anchors.horizontalCenter: parent.horizontalCenter; + } + + RalewaySemiBold { + text: "Sending"; + // Anchors + anchors.top: sendingMoneyImage.bottom; + anchors.topMargin: 22; + anchors.horizontalCenter: parent.horizontalCenter; + width: paintedWidth; + // Text size + size: 24; + // Style + color: hifi.colors.white; + verticalAlignment: Text.AlignVCenter; + } + } + // Sending Money Overlay END + + // Payment Success BEGIN + Rectangle { + id: paymentSuccess; + + visible: root.currentActiveView === "paymentSuccess"; + anchors.fill: parent; + color: "#AAAAAA"; + + Rectangle { + anchors.centerIn: parent; + width: parent.width - 30; + height: parent.height - 30; + + RalewaySemiBold { + id: paymentSentText; + text: "Payment Sent"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + } + + HiFiGlyphs { + id: closeGlyphButton_paymentSuccess; + text: hifi.glyphs.close; + size: 26; + anchors.top: parent.top; + anchors.topMargin: 10; + anchors.right: parent.right; + anchors.rightMargin: 10; + MouseArea { + anchors.fill: parent; + hoverEnabled: true; + onEntered: { + parent.text = hifi.glyphs.closeInverted; + } + onExited: { + parent.text = hifi.glyphs.close; + } + onClicked: { + root.nextActiveView = "sendMoneyHome"; + resetSendMoneyData(); + } + } + } + + Item { + id: sendToContainer_paymentSuccess; + anchors.top: paymentSentText.bottom; + anchors.topMargin: 20; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: sendToText_paymentSuccess; + text: "Sent To:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + RecipientDisplay { + anchors.top: parent.top; + anchors.left: sendToText_paymentSuccess.right; + anchors.right: parent.right; + height: parent.height; + + displayName: sendMoneyStep.selectedRecipientDisplayName; + userName: sendMoneyStep.selectedRecipientUserName; + profilePic: sendMoneyStep.selectedRecipientProfilePic !== "" ? ((0 === sendMoneyStep.selectedRecipientProfilePic.indexOf("http")) ? + sendMoneyStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendMoneyStep.selectedRecipientProfilePic)) : ""; + isDisplayingNearby: sendMoneyStep.referrer === "nearby"; + } + } + + Item { + id: amountContainer_paymentSuccess; + anchors.top: sendToContainer_paymentSuccess.bottom; + anchors.topMargin: 16; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: amountText_paymentSuccess; + text: "Amount:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + // "HFC" balance label + HiFiGlyphs { + id: amountSentLabel; + text: hifi.glyphs.hfc; + // Size + size: 32; + // Anchors + anchors.left: amountText_paymentSuccess.right; + anchors.verticalCenter: parent.verticalCenter; + height: 50; + // Style + color: hifi.colors.baseGray; + } + + RalewaySemiBold { + id: amountSentText; + text: amountTextField.text; + // Anchors + anchors.verticalCenter: parent.verticalCenter; + anchors.left: amountSentLabel.right; + anchors.leftMargin: 20; + anchors.right: parent.right; + height: 50; + // Style + size: 22; + color: hifi.colors.baseGray; + } + } + + RalewaySemiBold { + id: optionalMessage_paymentSuccess; + text: optionalMessage.text; + // Anchors + anchors.top: amountContainer_paymentSuccess.bottom; + anchors.left: parent.left; + anchors.leftMargin: 110; + anchors.right: parent.right; + anchors.rightMargin: 16; + anchors.bottom: closeButton.top; + anchors.bottomMargin: 40; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + wrapMode: Text.Wrap; + verticalAlignment: Text.AlignTop; + } + + // "Close" button + HifiControlsUit.Button { + id: closeButton; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.horizontalCenter: parent.horizontalCenter; + anchors.bottom: parent.bottom; + anchors.bottomMargin: 80; + height: 50; + width: 120; + text: "Close"; + onClicked: { + root.nextActiveView = "sendMoneyHome"; + resetSendMoneyData(); + } + } + } + } + // Payment Success END + + // Payment Failure BEGIN + Rectangle { + id: paymentFailure; + + visible: root.currentActiveView === "paymentFailure"; + anchors.fill: parent; + color: "#AAAAAA"; + + Rectangle { + anchors.centerIn: parent; + width: parent.width - 30; + height: parent.height - 30; + + RalewaySemiBold { + id: paymentFailureText; + text: "Payment Failed"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + } + + HiFiGlyphs { + id: closeGlyphButton_paymentFailure; + text: hifi.glyphs.close; + size: 26; + anchors.top: parent.top; + anchors.topMargin: 10; + anchors.right: parent.right; + anchors.rightMargin: 10; + MouseArea { + anchors.fill: parent; + hoverEnabled: true; + onEntered: { + parent.text = hifi.glyphs.closeInverted; + } + onExited: { + parent.text = hifi.glyphs.close; + } + onClicked: { + root.nextActiveView = "sendMoneyHome"; + resetSendMoneyData(); + } + } + } + + RalewaySemiBold { + id: paymentFailureDetailText; + text: "The recipient you specified was unable to receive your payment."; + anchors.top: paymentFailureText.bottom; + anchors.topMargin: 20; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + wrapMode: Text.Wrap; + } + + Item { + id: sendToContainer_paymentFailure; + anchors.top: paymentFailureDetailText.bottom; + anchors.topMargin: 8; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: sentToText_paymentFailure; + text: "Sent To:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + RecipientDisplay { + anchors.top: parent.top; + anchors.left: sentToText_paymentFailure.right; + anchors.right: parent.right; + height: parent.height; + + displayName: sendMoneyStep.selectedRecipientDisplayName; + userName: sendMoneyStep.selectedRecipientUserName; + profilePic: sendMoneyStep.selectedRecipientProfilePic !== "" ? ((0 === sendMoneyStep.selectedRecipientProfilePic.indexOf("http")) ? + sendMoneyStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendMoneyStep.selectedRecipientProfilePic)) : ""; + isDisplayingNearby: sendMoneyStep.referrer === "nearby"; + } + } + + Item { + id: amountContainer_paymentFailure; + anchors.top: sendToContainer_paymentFailure.bottom; + anchors.topMargin: 16; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: amountText_paymentFailure; + text: "Amount:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + // "HFC" balance label + HiFiGlyphs { + id: amountSentLabel_paymentFailure; + text: hifi.glyphs.hfc; + // Size + size: 32; + // Anchors + anchors.left: amountText_paymentFailure.right; + anchors.verticalCenter: parent.verticalCenter; + height: 50; + // Style + color: hifi.colors.baseGray; + } + + RalewaySemiBold { + id: amountSentText_paymentFailure; + text: amountTextField.text; + // Anchors + anchors.verticalCenter: parent.verticalCenter; + anchors.left: amountSentLabel_paymentFailure.right; + anchors.leftMargin: 20; + anchors.right: parent.right; + height: 50; + // Style + size: 22; + color: hifi.colors.baseGray; + } + } + + RalewaySemiBold { + id: optionalMessage_paymentFailuire; + text: optionalMessage.text; + // Anchors + anchors.top: amountContainer_paymentFailure.bottom; + anchors.left: parent.left; + anchors.leftMargin: 110; + anchors.right: parent.right; + anchors.rightMargin: 16; + anchors.bottom: closeButton_paymentFailure.top; + anchors.bottomMargin: 40; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + wrapMode: Text.Wrap; + verticalAlignment: Text.AlignTop; + } + + // "Close" button + HifiControlsUit.Button { + id: closeButton_paymentFailure; + color: hifi.buttons.noneBorderless; + colorScheme: hifi.colorSchemes.dark; + anchors.horizontalCenter: parent.horizontalCenter; + anchors.bottom: parent.bottom; + anchors.bottomMargin: 80; + height: 50; + width: 120; + text: "Cancel"; + onClicked: { + root.nextActiveView = "sendMoneyHome"; + resetSendMoneyData(); + } + } + + // "Retry" button + HifiControlsUit.Button { + id: retryButton_paymentFailure; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.right: parent.right; + anchors.rightMargin: 12; + anchors.bottom: parent.bottom; + anchors.bottomMargin: 80; + height: 50; + width: 120; + text: "Retry"; + onClicked: { + root.isCurrentlySendingMoney = true; + if (sendMoneyStep.referrer === "connections") { + Commerce.transferHfcToUsername(sendMoneyStep.selectedRecipientUserName, parseInt(amountTextField.text), optionalMessage.text); + } else if (sendMoneyStep.referrer === "nearby") { + Commerce.transferHfcToNode(sendMoneyStep.selectedRecipientNodeID, parseInt(amountTextField.text), optionalMessage.text); + } + } + } + } + } + // Payment Failure END + + + // + // FUNCTION DEFINITIONS START + // + + function updateConnections(connections) { + connectionsModel.clear(); + connectionsModel.append(connections); + buildFilteredConnectionsModel(); + connectionsLoading.visible = false; + } + + function buildFilteredConnectionsModel() { + filteredConnectionsModel.clear(); + for (var i = 0; i < connectionsModel.count; i++) { + if (connectionsModel.get(i).userName.toLowerCase().indexOf(filterBar.text.toLowerCase()) !== -1) { + filteredConnectionsModel.append(connectionsModel.get(i)); + } + } + } + + function resetSendMoneyData() { + amountTextField.focus = false; + optionalMessage.focus = false; + amountTextFieldError.text = ""; + amountTextField.error = false; + chooseRecipientNearby.selectedRecipient = ""; + sendMoneyStep.selectedRecipientNodeID = ""; + sendMoneyStep.selectedRecipientDisplayName = ""; + sendMoneyStep.selectedRecipientUserName = ""; + sendMoneyStep.selectedRecipientProfilePic = ""; + amountTextField.text = ""; + optionalMessage.text = ""; + } + + // + // Function Name: fromScript() + // + // Relevant Variables: + // None + // + // Arguments: + // message: The message sent from the JavaScript. + // Messages are in format "{method, params}", like json-rpc. + // + // Description: + // Called when a message is received from a script. + // + function fromScript(message) { + switch (message.method) { + case 'selectRecipient': + if (message.isSelected) { + chooseRecipientNearby.selectedRecipient = message.id[0]; + sendMoneyStep.selectedRecipientDisplayName = message.displayName; + sendMoneyStep.selectedRecipientUserName = message.userName; + } else { + chooseRecipientNearby.selectedRecipient = ""; + sendMoneyStep.selectedRecipientDisplayName = ''; + sendMoneyStep.selectedRecipientUserName = ''; + } + break; + case 'updateSelectedRecipientUsername': + sendMoneyStep.selectedRecipientUserName = message.userName; + break; + default: + console.log('SendMoney: Unrecognized message from wallet.js:', JSON.stringify(message)); + } + } + signal sendSignalToWallet(var msg); + // + // FUNCTION DEFINITIONS END + // +} diff --git a/interface/resources/qml/hifi/tablet/TabletMenuStack.qml b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml index ff653b6457..4fa29de9a3 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenuStack.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml @@ -22,7 +22,6 @@ Item { anchors.fill: parent id: d objectName: "stack" - initialItem: topMenu property var menuStack: [] property var topMenu: null; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e081e80360..6849bd07b5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -157,7 +157,7 @@ #include "scripting/AssetMappingsScriptingInterface.h" #include "scripting/ClipboardScriptingInterface.h" #include "scripting/DesktopScriptingInterface.h" -#include "scripting/GlobalServicesScriptingInterface.h" +#include "scripting/AccountServicesScriptingInterface.h" #include "scripting/HMDScriptingInterface.h" #include "scripting/MenuScriptingInterface.h" #include "scripting/SettingsScriptingInterface.h" @@ -2287,7 +2287,7 @@ void Application::initializeUi() { QUrl{ "hifi/commerce/wallet/SecurityImageChange.qml" }, QUrl{ "hifi/commerce/wallet/SecurityImageModel.qml" }, QUrl{ "hifi/commerce/wallet/SecurityImageSelection.qml" }, - QUrl{ "hifi/commerce/wallet/SendMoney.qml" }, + QUrl{ "hifi/commerce/wallet/sendMoney/SendMoney.qml" }, QUrl{ "hifi/commerce/wallet/Wallet.qml" }, QUrl{ "hifi/commerce/wallet/WalletHome.qml" }, QUrl{ "hifi/commerce/wallet/WalletSetup.qml" }, @@ -2376,9 +2376,11 @@ void Application::initializeUi() { surfaceContext->setContextProperty("SoundCache", DependencyManager::get().data()); surfaceContext->setContextProperty("InputConfiguration", DependencyManager::get().data()); - surfaceContext->setContextProperty("Account", GlobalServicesScriptingInterface::getInstance()); + surfaceContext->setContextProperty("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED + surfaceContext->setContextProperty("GlobalServices", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED + surfaceContext->setContextProperty("AccountServices", AccountServicesScriptingInterface::getInstance()); + surfaceContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface); - surfaceContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); surfaceContext->setContextProperty("FaceTracker", DependencyManager::get().data()); surfaceContext->setContextProperty("AvatarManager", DependencyManager::get().data()); surfaceContext->setContextProperty("UndoStack", &_undoStackScriptingInterface); @@ -5465,7 +5467,7 @@ void Application::clearDomainOctreeDetails() { auto skyStage = DependencyManager::get()->getSkyStage(); - skyStage->setBackgroundMode(model::SunSkyStage::SKY_DEFAULT); + skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT); DependencyManager::get()->clearUnusedResources(); DependencyManager::get()->clearUnusedResources(); @@ -5775,10 +5777,11 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe scriptEngine->registerGlobalObject("ModelCache", DependencyManager::get().data()); scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get().data()); - scriptEngine->registerGlobalObject("Account", GlobalServicesScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("DialogsManager", _dialogsManagerScriptingInterface); - scriptEngine->registerGlobalObject("GlobalServices", GlobalServicesScriptingInterface::getInstance()); + scriptEngine->registerGlobalObject("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED + scriptEngine->registerGlobalObject("GlobalServices", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED + scriptEngine->registerGlobalObject("AccountServices", AccountServicesScriptingInterface::getInstance()); qScriptRegisterMetaType(scriptEngine.data(), DownloadInfoResultToScriptValue, DownloadInfoResultFromScriptValue); scriptEngine->registerGlobalObject("FaceTracker", DependencyManager::get().data()); @@ -6178,7 +6181,7 @@ void Application::showAssetServerWidget(QString filePath) { if (!hmd->getShouldShowTablet() && !isHMDMode()) { DependencyManager::get()->show(url, "AssetServer", startUpload); } else { - static const QUrl url("hifi/dialogs/TabletAssetServer.qml"); + static const QUrl url("../dialogs/TabletAssetServer.qml"); tablet->pushOntoStack(url); } } @@ -7398,11 +7401,13 @@ void Application::updateThreadPoolCount() const { } void Application::updateSystemTabletMode() { - qApp->setProperty(hifi::properties::HMD, isHMDMode()); - if (isHMDMode()) { - DependencyManager::get()->setToolbarMode(getHmdTabletBecomesToolbarSetting()); - } else { - DependencyManager::get()->setToolbarMode(getDesktopTabletBecomesToolbarSetting()); + if (_settingsLoaded) { + qApp->setProperty(hifi::properties::HMD, isHMDMode()); + if (isHMDMode()) { + DependencyManager::get()->setToolbarMode(getHmdTabletBecomesToolbarSetting()); + } else { + DependencyManager::get()->setToolbarMode(getDesktopTabletBecomesToolbarSetting()); + } } } diff --git a/interface/src/Application.h b/interface/src/Application.h index effb35caee..ddb8ce11e5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -71,7 +71,7 @@ #include "UndoStackScriptingInterface.h" #include -#include +#include #include #include "FrameTimingsScriptingInterface.h" @@ -270,7 +270,7 @@ public: void takeSecondaryCameraSnapshot(); void shareSnapshot(const QString& filename, const QUrl& href = QUrl("")); - model::SkyboxPointer getDefaultSkybox() const { return _defaultSkybox; } + graphics::SkyboxPointer getDefaultSkybox() const { return _defaultSkybox; } gpu::TexturePointer getDefaultSkyboxTexture() const { return _defaultSkyboxTexture; } gpu::TexturePointer getDefaultSkyboxAmbientTexture() const { return _defaultSkyboxAmbientTexture; } @@ -667,7 +667,7 @@ private: ConnectionMonitor _connectionMonitor; - model::SkyboxPointer _defaultSkybox { new ProceduralSkybox() } ; + graphics::SkyboxPointer _defaultSkybox { new ProceduralSkybox() } ; gpu::TexturePointer _defaultSkyboxTexture; gpu::TexturePointer _defaultSkyboxAmbientTexture; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 3072ecf240..2a33ee6f7b 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -574,8 +574,6 @@ Menu::Menu() { avatar.get(), SLOT(setEnableMeshVisible(bool))); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::DisableEyelidAdjustment, 0, false); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::TurnWithHead, 0, false); - addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::UseAnimPreAndPostRotations, 0, true, - avatar.get(), SLOT(setUseAnimPreAndPostRotations(bool))); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableInverseKinematics, 0, true, avatar.get(), SLOT(setEnableInverseKinematics(bool))); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderSensorToWorldMatrix, 0, false, diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 854f8d8c2b..11a27ff7f5 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -194,7 +194,6 @@ namespace MenuOption { const QString TurnWithHead = "Turn using Head"; const QString UseAudioForMouth = "Use Audio for Mouth"; const QString UseCamera = "Use Camera"; - const QString UseAnimPreAndPostRotations = "Use Anim Pre and Post Rotations"; const QString VelocityFilter = "Velocity Filter"; const QString VisibleToEveryone = "Everyone"; const QString VisibleToFriends = "Friends"; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e863a58e14..11496f727e 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -537,6 +537,7 @@ void MyAvatar::simulate(float deltaTime) { // we've achived our final adjusted position and rotation for the avatar // and all of its joints, now update our attachements. Avatar::simulateAttachments(deltaTime); + relayJointDataToChildren(); if (!_skeletonModel->hasSkeleton()) { // All the simulation that can be done has been done @@ -1061,11 +1062,6 @@ void MyAvatar::setEnableMeshVisible(bool isEnabled) { _skeletonModel->setVisibleInScene(isEnabled, qApp->getMain3DScene()); } -void MyAvatar::setUseAnimPreAndPostRotations(bool isEnabled) { - AnimClip::usePreAndPostPoseFromAnim = isEnabled; - reset(true); -} - void MyAvatar::setEnableInverseKinematics(bool isEnabled) { _skeletonModel->getRig().setEnableInverseKinematics(isEnabled); } @@ -1929,7 +1925,7 @@ void MyAvatar::preDisplaySide(RenderArgs* renderArgs) { _prevShouldDrawHead = shouldDrawHead; } -const float RENDER_HEAD_CUTOFF_DISTANCE = 0.3f; +const float RENDER_HEAD_CUTOFF_DISTANCE = 0.47f; bool MyAvatar::cameraInsideHead(const glm::vec3& cameraPosition) const { return glm::length(cameraPosition - getHeadPosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getModelScale()); @@ -2100,7 +2096,7 @@ void MyAvatar::updateActionMotor(float deltaTime) { _actionMotorVelocity = motorSpeed * direction; } else { // we're interacting with a floor --> simple horizontal speed and exponential decay - _actionMotorVelocity = getSensorToWorldScale() * DEFAULT_AVATAR_MAX_WALKING_SPEED * direction; + _actionMotorVelocity = getSensorToWorldScale() * _walkSpeed.get() * direction; } float boomChange = getDriveKey(ZOOM); @@ -2692,6 +2688,14 @@ float MyAvatar::getUserEyeHeight() const { return userHeight - userHeight * ratio; } +float MyAvatar::getWalkSpeed() const { + return _walkSpeed.get(); +} + +void MyAvatar::setWalkSpeed(float value) { + _walkSpeed.set(value); +} + glm::vec3 MyAvatar::getPositionForAudio() { switch (_audioListenerMode) { case AudioListenerMode::FROM_HEAD: diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index ab74460d4e..58b49b61ff 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -163,6 +163,8 @@ class MyAvatar : public Avatar { Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT) + Q_PROPERTY(float walkSpeed READ getWalkSpeed WRITE setWalkSpeed); + const QString DOMINANT_LEFT_HAND = "left"; const QString DOMINANT_RIGHT_HAND = "right"; @@ -557,6 +559,9 @@ public: const QUuid& getSelfID() const { return AVATAR_SELF_ID; } + void setWalkSpeed(float value); + float getWalkSpeed() const; + public slots: void increaseSize(); void decreaseSize(); @@ -594,7 +599,6 @@ public slots: bool getEnableMeshVisible() const { return _skeletonModel->isVisible(); } void setEnableMeshVisible(bool isEnabled); - void setUseAnimPreAndPostRotations(bool isEnabled); void setEnableInverseKinematics(bool isEnabled); QUrl getAnimGraphOverrideUrl() const; // thread-safe @@ -841,6 +845,9 @@ private: // height of user in sensor space, when standing erect. ThreadSafeValueCache _userHeight { DEFAULT_AVATAR_HEIGHT }; + + // max unscaled forward movement speed + ThreadSafeValueCache _walkSpeed { DEFAULT_AVATAR_MAX_WALKING_SPEED }; }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 15830636f0..50ea6629cf 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -46,6 +46,8 @@ Handler(buy) Handler(receiveAt) Handler(balance) Handler(inventory) +Handler(transferHfcToNode) +Handler(transferHfcToUsername) void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request) { auto accountManager = DependencyManager::get(); @@ -116,23 +118,60 @@ void Ledger::inventory(const QStringList& keys) { keysQuery("inventory", "inventorySuccess", "inventoryFailure"); } -QString amountString(const QString& label, const QString&color, const QJsonValue& moneyValue, const QJsonValue& certsValue) { - int money = moneyValue.toInt(); - int certs = certsValue.toInt(); - if (money <= 0 && certs <= 0) { - return QString(); +QString hfcString(const QJsonValue& sentValue, const QJsonValue& receivedValue) { + int sent = sentValue.toInt(); + int received = receivedValue.toInt(); + if (sent <= 0 && received <= 0) { + return QString("-"); } - QString result(QString(" %2").arg(color, label)); - if (money > 0) { - result += QString(" %1 HFC").arg(money); - } - if (certs > 0) { - if (money > 0) { - result += QString(","); + QString result; + if (sent > 0) { + result += QString("-%1 HFC").arg(sent); + if (received > 0) { + result += QString("
"); } - result += QString((certs == 1) ? " %1 certificate" : " %1 certificates").arg(certs); } - return result + QString("
"); + if (received > 0) { + result += QString("%1 HFC").arg(received); + } + return result; +} +static const QString USER_PAGE_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/users/"; +QString userLink(const QString& username) { + if (username.isEmpty()) { + return QString("someone"); + } + return QString("%2").arg(USER_PAGE_BASE_URL, username); +} + +QString transactionString(const QJsonObject& valueObject) { + int sentCerts = valueObject["sent_certs"].toInt(); + int receivedCerts = valueObject["received_certs"].toInt(); + int sent = valueObject["sent_money"].toInt(); + int dateInteger = valueObject["created_at"].toInt(); + QString message = valueObject["message"].toString(); + QDateTime createdAt(QDateTime::fromSecsSinceEpoch(dateInteger, Qt::UTC)); + QString result; + + if (sentCerts <= 0 && receivedCerts <= 0) { + // this is an hfc transfer. + if (sent > 0) { + QString recipient = userLink(valueObject["recipient_name"].toString()); + result += QString("Money sent to %1").arg(recipient); + } else { + QString sender = userLink(valueObject["sender_name"].toString()); + result += QString("Money from %1").arg(sender); + } + if (!message.isEmpty()) { + result += QString("
with memo: \"%1\"").arg(message); + } + } else { + result += valueObject["message"].toString(); + } + // no matter what we append a smaller date to the bottom of this... + + result += QString("
%1").arg(createdAt.toLocalTime().toString(Qt::DefaultLocaleShortDate)); + return result; } static const QString MARKETPLACE_ITEMS_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/marketplace/items/"; @@ -155,16 +194,13 @@ void Ledger::historySuccess(QNetworkReply& reply) { // TODO: do this with 0 copies if possible for (auto it = historyArray.begin(); it != historyArray.end(); it++) { + // We have 2 text fields to synthesize, the one on the left is a listing + // of the HFC in/out of your wallet. The one on the right contains an explaination + // of the transaction. That could be just the memo (if it is a regular purchase), or + // more text (plus the optional memo) if an hfc transfer auto valueObject = (*it).toObject(); - QString sent = amountString("sent", "EA4C5F", valueObject["sent_money"], valueObject["sent_certs"]); - QString received = amountString("received", "1FC6A6", valueObject["received_money"], valueObject["received_certs"]); - - // turns out on my machine, toLocalTime convert to some weird timezone, yet the - // systemTimeZone is correct. To avoid a strange bug with other's systems too, lets - // be explicit - QDateTime createdAt = QDateTime::fromSecsSinceEpoch(valueObject["created_at"].toInt(), Qt::UTC); - QDateTime localCreatedAt = createdAt.toTimeZone(QTimeZone::systemTimeZone()); - valueObject["text"] = QString("%1%2%3").arg(valueObject["message"].toString(), sent, received); + valueObject["hfc_text"] = hfcString(valueObject["sent_money"], valueObject["received_money"]); + valueObject["transaction_text"] = transactionString(valueObject); newHistoryArray.push_back(valueObject); } // now copy the rest of the json -- this is inefficient @@ -198,11 +234,17 @@ void Ledger::accountSuccess(QNetworkReply& reply) { auto salt = QByteArray::fromBase64(data["salt"].toString().toUtf8()); auto iv = QByteArray::fromBase64(data["iv"].toString().toUtf8()); auto ckey = QByteArray::fromBase64(data["ckey"].toString().toUtf8()); + QString remotePublicKey = data["public_key"].toString(); wallet->setSalt(salt); wallet->setIv(iv); wallet->setCKey(ckey); + QStringList localPublicKeys = wallet->listPublicKeys(); + if (remotePublicKey.isEmpty() && !localPublicKeys.isEmpty()) { + receiveAt(localPublicKeys.first(), ""); + } + // none of the hfc account info should be emitted emit accountResult(QJsonObject{ {"status", "success"} }); } @@ -261,3 +303,25 @@ void Ledger::certificateInfo(const QString& certificateId) { request["certificate_id"] = certificateId; send(endpoint, "certificateInfoSuccess", "certificateInfoFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::None, request); } + +void Ledger::transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage) { + QJsonObject transaction; + transaction["public_key"] = hfc_key; + transaction["node_id"] = nodeID; + transaction["quantity"] = amount; + transaction["message"] = optionalMessage; + QJsonDocument transactionDoc{ transaction }; + auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); + signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_node", "transferHfcToNodeSuccess", "transferHfcToNodeFailure"); +} + +void Ledger::transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage) { + QJsonObject transaction; + transaction["public_key"] = hfc_key; + transaction["username"] = username; + transaction["quantity"] = amount; + transaction["message"] = optionalMessage; + QJsonDocument transactionDoc{ transaction }; + auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); + signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_user", "transferHfcToUsernameSuccess", "transferHfcToUsernameFailure"); +} diff --git a/interface/src/commerce/Ledger.h b/interface/src/commerce/Ledger.h index 318006b645..1b56c893ab 100644 --- a/interface/src/commerce/Ledger.h +++ b/interface/src/commerce/Ledger.h @@ -33,6 +33,8 @@ public: void account(); void updateLocation(const QString& asset_id, const QString location, const bool controlledFailure = false); void certificateInfo(const QString& certificateId); + void transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage); + void transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage); enum CertificateStatus { CERTIFICATE_STATUS_UNKNOWN = 0, @@ -51,6 +53,8 @@ signals: void accountResult(QJsonObject result); void locationUpdateResult(QJsonObject result); void certificateInfoResult(QJsonObject result); + void transferHfcToNodeResult(QJsonObject result); + void transferHfcToUsernameResult(QJsonObject result); void updateCertificateStatus(const QString& certID, uint certStatus); @@ -71,6 +75,10 @@ public slots: void updateLocationFailure(QNetworkReply& reply); void certificateInfoSuccess(QNetworkReply& reply); void certificateInfoFailure(QNetworkReply& reply); + void transferHfcToNodeSuccess(QNetworkReply& reply); + void transferHfcToNodeFailure(QNetworkReply& reply); + void transferHfcToUsernameSuccess(QNetworkReply& reply); + void transferHfcToUsernameFailure(QNetworkReply& reply); private: QJsonObject apiResponse(const QString& label, QNetworkReply& reply); diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index 58548eb3ef..c9caa393ce 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -29,6 +29,8 @@ QmlCommerce::QmlCommerce() { connect(wallet.data(), &Wallet::walletStatusResult, this, &QmlCommerce::walletStatusResult); connect(ledger.data(), &Ledger::certificateInfoResult, this, &QmlCommerce::certificateInfoResult); connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus); + connect(ledger.data(), &Ledger::transferHfcToNodeResult, this, &QmlCommerce::transferHfcToNodeResult); + connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult); auto accountManager = DependencyManager::get(); connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { @@ -137,3 +139,27 @@ void QmlCommerce::certificateInfo(const QString& certificateId) { auto ledger = DependencyManager::get(); ledger->certificateInfo(certificateId); } + +void QmlCommerce::transferHfcToNode(const QString& nodeID, const int& amount, const QString& optionalMessage) { + auto ledger = DependencyManager::get(); + auto wallet = DependencyManager::get(); + QStringList keys = wallet->listPublicKeys(); + if (keys.count() == 0) { + QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; + return emit buyResult(result); + } + QString key = keys[0]; + ledger->transferHfcToNode(key, nodeID, amount, optionalMessage); +} + +void QmlCommerce::transferHfcToUsername(const QString& username, const int& amount, const QString& optionalMessage) { + auto ledger = DependencyManager::get(); + auto wallet = DependencyManager::get(); + QStringList keys = wallet->listPublicKeys(); + if (keys.count() == 0) { + QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; + return emit buyResult(result); + } + QString key = keys[0]; + ledger->transferHfcToUsername(key, username, amount, optionalMessage); +} diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index c04ede86c4..b261ee6de6 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -45,6 +45,9 @@ signals: void updateCertificateStatus(const QString& certID, uint certStatus); + void transferHfcToNodeResult(QJsonObject result); + void transferHfcToUsernameResult(QJsonObject result); + protected: Q_INVOKABLE void getWalletStatus(); @@ -65,6 +68,9 @@ protected: Q_INVOKABLE void account(); Q_INVOKABLE void certificateInfo(const QString& certificateId); + + Q_INVOKABLE void transferHfcToNode(const QString& nodeID, const int& amount, const QString& optionalMessage); + Q_INVOKABLE void transferHfcToUsername(const QString& username, const int& amount, const QString& optionalMessage); }; #endif // hifi_QmlCommerce_h diff --git a/interface/src/scripting/AccountScriptingInterface.cpp b/interface/src/scripting/AccountScriptingInterface.cpp deleted file mode 100644 index fd54198b3c..0000000000 --- a/interface/src/scripting/AccountScriptingInterface.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// -// AccountScriptingInterface.cpp -// interface/src/scripting -// -// Created by Stojce Slavkovski on 6/07/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "AccountManager.h" - -#include "AccountScriptingInterface.h" -#include "GlobalServicesScriptingInterface.h" - -AccountScriptingInterface* AccountScriptingInterface::getInstance() { - static AccountScriptingInterface sharedInstance; - return &sharedInstance; -} - -bool AccountScriptingInterface::isLoggedIn() { - return GlobalServicesScriptingInterface::getInstance()->isLoggedIn(); -} - -void AccountScriptingInterface::logOut() { - GlobalServicesScriptingInterface::getInstance()->logOut(); -} - -bool AccountScriptingInterface::loggedIn() const { - return GlobalServicesScriptingInterface::getInstance()->loggedIn(); -} - -QString AccountScriptingInterface::getUsername() { - return GlobalServicesScriptingInterface::getInstance()->getUsername(); -} diff --git a/interface/src/scripting/AccountScriptingInterface.h b/interface/src/scripting/AccountScriptingInterface.h deleted file mode 100644 index 10d33ffa36..0000000000 --- a/interface/src/scripting/AccountScriptingInterface.h +++ /dev/null @@ -1,60 +0,0 @@ -// -// AccountScriptingInterface.h -// interface/src/scripting -// -// Created by Stojce Slavkovski on 6/07/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_AccountScriptingInterface_h -#define hifi_AccountScriptingInterface_h - -#include - -class AccountScriptingInterface : public QObject { - Q_OBJECT - - /**jsdoc - * @namespace Account - * @property username {String} username if user is logged in, otherwise it returns "Unknown user" - */ - Q_PROPERTY(QString username READ getUsername) - Q_PROPERTY(bool loggedIn READ loggedIn) - -signals: - - /**jsdoc - * Triggered when username has changed. - * @function Account.usernameChanged - * @return {Signal} - */ - void usernameChanged(); - void loggedInChanged(bool loggedIn); - -public slots: - static AccountScriptingInterface* getInstance(); - - /**jsdoc - * Returns the username for the currently logged in High Fidelity metaverse account. - * @function Account.getUsername - * @return {string} username if user is logged in, otherwise it returns "Unknown user" - */ - QString getUsername(); - - /**jsdoc - * Determine if the user is logged into the High Fidleity metaverse. - * @function Account.isLoggedIn - * @return {bool} true when user is logged into the High Fidelity metaverse. - */ - bool isLoggedIn(); - void logOut(); - -public: - AccountScriptingInterface(QObject* parent = nullptr) {} - bool loggedIn() const; -}; - -#endif // hifi_AccountScriptingInterface_h diff --git a/interface/src/scripting/GlobalServicesScriptingInterface.cpp b/interface/src/scripting/AccountServicesScriptingInterface.cpp similarity index 71% rename from interface/src/scripting/GlobalServicesScriptingInterface.cpp rename to interface/src/scripting/AccountServicesScriptingInterface.cpp index 305bfa3e79..fc293098bb 100644 --- a/interface/src/scripting/GlobalServicesScriptingInterface.cpp +++ b/interface/src/scripting/AccountServicesScriptingInterface.cpp @@ -1,5 +1,5 @@ // -// GlobalServicesScriptingInterface.cpp +// AccountServicesScriptingInterface.cpp // interface/src/scripting // // Created by Thijs Wenker on 9/10/14. @@ -14,41 +14,41 @@ #include "DiscoverabilityManager.h" #include "ResourceCache.h" -#include "GlobalServicesScriptingInterface.h" +#include "AccountServicesScriptingInterface.h" -GlobalServicesScriptingInterface::GlobalServicesScriptingInterface() { +AccountServicesScriptingInterface::AccountServicesScriptingInterface() { auto accountManager = DependencyManager::get(); - connect(accountManager.data(), &AccountManager::usernameChanged, this, &GlobalServicesScriptingInterface::onUsernameChanged); - connect(accountManager.data(), &AccountManager::logoutComplete, this, &GlobalServicesScriptingInterface::loggedOut); - connect(accountManager.data(), &AccountManager::loginComplete, this, &GlobalServicesScriptingInterface::connected); + connect(accountManager.data(), &AccountManager::usernameChanged, this, &AccountServicesScriptingInterface::onUsernameChanged); + connect(accountManager.data(), &AccountManager::logoutComplete, this, &AccountServicesScriptingInterface::loggedOut); + connect(accountManager.data(), &AccountManager::loginComplete, this, &AccountServicesScriptingInterface::connected); _downloading = false; QTimer* checkDownloadTimer = new QTimer(this); - connect(checkDownloadTimer, &QTimer::timeout, this, &GlobalServicesScriptingInterface::checkDownloadInfo); + connect(checkDownloadTimer, &QTimer::timeout, this, &AccountServicesScriptingInterface::checkDownloadInfo); const int CHECK_DOWNLOAD_INTERVAL = MSECS_PER_SECOND / 2; checkDownloadTimer->start(CHECK_DOWNLOAD_INTERVAL); auto discoverabilityManager = DependencyManager::get(); connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged, - this, &GlobalServicesScriptingInterface::discoverabilityModeChanged); + this, &AccountServicesScriptingInterface::discoverabilityModeChanged); _loggedIn = isLoggedIn(); emit loggedInChanged(_loggedIn); } -GlobalServicesScriptingInterface::~GlobalServicesScriptingInterface() { +AccountServicesScriptingInterface::~AccountServicesScriptingInterface() { auto accountManager = DependencyManager::get(); - disconnect(accountManager.data(), &AccountManager::usernameChanged, this, &GlobalServicesScriptingInterface::onUsernameChanged); - disconnect(accountManager.data(), &AccountManager::logoutComplete, this, &GlobalServicesScriptingInterface::loggedOut); - disconnect(accountManager.data(), &AccountManager::loginComplete, this, &GlobalServicesScriptingInterface::connected); + disconnect(accountManager.data(), &AccountManager::usernameChanged, this, &AccountServicesScriptingInterface::onUsernameChanged); + disconnect(accountManager.data(), &AccountManager::logoutComplete, this, &AccountServicesScriptingInterface::loggedOut); + disconnect(accountManager.data(), &AccountManager::loginComplete, this, &AccountServicesScriptingInterface::connected); } -GlobalServicesScriptingInterface* GlobalServicesScriptingInterface::getInstance() { - static GlobalServicesScriptingInterface sharedInstance; +AccountServicesScriptingInterface* AccountServicesScriptingInterface::getInstance() { + static AccountServicesScriptingInterface sharedInstance; return &sharedInstance; } -const QString GlobalServicesScriptingInterface::getUsername() const { +const QString AccountServicesScriptingInterface::getUsername() const { auto accountManager = DependencyManager::get(); if (accountManager->isLoggedIn()) { return accountManager->getAccountInfo().getUsername(); @@ -57,31 +57,31 @@ const QString GlobalServicesScriptingInterface::getUsername() const { } } -bool GlobalServicesScriptingInterface::isLoggedIn() { +bool AccountServicesScriptingInterface::isLoggedIn() { auto accountManager = DependencyManager::get(); return accountManager->isLoggedIn(); } -bool GlobalServicesScriptingInterface::checkAndSignalForAccessToken() { +bool AccountServicesScriptingInterface::checkAndSignalForAccessToken() { auto accountManager = DependencyManager::get(); return accountManager->checkAndSignalForAccessToken(); } -void GlobalServicesScriptingInterface::logOut() { +void AccountServicesScriptingInterface::logOut() { auto accountManager = DependencyManager::get(); return accountManager->logout(); } -void GlobalServicesScriptingInterface::loggedOut() { - emit GlobalServicesScriptingInterface::disconnected(QString("logout")); +void AccountServicesScriptingInterface::loggedOut() { + emit AccountServicesScriptingInterface::disconnected(QString("logout")); } -QString GlobalServicesScriptingInterface::getFindableBy() const { +QString AccountServicesScriptingInterface::getFindableBy() const { auto discoverabilityManager = DependencyManager::get(); return DiscoverabilityManager::findableByString(discoverabilityManager->getDiscoverabilityMode()); } -void GlobalServicesScriptingInterface::setFindableBy(const QString& discoverabilityMode) { +void AccountServicesScriptingInterface::setFindableBy(const QString& discoverabilityMode) { auto discoverabilityManager = DependencyManager::get(); if (discoverabilityMode.toLower() == "none") { discoverabilityManager->setDiscoverabilityMode(Discoverability::None); @@ -96,11 +96,11 @@ void GlobalServicesScriptingInterface::setFindableBy(const QString& discoverabil } } -void GlobalServicesScriptingInterface::discoverabilityModeChanged(Discoverability::Mode discoverabilityMode) { +void AccountServicesScriptingInterface::discoverabilityModeChanged(Discoverability::Mode discoverabilityMode) { emit findableByChanged(DiscoverabilityManager::findableByString(discoverabilityMode)); } -void GlobalServicesScriptingInterface::onUsernameChanged(const QString& username) { +void AccountServicesScriptingInterface::onUsernameChanged(const QString& username) { _loggedIn = (username != QString()); emit myUsernameChanged(username); emit loggedInChanged(_loggedIn); @@ -135,7 +135,7 @@ void DownloadInfoResultFromScriptValue(const QScriptValue& object, DownloadInfoR result.pending = object.property("pending").toVariant().toFloat(); } -DownloadInfoResult GlobalServicesScriptingInterface::getDownloadInfo() { +DownloadInfoResult AccountServicesScriptingInterface::getDownloadInfo() { DownloadInfoResult result; foreach(const auto& resource, ResourceCache::getLoadingRequests()) { result.downloading.append(resource->getProgress() * 100.0f); @@ -144,7 +144,7 @@ DownloadInfoResult GlobalServicesScriptingInterface::getDownloadInfo() { return result; } -void GlobalServicesScriptingInterface::checkDownloadInfo() { +void AccountServicesScriptingInterface::checkDownloadInfo() { DownloadInfoResult downloadInfo = getDownloadInfo(); bool downloading = downloadInfo.downloading.count() > 0 || downloadInfo.pending > 0; @@ -155,7 +155,7 @@ void GlobalServicesScriptingInterface::checkDownloadInfo() { } } -void GlobalServicesScriptingInterface::updateDownloadInfo() { +void AccountServicesScriptingInterface::updateDownloadInfo() { emit downloadInfoChanged(getDownloadInfo()); } diff --git a/interface/src/scripting/GlobalServicesScriptingInterface.h b/interface/src/scripting/AccountServicesScriptingInterface.h similarity index 84% rename from interface/src/scripting/GlobalServicesScriptingInterface.h rename to interface/src/scripting/AccountServicesScriptingInterface.h index 93d35e9ce8..012c37305d 100644 --- a/interface/src/scripting/GlobalServicesScriptingInterface.h +++ b/interface/src/scripting/AccountServicesScriptingInterface.h @@ -1,5 +1,5 @@ // -// GlobalServicesScriptingInterface.h +// AccountServicesScriptingInterface.h // interface/src/scripting // // Created by Thijs Wenker on 9/10/14. @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_GlobalServicesScriptingInterface_h -#define hifi_GlobalServicesScriptingInterface_h +#ifndef hifi_AccountServicesScriptingInterface_h +#define hifi_AccountServicesScriptingInterface_h #include #include @@ -32,7 +32,7 @@ Q_DECLARE_METATYPE(DownloadInfoResult) QScriptValue DownloadInfoResultToScriptValue(QScriptEngine* engine, const DownloadInfoResult& result); void DownloadInfoResultFromScriptValue(const QScriptValue& object, DownloadInfoResult& result); -class GlobalServicesScriptingInterface : public QObject { +class AccountServicesScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(QString username READ getUsername NOTIFY myUsernameChanged) @@ -41,7 +41,7 @@ class GlobalServicesScriptingInterface : public QObject { Q_PROPERTY(QUrl metaverseServerURL READ getMetaverseServerURL) public: - static GlobalServicesScriptingInterface* getInstance(); + static AccountServicesScriptingInterface* getInstance(); const QString getUsername() const; bool loggedIn() const { return _loggedIn; } @@ -74,11 +74,11 @@ signals: void loggedInChanged(bool loggedIn); private: - GlobalServicesScriptingInterface(); - ~GlobalServicesScriptingInterface(); + AccountServicesScriptingInterface(); + ~AccountServicesScriptingInterface(); bool _downloading; bool _loggedIn{ false }; }; -#endif // hifi_GlobalServicesScriptingInterface_h +#endif // hifi_AccountServicesScriptingInterface_h diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index e36b84ac96..e50eb06355 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -411,6 +411,11 @@ int WindowScriptingInterface::getY() { } void WindowScriptingInterface::copyToClipboard(const QString& text) { + if (QThread::currentThread() != qApp->thread()) { + QMetaObject::invokeMethod(this, "copyToClipboard", Q_ARG(QString, text)); + return; + } + qDebug() << "Copying"; QApplication::clipboard()->setText(text); } diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index af9c03a218..bfad5644bf 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -42,7 +42,7 @@ void CustomPromptResultFromScriptValue(const QScriptValue& object, CustomPromptR * @property {number} innerWidth - The width of the drawable area of the Interface window (i.e., without borders or other * chrome), in pixels. Read-only. * @property {number} innerHeight - The height of the drawable area of the Interface window (i.e., without borders or other - * chrome) plus the height of the menu bar, in pixels. Read-only. + * chrome), in pixels. Read-only. * @property {object} location - Provides facilities for working with your current metaverse location. See {@link location}. * @property {number} x - The x coordinate of the top left corner of the Interface window on the display. Read-only. * @property {number} y - The y coordinate of the top left corner of the Interface window on the display. Read-only. @@ -301,7 +301,7 @@ public slots: /**jsdoc * Get Interface's build number. * @function Window.checkVersion - * @returns {string} - Interface's build number. + * @returns {string} Interface's build number. */ QString checkVersion(); @@ -327,7 +327,7 @@ public slots: * full resolution is used (window dimensions in desktop mode; HMD display dimensions in HMD mode), otherwise one of the * dimensions is adjusted in order to match the aspect ratio. * @example Using the snapshot function and signals. - * function onStillSnapshottaken(path, notify) { + * function onStillSnapshotTaken(path, notify) { * print("Still snapshot taken: " + path); * print("Notify: " + notify); * } @@ -340,7 +340,7 @@ public slots: * print("Animated snapshot taken: " + animatedPath); * } * - * Window.stillSnapshotTaken.connect(onStillSnapshottaken); + * Window.stillSnapshotTaken.connect(onStillSnapshotTaken); * Window.processingGifStarted.connect(onProcessingGifStarted); * Window.processingGifCompleted.connect(onProcessingGifCompleted); * @@ -555,7 +555,7 @@ signals: /**jsdoc * Triggered when a still snapshot has been taken by calling {@link Window.takeSnapshot|takeSnapshot} with - * includeAnimated = false. + * includeAnimated = false or {@link Window.takeSecondaryCameraSnapshot|takeSecondaryCameraSnapshot}. * @function Window.stillSnapshotTaken * @param {string} pathStillSnapshot - The path and name of the snapshot image file. * @param {boolean} notify - The value of the notify parameter that {@link Window.takeSnapshot|takeSnapshot} diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 96b68f5ae0..9f0189c047 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -50,7 +50,7 @@ #include "ui/DomainConnectionModel.h" #include "ui/AvatarInputs.h" #include "avatar/AvatarManager.h" -#include "scripting/GlobalServicesScriptingInterface.h" +#include "scripting/AccountServicesScriptingInterface.h" #include #include "ui/Snapshot.h" #include "SoundCache.h" @@ -192,7 +192,10 @@ void Web3DOverlay::setupQmlSurface() { _webSurface->getSurfaceContext()->setContextProperty("offscreenFlags", flags); _webSurface->getSurfaceContext()->setContextProperty("AddressManager", DependencyManager::get().data()); - _webSurface->getSurfaceContext()->setContextProperty("Account", GlobalServicesScriptingInterface::getInstance()); + + _webSurface->getSurfaceContext()->setContextProperty("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED + _webSurface->getSurfaceContext()->setContextProperty("GlobalServices", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED + _webSurface->getSurfaceContext()->setContextProperty("AccountServices", AccountServicesScriptingInterface::getInstance()); // in Qt 5.10.0 there is already an "Audio" object in the QML context // though I failed to find it (from QtMultimedia??). So.. let it be "AudioScriptingInterface" @@ -208,7 +211,6 @@ void Web3DOverlay::setupQmlSurface() { _webSurface->getSurfaceContext()->setContextProperty("OctreeStats", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("DCModel", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); - _webSurface->getSurfaceContext()->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); _webSurface->getSurfaceContext()->setContextProperty("AvatarList", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance()); _webSurface->getSurfaceContext()->setContextProperty("InputConfiguration", DependencyManager::get().data()); diff --git a/libraries/animation/CMakeLists.txt b/libraries/animation/CMakeLists.txt index b9fef19fbb..1ec6194afd 100644 --- a/libraries/animation/CMakeLists.txt +++ b/libraries/animation/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME animation) setup_hifi_library(Network Script) -link_hifi_libraries(shared model fbx) +link_hifi_libraries(shared graphics fbx) include_hifi_library_headers(networking) include_hifi_library_headers(gpu) diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index 1118e21c91..2ead4558fe 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -13,8 +13,6 @@ #include "AnimationLogging.h" #include "AnimUtil.h" -bool AnimClip::usePreAndPostPoseFromAnim = true; - AnimClip::AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag) : AnimNode(AnimNode::Type::Clip, id), _startFrame(startFrame), @@ -138,14 +136,8 @@ void AnimClip::copyFromNetworkAnim() { if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) { AnimPose preRot, postRot; - if (usePreAndPostPoseFromAnim) { - preRot = animSkeleton.getPreRotationPose(animJoint); - postRot = animSkeleton.getPostRotationPose(animJoint); - } else { - // In order to support Blender, which does not have preRotation FBX support, we use the models defaultPose as the reference frame for the animations. - preRot = AnimPose(glm::vec3(1.0f), _skeleton->getRelativeBindPose(skeletonJoint).rot(), glm::vec3()); - postRot = AnimPose::identity; - } + preRot = animSkeleton.getPreRotationPose(animJoint); + postRot = animSkeleton.getPostRotationPose(animJoint); // cancel out scale preRot.scale() = glm::vec3(1.0f); diff --git a/libraries/animation/src/AnimClip.h b/libraries/animation/src/AnimClip.h index c7e7ebf3ee..717972ca26 100644 --- a/libraries/animation/src/AnimClip.h +++ b/libraries/animation/src/AnimClip.h @@ -25,8 +25,6 @@ class AnimClip : public AnimNode { public: friend class AnimTests; - static bool usePreAndPostPoseFromAnim; - AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag); virtual ~AnimClip() override; diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index c8388c3b12..e9f9f8818f 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -1255,7 +1255,7 @@ void AnimInverseKinematics::initConstraints() { // / / // O--O O--O - loadDefaultPoses(_skeleton->getRelativeBindPoses()); + loadDefaultPoses(_skeleton->getRelativeDefaultPoses()); int numJoints = (int)_defaultRelativePoses.size(); diff --git a/libraries/animation/src/AnimManipulator.cpp b/libraries/animation/src/AnimManipulator.cpp index 070949ab3b..46b3cf1c28 100644 --- a/libraries/animation/src/AnimManipulator.cpp +++ b/libraries/animation/src/AnimManipulator.cpp @@ -33,7 +33,7 @@ AnimManipulator::~AnimManipulator() { } const AnimPoseVec& AnimManipulator::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) { - return overlay(animVars, context, dt, triggersOut, _skeleton->getRelativeBindPoses()); + return overlay(animVars, context, dt, triggersOut, _skeleton->getRelativeDefaultPoses()); } const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) { diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 804ffb0583..2bce16c5ca 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -56,14 +56,6 @@ int AnimSkeleton::getChainDepth(int jointIndex) const { } } -const AnimPose& AnimSkeleton::getAbsoluteBindPose(int jointIndex) const { - return _absoluteBindPoses[jointIndex]; -} - -const AnimPose& AnimSkeleton::getRelativeBindPose(int jointIndex) const { - return _relativeBindPoses[jointIndex]; -} - const AnimPose& AnimSkeleton::getRelativeDefaultPose(int jointIndex) const { return _relativeDefaultPoses[jointIndex]; } @@ -164,8 +156,6 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints) _joints = joints; _jointsSize = (int)joints.size(); // build a cache of bind poses - _absoluteBindPoses.reserve(_jointsSize); - _relativeBindPoses.reserve(_jointsSize); // build a chache of default poses _absoluteDefaultPoses.reserve(_jointsSize); @@ -192,28 +182,6 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints) } else { _absoluteDefaultPoses.push_back(relDefaultPose); } - - // build relative and absolute bind poses - if (_joints[i].bindTransformFoundInCluster) { - // Use the FBXJoint::bindTransform, which is absolute model coordinates - // i.e. not relative to it's parent. - AnimPose absoluteBindPose(_joints[i].bindTransform); - _absoluteBindPoses.push_back(absoluteBindPose); - if (parentIndex >= 0) { - AnimPose inverseParentAbsoluteBindPose = _absoluteBindPoses[parentIndex].inverse(); - _relativeBindPoses.push_back(inverseParentAbsoluteBindPose * absoluteBindPose); - } else { - _relativeBindPoses.push_back(absoluteBindPose); - } - } else { - // use default transform instead - _relativeBindPoses.push_back(relDefaultPose); - if (parentIndex >= 0) { - _absoluteBindPoses.push_back(_absoluteBindPoses[parentIndex] * relDefaultPose); - } else { - _absoluteBindPoses.push_back(relDefaultPose); - } - } } for (int i = 0; i < _jointsSize; i++) { @@ -251,8 +219,6 @@ void AnimSkeleton::dump(bool verbose) const { qCDebug(animation) << " {"; qCDebug(animation) << " index =" << i; qCDebug(animation) << " name =" << getJointName(i); - qCDebug(animation) << " absBindPose =" << getAbsoluteBindPose(i); - qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i); qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i); qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i); if (verbose) { @@ -287,8 +253,6 @@ void AnimSkeleton::dump(const AnimPoseVec& poses) const { qCDebug(animation) << " {"; qCDebug(animation) << " index =" << i; qCDebug(animation) << " name =" << getJointName(i); - qCDebug(animation) << " absBindPose =" << getAbsoluteBindPose(i); - qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i); qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i); qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i); qCDebug(animation) << " pose =" << poses[i]; diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 99c9a148f7..664358f414 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -30,13 +30,6 @@ public: int getNumJoints() const; int getChainDepth(int jointIndex) const; - // absolute pose, not relative to parent - const AnimPose& getAbsoluteBindPose(int jointIndex) const; - - // relative to parent pose - const AnimPose& getRelativeBindPose(int jointIndex) const; - const AnimPoseVec& getRelativeBindPoses() const { return _relativeBindPoses; } - // the default poses are the orientations of the joints on frame 0. const AnimPose& getRelativeDefaultPose(int jointIndex) const; const AnimPoseVec& getRelativeDefaultPoses() const { return _relativeDefaultPoses; } @@ -72,8 +65,6 @@ protected: std::vector _joints; int _jointsSize { 0 }; - AnimPoseVec _absoluteBindPoses; - AnimPoseVec _relativeBindPoses; AnimPoseVec _relativeDefaultPoses; AnimPoseVec _absoluteDefaultPoses; AnimPoseVec _relativePreRotationPoses; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index daa1c2618f..1c9d9a3447 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -179,7 +179,7 @@ void Rig::restoreRoleAnimation(const QString& role) { } else { qCWarning(animation) << "Rig::restoreRoleAnimation could not find role " << role; } - + auto statesIter = _roleAnimStates.find(role); if (statesIter != _roleAnimStates.end()) { _roleAnimStates.erase(statesIter); @@ -1050,52 +1050,6 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons } } -void Rig::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::quat& targetRotation, float priority, - const QVector& freeLineage, glm::mat4 rootTransform) { - ASSERT(false); -} - -bool Rig::restoreJointPosition(int jointIndex, float fraction, float priority, const QVector& freeLineage) { - ASSERT(false); - return false; -} - -float Rig::getLimbLength(int jointIndex, const QVector& freeLineage, - const glm::vec3 scale, const QVector& fbxJoints) const { - ASSERT(false); - return 1.0f; -} - -glm::quat Rig::setJointRotationInBindFrame(int jointIndex, const glm::quat& rotation, float priority) { - ASSERT(false); - return glm::quat(); -} - -glm::vec3 Rig::getJointDefaultTranslationInConstrainedFrame(int jointIndex) { - ASSERT(false); - return glm::vec3(); -} - -glm::quat Rig::setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, float priority, float mix) { - ASSERT(false); - return glm::quat(); -} - -bool Rig::getJointRotationInConstrainedFrame(int jointIndex, glm::quat& quatOut) const { - ASSERT(false); - return false; -} - -void Rig::clearJointStatePriorities() { - ASSERT(false); -} - -glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) { - ASSERT(false); - return glm::quat(); -} - - void Rig::updateFromEyeParameters(const EyeParameters& params) { updateEyeJoint(params.leftEyeJointIndex, params.modelTranslation, params.modelRotation, params.eyeLookAt, params.eyeSaccade); updateEyeJoint(params.rightEyeJointIndex, params.modelTranslation, params.modelRotation, params.eyeLookAt, params.eyeSaccade); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 6968d7c3af..87277af754 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -172,36 +172,6 @@ public: // Regardless of who started the animations or how many, update the joints. void updateAnimations(float deltaTime, const glm::mat4& rootTransform, const glm::mat4& rigToWorldTransform); - // legacy - void inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::quat& targetRotation, float priority, - const QVector& freeLineage, glm::mat4 rootTransform); - - // legacy - bool restoreJointPosition(int jointIndex, float fraction, float priority, const QVector& freeLineage); - - // legacy - float getLimbLength(int jointIndex, const QVector& freeLineage, - const glm::vec3 scale, const QVector& fbxJoints) const; - - // legacy - glm::quat setJointRotationInBindFrame(int jointIndex, const glm::quat& rotation, float priority); - - // legacy - glm::vec3 getJointDefaultTranslationInConstrainedFrame(int jointIndex); - - // legacy - glm::quat setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, - float priority, float mix = 1.0f); - - // legacy - bool getJointRotationInConstrainedFrame(int jointIndex, glm::quat& rotOut) const; - - // legacy - glm::quat getJointDefaultRotationInParentFrame(int jointIndex); - - // legacy - void clearJointStatePriorities(); - void updateFromControllerParameters(const ControllerParameters& params, float dt); void updateFromEyeParameters(const EyeParameters& params); @@ -345,7 +315,7 @@ protected: float firstFrame; float lastFrame; }; - + struct RoleAnimState { RoleAnimState() {} RoleAnimState(const QString& roleId, const QString& urlIn, float fpsIn, bool loopIn, float firstFrameIn, float lastFrameIn) : diff --git a/libraries/avatars-renderer/CMakeLists.txt b/libraries/avatars-renderer/CMakeLists.txt index 148835965e..53edc692f2 100644 --- a/libraries/avatars-renderer/CMakeLists.txt +++ b/libraries/avatars-renderer/CMakeLists.txt @@ -1,7 +1,7 @@ set(TARGET_NAME avatars-renderer) -AUTOSCRIBE_SHADER_LIB(gpu model render render-utils) +AUTOSCRIBE_SHADER_LIB(gpu graphics render render-utils) setup_hifi_library(Widgets Network Script) -link_hifi_libraries(shared gpu model animation model-networking script-engine render render-utils image trackers entities-renderer) +link_hifi_libraries(shared gpu graphics animation model-networking script-engine render render-utils image trackers entities-renderer) include_hifi_library_headers(avatars) include_hifi_library_headers(networking) include_hifi_library_headers(fbx) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index c532e7659f..0f9573bb84 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -32,6 +32,8 @@ #include #include #include +#include "ModelEntityItem.h" +#include "RenderableModelEntityItem.h" #include "Logging.h" @@ -347,6 +349,65 @@ void Avatar::updateAvatarEntities() { setAvatarEntityDataChanged(false); } +void Avatar::relayJointDataToChildren() { + forEachChild([&](SpatiallyNestablePointer child) { + if (child->getNestableType() == NestableType::Entity) { + auto modelEntity = std::dynamic_pointer_cast(child); + if (modelEntity) { + if (modelEntity->getRelayParentJoints()) { + if (!modelEntity->getJointMapCompleted() || _reconstructSoftEntitiesJointMap) { + QStringList modelJointNames = modelEntity->getJointNames(); + int numJoints = modelJointNames.count(); + std::vector map; + map.reserve(numJoints); + for (int jointIndex = 0; jointIndex < numJoints; jointIndex++) { + QString jointName = modelJointNames.at(jointIndex); + int avatarJointIndex = getJointIndex(jointName); + glm::quat jointRotation; + glm::vec3 jointTranslation; + if (avatarJointIndex < 0) { + jointRotation = modelEntity->getAbsoluteJointRotationInObjectFrame(jointIndex); + jointTranslation = modelEntity->getAbsoluteJointTranslationInObjectFrame(jointIndex); + map.push_back(-1); + } else { + int jointIndex = getJointIndex(jointName); + jointRotation = getJointRotation(jointIndex); + jointTranslation = getJointTranslation(jointIndex); + map.push_back(avatarJointIndex); + } + modelEntity->setLocalJointRotation(jointIndex, jointRotation); + modelEntity->setLocalJointTranslation(jointIndex, jointTranslation); + } + modelEntity->setJointMap(map); + } else { + QStringList modelJointNames = modelEntity->getJointNames(); + int numJoints = modelJointNames.count(); + for (int jointIndex = 0; jointIndex < numJoints; jointIndex++) { + int avatarJointIndex = modelEntity->avatarJointIndex(jointIndex); + glm::quat jointRotation; + glm::vec3 jointTranslation; + if (avatarJointIndex >=0) { + jointRotation = getJointRotation(avatarJointIndex); + jointTranslation = getJointTranslation(avatarJointIndex); + } else { + jointRotation = modelEntity->getAbsoluteJointRotationInObjectFrame(jointIndex); + jointTranslation = modelEntity->getAbsoluteJointTranslationInObjectFrame(jointIndex); + } + modelEntity->setLocalJointRotation(jointIndex, jointRotation); + modelEntity->setLocalJointTranslation(jointIndex, jointTranslation); + } + } + Transform avatarTransform = _skeletonModel->getTransform(); + avatarTransform.setScale(_skeletonModel->getScale()); + modelEntity->setOverrideTransform(avatarTransform, _skeletonModel->getOffset()); + modelEntity->simulateRelayedJoints(); + } + } + } + }); + _reconstructSoftEntitiesJointMap = false; +} + void Avatar::simulate(float deltaTime, bool inView) { PROFILE_RANGE(simulation, "simulate"); @@ -379,6 +440,7 @@ void Avatar::simulate(float deltaTime, bool inView) { } head->setScale(getModelScale()); head->simulate(deltaTime); + relayJointDataToChildren(); } else { // a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated. _skeletonModel->simulate(deltaTime, false); @@ -1197,6 +1259,7 @@ void Avatar::setModelURLFinished(bool success) { invalidateJointIndicesCache(); _isAnimatingScale = true; + _reconstructSoftEntitiesJointMap = true; if (!success && _skeletonModelURL != AvatarData::defaultFullAvatarModelUrl()) { const int MAX_SKELETON_DOWNLOAD_ATTEMPTS = 4; // NOTE: we don't want to be as generous as ResourceCache is, we only want 4 attempts diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 39081ba44b..3fe14f980f 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -330,6 +330,7 @@ protected: // protected methods... bool isLookingAtMe(AvatarSharedPointer avatar) const; + void relayJointDataToChildren(); void fade(render::Transaction& transaction, render::Transition::Type type); @@ -382,6 +383,7 @@ protected: bool _isAnimatingScale { false }; bool _mustFadeIn { false }; bool _isFading { false }; + bool _reconstructSoftEntitiesJointMap { false }; float _modelScale { 1.0f }; static int _jointConesID; diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index a13ef07cd4..1112ccde60 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -237,30 +237,14 @@ bool SkeletonModel::getRightHandPosition(glm::vec3& position) const { return getJointPositionInWorldFrame(getRightHandJointIndex(), position); } -bool SkeletonModel::restoreLeftHandPosition(float fraction, float priority) { - return restoreJointPosition(getLeftHandJointIndex(), fraction, priority); -} - bool SkeletonModel::getLeftShoulderPosition(glm::vec3& position) const { return getJointPositionInWorldFrame(getLastFreeJointIndex(getLeftHandJointIndex()), position); } -float SkeletonModel::getLeftArmLength() const { - return getLimbLength(getLeftHandJointIndex()); -} - -bool SkeletonModel::restoreRightHandPosition(float fraction, float priority) { - return restoreJointPosition(getRightHandJointIndex(), fraction, priority); -} - bool SkeletonModel::getRightShoulderPosition(glm::vec3& position) const { return getJointPositionInWorldFrame(getLastFreeJointIndex(getRightHandJointIndex()), position); } -float SkeletonModel::getRightArmLength() const { - return getLimbLength(getRightHandJointIndex()); -} - bool SkeletonModel::getHeadPosition(glm::vec3& headPosition) const { return isActive() && getJointPositionInWorldFrame(getFBXGeometry().headJointIndex, headPosition); } diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.h b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.h index f911ad0c5a..d82fce7412 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.h +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.h @@ -57,11 +57,6 @@ public: /// \return true whether or not the position was found bool getRightHandPosition(glm::vec3& position) const; - /// Restores some fraction of the default position of the left hand. - /// \param fraction the fraction of the default position to restore - /// \return whether or not the left hand joint was found - bool restoreLeftHandPosition(float fraction = 1.0f, float priority = 1.0f); - /// Gets the position of the left shoulder. /// \return whether or not the left shoulder joint was found bool getLeftShoulderPosition(glm::vec3& position) const; @@ -69,18 +64,10 @@ public: /// Returns the extended length from the left hand to its last free ancestor. float getLeftArmLength() const; - /// Restores some fraction of the default position of the right hand. - /// \param fraction the fraction of the default position to restore - /// \return whether or not the right hand joint was found - bool restoreRightHandPosition(float fraction = 1.0f, float priority = 1.0f); - /// Gets the position of the right shoulder. /// \return whether or not the right shoulder joint was found bool getRightShoulderPosition(glm::vec3& position) const; - /// Returns the extended length from the right hand to its first free ancestor. - float getRightArmLength() const; - /// Returns the position of the head joint. /// \return whether or not the head was found bool getHeadPosition(glm::vec3& headPosition) const; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index f2053e29d7..94df5bf7f4 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -530,9 +530,13 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent destinationBuffer += numValidityBytes; // Move pointer past the validity bytes + // sentJointDataOut and lastSentJointData might be the same vector + // build sentJointDataOut locally and then swap it at the end. + QVector localSentJointDataOut; if (sentJointDataOut) { - sentJointDataOut->resize(_jointData.size()); // Make sure the destination is resized before using it + localSentJointDataOut.resize(numJoints); // Make sure the destination is resized before using it } + float minRotationDOT = !distanceAdjust ? AVATAR_MIN_ROTATION_DOT : getDistanceBasedMinRotationDOT(viewerPosition); for (int i = 0; i < _jointData.size(); i++) { @@ -552,8 +556,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, data.rotation); if (sentJointDataOut) { - auto jointDataOut = *sentJointDataOut; - jointDataOut[i].rotation = data.rotation; + localSentJointDataOut[i].rotation = data.rotation; } } @@ -602,8 +605,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); if (sentJointDataOut) { - auto jointDataOut = *sentJointDataOut; - jointDataOut[i].translation = data.translation; + localSentJointDataOut[i].translation = data.translation; } } @@ -646,6 +648,11 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent if (outboundDataRateOut) { outboundDataRateOut->jointDataRate.increment(numBytes); } + + if (sentJointDataOut) { + // Push new sent joint data to sentJointDataOut + sentJointDataOut->swap(localSentJointDataOut); + } } int avatarDataSize = destinationBuffer - startPosition; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index d7dd2837cb..00cc760658 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -358,7 +358,7 @@ class AvatarData : public QObject, public SpatiallyNestable { Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged) // sessionDisplayName is sanitized, defaulted version displayName that is defined by the AvatarMixer rather than by Interface clients. // The result is unique among all avatars present at the time. - Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName WRITE setSessionDisplayName) + Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName WRITE setSessionDisplayName NOTIFY sessionDisplayNameChanged) Q_PROPERTY(bool lookAtSnappingEnabled MEMBER _lookAtSnappingEnabled NOTIFY lookAtSnappingChanged) Q_PROPERTY(QString skeletonModelURL READ getSkeletonModelURLFromScript WRITE setSkeletonModelURLFromScript) Q_PROPERTY(QVector attachmentData READ getAttachmentData WRITE setAttachmentData) @@ -685,6 +685,7 @@ public: signals: void displayNameChanged(); + void sessionDisplayNameChanged(); void lookAtSnappingChanged(bool enabled); void sessionUUIDChanged(); diff --git a/libraries/avatars/src/ScriptAvatarData.cpp b/libraries/avatars/src/ScriptAvatarData.cpp index 64cd534c8b..1fd001e536 100644 --- a/libraries/avatars/src/ScriptAvatarData.cpp +++ b/libraries/avatars/src/ScriptAvatarData.cpp @@ -15,6 +15,7 @@ ScriptAvatarData::ScriptAvatarData(AvatarSharedPointer avatarData) : _avatarData(avatarData) { QObject::connect(avatarData.get(), &AvatarData::displayNameChanged, this, &ScriptAvatarData::displayNameChanged); + QObject::connect(avatarData.get(), &AvatarData::sessionDisplayNameChanged, this, &ScriptAvatarData::sessionDisplayNameChanged); QObject::connect(avatarData.get(), &AvatarData::lookAtSnappingChanged, this, &ScriptAvatarData::lookAtSnappingChanged); } diff --git a/libraries/avatars/src/ScriptAvatarData.h b/libraries/avatars/src/ScriptAvatarData.h index 46dfb5325f..68074b838d 100644 --- a/libraries/avatars/src/ScriptAvatarData.h +++ b/libraries/avatars/src/ScriptAvatarData.h @@ -44,7 +44,7 @@ class ScriptAvatarData : public QObject { // Q_PROPERTY(QUuid sessionUUID READ getSessionUUID) Q_PROPERTY(QString displayName READ getDisplayName NOTIFY displayNameChanged) - Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName) + Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName NOTIFY sessionDisplayNameChanged) Q_PROPERTY(bool isReplicated READ getIsReplicated) Q_PROPERTY(bool lookAtSnappingEnabled READ getLookAtSnappingEnabled NOTIFY lookAtSnappingChanged) @@ -131,6 +131,7 @@ public: signals: void displayNameChanged(); + void sessionDisplayNameChanged(); void lookAtSnappingChanged(bool enabled); public slots: diff --git a/libraries/baking/CMakeLists.txt b/libraries/baking/CMakeLists.txt index 66cf791776..ec7caf574b 100644 --- a/libraries/baking/CMakeLists.txt +++ b/libraries/baking/CMakeLists.txt @@ -1,7 +1,7 @@ set(TARGET_NAME baking) setup_hifi_library(Concurrent) -link_hifi_libraries(shared model networking ktx image fbx) +link_hifi_libraries(shared graphics networking ktx image fbx) include_hifi_library_headers(gpu) add_dependency_external_projects(draco) diff --git a/libraries/display-plugins/CMakeLists.txt b/libraries/display-plugins/CMakeLists.txt index 1fd855e6aa..1d9d42d579 100644 --- a/libraries/display-plugins/CMakeLists.txt +++ b/libraries/display-plugins/CMakeLists.txt @@ -5,7 +5,7 @@ link_hifi_libraries(shared plugins ui-plugins gl ui render-utils ${PLATFORM_GL_B include_hifi_library_headers(gpu) include_hifi_library_headers(model-networking) include_hifi_library_headers(networking) -include_hifi_library_headers(model) +include_hifi_library_headers(graphics) include_hifi_library_headers(fbx) include_hifi_library_headers(image) include_hifi_library_headers(ktx) diff --git a/libraries/entities-renderer/CMakeLists.txt b/libraries/entities-renderer/CMakeLists.txt index 19987197b8..ea75367e1e 100644 --- a/libraries/entities-renderer/CMakeLists.txt +++ b/libraries/entities-renderer/CMakeLists.txt @@ -1,7 +1,7 @@ set(TARGET_NAME entities-renderer) -AUTOSCRIBE_SHADER_LIB(gpu model procedural render render-utils) +AUTOSCRIBE_SHADER_LIB(gpu graphics procedural render render-utils) setup_hifi_library(Widgets Network Script) -link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils image ui pointers) +link_hifi_libraries(shared gpu procedural graphics model-networking script-engine render render-utils image ui pointers) include_hifi_library_headers(networking) include_hifi_library_headers(gl) include_hifi_library_headers(ktx) diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp index fc33ebc498..4ea293a3da 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp @@ -52,9 +52,9 @@ void LightEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint float exponent = entity->getExponent(); float cutoff = glm::radians(entity->getCutoff()); if (!entity->getIsSpotlight()) { - light->setType(model::Light::POINT); + light->setType(graphics::Light::POINT); } else { - light->setType(model::Light::SPOT); + light->setType(graphics::Light::SPOT); light->setSpotAngle(cutoff); light->setSpotExponent(exponent); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 86237e75a4..827507c3aa 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -558,10 +558,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { if (type == SHAPE_TYPE_STATIC_MESH) { // copy into triangleIndices triangleIndices.reserve((int32_t)((gpu::Size)(triangleIndices.size()) + indices.getNumElements())); - gpu::BufferView::Iterator partItr = parts.cbegin(); - while (partItr != parts.cend()) { + gpu::BufferView::Iterator partItr = parts.cbegin(); + while (partItr != parts.cend()) { auto numIndices = partItr->_numIndices; - if (partItr->_topology == model::Mesh::TRIANGLES) { + if (partItr->_topology == graphics::Mesh::TRIANGLES) { // TODO: assert rather than workaround after we start sanitizing FBXMesh higher up //assert(numIndices % TRIANGLE_STRIDE == 0); numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader @@ -572,7 +572,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { triangleIndices.push_back(*indexItr + meshIndexOffset); ++indexItr; } - } else if (partItr->_topology == model::Mesh::TRIANGLE_STRIP) { + } else if (partItr->_topology == graphics::Mesh::TRIANGLE_STRIP) { // TODO: resurrect assert after we start sanitizing FBXMesh higher up //assert(numIndices > 2); @@ -593,7 +593,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { // the rest use previous and next index uint32_t triangleCount = 1; while (indexItr != indexEnd) { - if ((*indexItr) != model::Mesh::PRIMITIVE_RESTART_INDEX) { + if ((*indexItr) != graphics::Mesh::PRIMITIVE_RESTART_INDEX) { if (triangleCount % 2 == 0) { // even triangles use first two indices in order triangleIndices.push_back(*(indexItr - 2) + meshIndexOffset); @@ -613,12 +613,12 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { } } else if (type == SHAPE_TYPE_SIMPLE_COMPOUND) { // for each mesh copy unique part indices, separated by special bogus (flag) index values - gpu::BufferView::Iterator partItr = parts.cbegin(); - while (partItr != parts.cend()) { + gpu::BufferView::Iterator partItr = parts.cbegin(); + while (partItr != parts.cend()) { // collect unique list of indices for this part std::set uniqueIndices; auto numIndices = partItr->_numIndices; - if (partItr->_topology == model::Mesh::TRIANGLES) { + if (partItr->_topology == graphics::Mesh::TRIANGLES) { // TODO: assert rather than workaround after we start sanitizing FBXMesh higher up //assert(numIndices% TRIANGLE_STRIDE == 0); numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader @@ -629,7 +629,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { uniqueIndices.insert(*indexItr); ++indexItr; } - } else if (partItr->_topology == model::Mesh::TRIANGLE_STRIP) { + } else if (partItr->_topology == graphics::Mesh::TRIANGLE_STRIP) { // TODO: resurrect assert after we start sanitizing FBXMesh higher up //assert(numIndices > TRIANGLE_STRIDE - 1); @@ -644,7 +644,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { // the rest use previous and next index uint32_t triangleCount = 1; while (indexItr != indexEnd) { - if ((*indexItr) != model::Mesh::PRIMITIVE_RESTART_INDEX) { + if ((*indexItr) != graphics::Mesh::PRIMITIVE_RESTART_INDEX) { if (triangleCount % 2 == 0) { // EVEN triangles use first two indices in order uniqueIndices.insert(*(indexItr - 2)); @@ -708,6 +708,26 @@ void RenderableModelEntityItem::setCollisionShape(const btCollisionShape* shape) } } +void RenderableModelEntityItem::setJointMap(std::vector jointMap) { + if (jointMap.size() > 0) { + _jointMap = jointMap; + _jointMapCompleted = true; + return; + } + + _jointMapCompleted = false; +}; + +int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) { + int result = -1; + int mapSize = (int) _jointMap.size(); + if (modelJointIndex >=0 && modelJointIndex < mapSize) { + result = _jointMap[modelJointIndex]; + } + + return result; +} + bool RenderableModelEntityItem::contains(const glm::vec3& point) const { auto model = getModel(); if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) { @@ -813,6 +833,10 @@ bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int ind return setLocalJointTranslation(index, jointRelativePose.trans()); } +bool RenderableModelEntityItem::getJointMapCompleted() { + return _jointMapCompleted; +} + glm::quat RenderableModelEntityItem::getLocalJointRotation(int index) const { auto model = getModel(); if (model) { @@ -835,6 +859,13 @@ glm::vec3 RenderableModelEntityItem::getLocalJointTranslation(int index) const { return glm::vec3(); } +void RenderableModelEntityItem::setOverrideTransform(const Transform& transform, const glm::vec3& offset) { + auto model = getModel(); + if (model) { + model->overrideModelTransformAndOffset(transform, offset); + } +} + bool RenderableModelEntityItem::setLocalJointRotation(int index, const glm::quat& rotation) { autoResizeJointArrays(); bool result = false; @@ -929,6 +960,26 @@ bool RenderableModelEntityItem::getMeshes(MeshProxyList& result) { return !result.isEmpty(); } +void RenderableModelEntityItem::simulateRelayedJoints() { + ModelPointer model = getModel(); + if (model && model->isLoaded()) { + copyAnimationJointDataToModel(); + model->simulate(0.0f); + model->updateRenderItems(); + } +} + +void RenderableModelEntityItem::stopModelOverrideIfNoParent() { + auto model = getModel(); + if (model) { + bool overriding = model->isOverridingModelTransformAndOffset(); + QUuid parentID = getParentID(); + if (overriding && (!_relayParentJoints || parentID.isNull())) { + model->stopTransformAndOffsetOverride(); + } + } +} + void RenderableModelEntityItem::copyAnimationJointDataToModel() { auto model = getModel(); if (!model || !model->isLoaded()) { @@ -1280,6 +1331,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } entity->updateModelBounds(); + entity->stopModelOverrideIfNoParent(); if (model->isVisible() != _visible) { // FIXME: this seems like it could be optimized if we tracked our last known visible state in @@ -1295,7 +1347,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce ShapeType type = entity->getShapeType(); if (DependencyManager::get()->shouldRenderDebugHulls() && type != SHAPE_TYPE_STATIC_MESH && type != SHAPE_TYPE_NONE) { // NOTE: it is OK if _collisionMeshKey is nullptr - model::MeshPointer mesh = collisionMeshCache.getMesh(_collisionMeshKey); + graphics::MeshPointer mesh = collisionMeshCache.getMesh(_collisionMeshKey); // NOTE: the model will render the collisionGeometry if it has one _model->setCollisionMesh(mesh); } else { @@ -1304,7 +1356,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce collisionMeshCache.releaseMesh(_collisionMeshKey); } // clear model's collision geometry - model::MeshPointer mesh = nullptr; + graphics::MeshPointer mesh = nullptr; _model->setCollisionMesh(mesh); } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 1f3c4af054..b3988e0239 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -81,8 +81,14 @@ public: void setCollisionShape(const btCollisionShape* shape) override; virtual bool contains(const glm::vec3& point) const override; + void stopModelOverrideIfNoParent(); virtual bool shouldBePhysical() const override; + void simulateRelayedJoints(); + bool getJointMapCompleted(); + void setJointMap(std::vector jointMap); + int avatarJointIndex(int modelJointIndex); + void setOverrideTransform(const Transform& transform, const glm::vec3& offset); // these are in the frame of this object (model space) virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; @@ -90,7 +96,6 @@ public: virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override; virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override; - virtual glm::quat getLocalJointRotation(int index) const override; virtual glm::vec3 getLocalJointTranslation(int index) const override; virtual bool setLocalJointRotation(int index, const glm::quat& rotation) override; @@ -119,7 +124,9 @@ private: void getCollisionGeometryResource(); GeometryResource::Pointer _compoundShapeResource; + bool _jointMapCompleted { false }; bool _originalTexturesRead { false }; + std::vector _jointMap; QVariantMap _originalTextures; bool _dimensionsInitialized { true }; bool _needsJointSimulation { false }; diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index ad0202457e..b4412e441f 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -65,7 +65,7 @@ #pragma warning(pop) #endif -#include "model/Geometry.h" +#include "graphics/Geometry.h" #include "StencilMaskPass.h" @@ -1060,7 +1060,7 @@ void RenderablePolyVoxEntityItem::recomputeMesh() { auto entity = std::static_pointer_cast(getThisPointer()); QtConcurrent::run([entity, voxelSurfaceStyle] { - model::MeshPointer mesh(new model::Mesh()); + graphics::MeshPointer mesh(new graphics::Mesh()); // A mesh object to hold the result of surface extraction PolyVox::SurfaceMesh polyVoxMesh; @@ -1122,18 +1122,18 @@ void RenderablePolyVoxEntityItem::recomputeMesh() { sizeof(PolyVox::PositionMaterialNormal), gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ))); - std::vector parts; - parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex - (model::Index)vecIndices.size(), // numIndices - (model::Index)0, // baseVertex - model::Mesh::TRIANGLES)); // topology - mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), + std::vector parts; + parts.emplace_back(graphics::Mesh::Part((graphics::Index)0, // startIndex + (graphics::Index)vecIndices.size(), // numIndices + (graphics::Index)0, // baseVertex + graphics::Mesh::TRIANGLES)); // topology + mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); entity->setMesh(mesh); }); } -void RenderablePolyVoxEntityItem::setMesh(model::MeshPointer mesh) { +void RenderablePolyVoxEntityItem::setMesh(graphics::MeshPointer mesh) { // this catches the payload from recomputeMesh bool neighborsNeedUpdate; withWriteLock([&] { @@ -1164,7 +1164,7 @@ void RenderablePolyVoxEntityItem::computeShapeInfoWorker() { PolyVoxSurfaceStyle voxelSurfaceStyle; glm::vec3 voxelVolumeSize; - model::MeshPointer mesh; + graphics::MeshPointer mesh; withReadLock([&] { voxelSurfaceStyle = _voxelSurfaceStyle; @@ -1582,7 +1582,7 @@ void PolyVoxEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& s void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { _lastVoxelToWorldMatrix = entity->voxelToWorldMatrix(); - model::MeshPointer newMesh; + graphics::MeshPointer newMesh; entity->withReadLock([&] { newMesh = entity->_mesh; }); diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 6ac518f79b..03c7351a59 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -21,8 +21,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -104,7 +104,7 @@ public: void forEachVoxelValue(const ivec3& voxelSize, std::function thunk); QByteArray volDataToArray(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize) const; - void setMesh(model::MeshPointer mesh); + void setMesh(graphics::MeshPointer mesh); void setCollisionPoints(ShapeInfo::PointCollection points, AABox box); PolyVox::SimpleVolume* getVolData() { return _volData.get(); } @@ -134,7 +134,7 @@ private: // may not match _voxelVolumeSize. bool _meshDirty { true }; // does collision-shape need to be recomputed? bool _meshReady{ false }; - model::MeshPointer _mesh; + graphics::MeshPointer _mesh; ShapeInfo _shapeInfo; @@ -178,7 +178,7 @@ private: bool _hasTransitioned{ false }; #endif - model::MeshPointer _mesh; + graphics::MeshPointer _mesh; std::array _xyzTextures; glm::vec3 _lastVoxelVolumeSize; glm::mat4 _lastVoxelToWorldMatrix; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 3ecce5ec38..b43944f26a 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -13,7 +13,7 @@ #include -#include +#include #include #include @@ -162,28 +162,31 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) { } if (_visible) { - // Finally, push the light visible in the frame + // Finally, push the lights visible in the frame + // + // If component is disabled then push component off state + // else if component is enabled then push current state + // (else mode is inherit, the value from the parent zone will be used + // if (_keyLightMode == COMPONENT_MODE_DISABLED) { _stage->_currentFrame.pushSunLight(_stage->getSunOffLight()); } else if (_keyLightMode == COMPONENT_MODE_ENABLED) { _stage->_currentFrame.pushSunLight(_sunIndex); } - // The background only if the mode is not inherit if (_skyboxMode == COMPONENT_MODE_DISABLED) { _backgroundStage->_currentFrame.pushBackground(INVALID_INDEX); } else if (_skyboxMode == COMPONENT_MODE_ENABLED) { _backgroundStage->_currentFrame.pushBackground(_backgroundIndex); } - // The ambient light only if it has a valid texture to render with if (_ambientLightMode == COMPONENT_MODE_DISABLED) { _stage->_currentFrame.pushAmbientLight(_stage->getAmbientOffLight()); } else if (_ambientLightMode == COMPONENT_MODE_ENABLED) { _stage->_currentFrame.pushAmbientLight(_ambientIndex); } - // Haze only if the mode is not inherit + // Haze only if the mode is not inherit, as the model deals with on/off if (_hazeMode != COMPONENT_MODE_INHERIT) { _hazeStage->_currentFrame.pushHaze(_hazeIndex); } @@ -319,7 +322,7 @@ void ZoneEntityRenderer::updateKeySunFromEntity(const TypedEntityPointer& entity setKeyLightMode((ComponentMode)entity->getKeyLightMode()); const auto& sunLight = editSunLight(); - sunLight->setType(model::Light::SUN); + sunLight->setType(graphics::Light::SUN); sunLight->setPosition(_lastPosition); sunLight->setOrientation(_lastRotation); @@ -333,7 +336,7 @@ void ZoneEntityRenderer::updateAmbientLightFromEntity(const TypedEntityPointer& setAmbientLightMode((ComponentMode)entity->getAmbientLightMode()); const auto& ambientLight = editAmbientLight(); - ambientLight->setType(model::Light::AMBIENT); + ambientLight->setType(graphics::Light::AMBIENT); ambientLight->setPosition(_lastPosition); ambientLight->setOrientation(_lastRotation); @@ -357,23 +360,23 @@ void ZoneEntityRenderer::updateHazeFromEntity(const TypedEntityPointer& entity) haze->setHazeActive(hazeMode == COMPONENT_MODE_ENABLED); haze->setAltitudeBased(_hazeProperties.getHazeAltitudeEffect()); - haze->setHazeRangeFactor(model::Haze::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeRange())); + haze->setHazeRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeRange())); xColor hazeColor = _hazeProperties.getHazeColor(); haze->setHazeColor(glm::vec3(hazeColor.red / 255.0, hazeColor.green / 255.0, hazeColor.blue / 255.0)); xColor hazeGlareColor = _hazeProperties.getHazeGlareColor(); haze->setHazeGlareColor(glm::vec3(hazeGlareColor.red / 255.0, hazeGlareColor.green / 255.0, hazeGlareColor.blue / 255.0)); haze->setHazeEnableGlare(_hazeProperties.getHazeEnableGlare()); - haze->setHazeGlareBlend(model::Haze::convertGlareAngleToPower(_hazeProperties.getHazeGlareAngle())); + haze->setHazeGlareBlend(graphics::Haze::convertGlareAngleToPower(_hazeProperties.getHazeGlareAngle())); float hazeAltitude = _hazeProperties.getHazeCeiling() - _hazeProperties.getHazeBaseRef(); - haze->setHazeAltitudeFactor(model::Haze::convertHazeAltitudeToHazeAltitudeFactor(hazeAltitude)); + haze->setHazeAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(hazeAltitude)); haze->setHazeBaseReference(_hazeProperties.getHazeBaseRef()); haze->setHazeBackgroundBlend(_hazeProperties.getHazeBackgroundBlend()); haze->setHazeAttenuateKeyLight(_hazeProperties.getHazeAttenuateKeyLight()); - haze->setHazeKeyLightRangeFactor(model::Haze::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeKeyLightRange())); - haze->setHazeKeyLightAltitudeFactor(model::Haze::convertHazeAltitudeToHazeAltitudeFactor(_hazeProperties.getHazeKeyLightAltitude())); + haze->setHazeKeyLightRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeKeyLightRange())); + haze->setHazeKeyLightAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(_hazeProperties.getHazeKeyLightAltitude())); haze->setZoneTransform(entity->getTransform().getMatrix()); } diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index 3174f00f4f..69f0663c06 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -13,9 +13,9 @@ #define hifi_RenderableZoneEntityItem_h #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -63,11 +63,11 @@ private: void setSkyboxColor(const glm::vec3& color); void setProceduralUserData(const QString& userData); - model::LightPointer editSunLight() { _needSunUpdate = true; return _sunLight; } - model::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; } - model::SunSkyStagePointer editBackground() { _needBackgroundUpdate = true; return _background; } - model::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); } - model::HazePointer editHaze() { _needHazeUpdate = true; return _haze; } + graphics::LightPointer editSunLight() { _needSunUpdate = true; return _sunLight; } + graphics::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; } + graphics::SunSkyStagePointer editBackground() { _needBackgroundUpdate = true; return _background; } + graphics::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); } + graphics::HazePointer editHaze() { _needHazeUpdate = true; return _haze; } bool _needsInitialSimulation{ true }; glm::vec3 _lastPosition; @@ -83,10 +83,10 @@ private: #endif LightStagePointer _stage; - const model::LightPointer _sunLight{ std::make_shared() }; - const model::LightPointer _ambientLight{ std::make_shared() }; - const model::SunSkyStagePointer _background{ std::make_shared() }; - const model::HazePointer _haze{ std::make_shared() }; + const graphics::LightPointer _sunLight{ std::make_shared() }; + const graphics::LightPointer _ambientLight{ std::make_shared() }; + const graphics::SunSkyStagePointer _background{ std::make_shared() }; + const graphics::HazePointer _haze{ std::make_shared() }; ComponentMode _keyLightMode { COMPONENT_MODE_INHERIT }; ComponentMode _ambientLightMode { COMPONENT_MODE_INHERIT }; diff --git a/libraries/entities-renderer/src/polyvox.slf b/libraries/entities-renderer/src/polyvox.slf index 56f6f31d71..50034db48c 100644 --- a/libraries/entities-renderer/src/polyvox.slf +++ b/libraries/entities-renderer/src/polyvox.slf @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include DeferredBufferWrite.slh@> in vec3 _normal; diff --git a/libraries/entities-renderer/src/polyvox_fade.slf b/libraries/entities-renderer/src/polyvox_fade.slf index 7af43be53f..4c179a15b6 100644 --- a/libraries/entities-renderer/src/polyvox_fade.slf +++ b/libraries/entities-renderer/src/polyvox_fade.slf @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include DeferredBufferWrite.slh@> <@include Fade.slh@> diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index c23740654e..d6d9058e44 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -1,4 +1,4 @@ set(TARGET_NAME entities) setup_hifi_library(Network Script) include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") -link_hifi_libraries(shared networking octree avatars model) +link_hifi_libraries(shared networking octree avatars graphics) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 8bfce7e2d2..a19ed14d4a 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -395,6 +395,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_SHAPE, shape); CHECK_PROPERTY_CHANGE(PROP_DPI, dpi); + CHECK_PROPERTY_CHANGE(PROP_RELAY_PARENT_JOINTS, relayParentJoints); changedProperties += _animation.getChangedProperties(); changedProperties += _keyLight.getChangedProperties(); @@ -527,6 +528,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS, jointRotations); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS, jointTranslations); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RELAY_PARENT_JOINTS, relayParentJoints); } if (_type == EntityTypes::Model || _type == EntityTypes::Zone || _type == EntityTypes::ParticleEffect) { @@ -755,6 +757,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusSpread, float, setRadiusSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusStart, float, setRadiusStart); COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusFinish, float, setRadiusFinish); + COPY_PROPERTY_FROM_QSCRIPTVALUE(relayParentJoints, bool, setRelayParentJoints); // Certifiable Properties COPY_PROPERTY_FROM_QSCRIPTVALUE(itemName, QString, setItemName); @@ -1163,6 +1166,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector); ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector); ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector); + ADD_PROPERTY_TO_MAP(PROP_RELAY_PARENT_JOINTS, RelayParentJoints, relayParentJoints, bool); ADD_PROPERTY_TO_MAP(PROP_SHAPE, Shape, shape, QString); @@ -1386,6 +1390,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, properties.getJointRotations()); APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, properties.getJointTranslationsSet()); APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, properties.getJointTranslations()); + APPEND_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, properties.getRelayParentJoints()); } if (properties.getType() == EntityTypes::Light) { @@ -1745,6 +1750,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS, QVector, setJointRotations); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS_SET, QVector, setJointTranslationsSet); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS, QVector, setJointTranslations); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RELAY_PARENT_JOINTS, bool, setRelayParentJoints); } if (properties.getType() == EntityTypes::Light) { @@ -2089,6 +2095,7 @@ void EntityItemProperties::markAllChanged() { _owningAvatarIDChanged = true; _dpiChanged = true; + _relayParentJointsChanged = true; } // The minimum bounding box for the entity. @@ -2455,6 +2462,9 @@ QList EntityItemProperties::listChangedProperties() { if (jointTranslationsChanged()) { out += "jointTranslations"; } + if (relayParentJointsChanged()) { + out += "relayParentJoints"; + } if (queryAACubeChanged()) { out += "queryAACube"; } diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index c3d04dc7ad..3e0770f386 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -255,6 +255,7 @@ public: DEFINE_PROPERTY_REF(PROP_LAST_EDITED_BY, LastEditedBy, lastEditedBy, QUuid, ENTITY_ITEM_DEFAULT_LAST_EDITED_BY); DEFINE_PROPERTY_REF(PROP_SERVER_SCRIPTS, ServerScripts, serverScripts, QString, ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS); + DEFINE_PROPERTY(PROP_RELAY_PARENT_JOINTS, RelayParentJoints, relayParentJoints, bool, ENTITY_ITEM_DEFAULT_RELAY_PARENT_JOINTS); static QString getComponentModeString(uint32_t mode); static QString getComponentModeAsString(uint32_t mode); diff --git a/libraries/entities/src/EntityItemPropertiesDefaults.h b/libraries/entities/src/EntityItemPropertiesDefaults.h index 49bce37fbd..eb09a64628 100644 --- a/libraries/entities/src/EntityItemPropertiesDefaults.h +++ b/libraries/entities/src/EntityItemPropertiesDefaults.h @@ -92,4 +92,6 @@ const uint16_t ENTITY_ITEM_DEFAULT_DPI = 30; const QUuid ENTITY_ITEM_DEFAULT_LAST_EDITED_BY = QUuid(); +const bool ENTITY_ITEM_DEFAULT_RELAY_PARENT_JOINTS = false; + #endif // hifi_EntityItemPropertiesDefaults_h diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 7fd72bf0ee..90438ab01c 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -40,6 +40,7 @@ enum EntityPropertyList { PROP_ANIMATION_FRAME_INDEX, PROP_ANIMATION_PLAYING, PROP_ANIMATION_ALLOW_TRANSLATION, + PROP_RELAY_PARENT_JOINTS, // these properties are supported by the EntityItem base class PROP_REGISTRATION_POINT, diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 907426c922..15fc3256bd 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2283,30 +2283,35 @@ bool EntityTree::readFromMap(QVariantMap& map) { properties.setOwningAvatarID(myNodeID); } - // Fix for older content not containing these fields in the zones + // Fix for older content not containing mode fields in the zones if (needsConversion && (properties.getType() == EntityTypes::EntityType::Zone)) { + // The legacy version had no keylight mode - this is set to on + properties.setKeyLightMode(COMPONENT_MODE_ENABLED); + // The ambient URL has been moved from "keyLight" to "ambientLight" if (entityMap.contains("keyLight")) { QVariantMap keyLightObject = entityMap["keyLight"].toMap(); properties.getAmbientLight().setAmbientURL(keyLightObject["ambientURL"].toString()); } + // Copy the skybox URL if the ambient URL is empty, as this is the legacy behaviour + // Use skybox value only if it is not empty, else set ambientMode to inherit (to use default URL) + properties.setAmbientLightMode(COMPONENT_MODE_ENABLED); + if (properties.getAmbientLight().getAmbientURL() == "") { + if (properties.getSkybox().getURL() != "") { + properties.getAmbientLight().setAmbientURL(properties.getSkybox().getURL()); + } else { + properties.setAmbientLightMode(COMPONENT_MODE_INHERIT); + } + } + // The background should be enabled if the mode is skybox // Note that if the values are default then they are not stored in the JSON file if (entityMap.contains("backgroundMode") && (entityMap["backgroundMode"].toString() == "skybox")) { properties.setSkyboxMode(COMPONENT_MODE_ENABLED); - - // Copy the skybox URL if the ambient URL is empty, as this is the legacy behaviour - if (properties.getAmbientLight().getAmbientURL() == "") { - properties.getAmbientLight().setAmbientURL(properties.getSkybox().getURL()); - } - } else { + } else { properties.setSkyboxMode(COMPONENT_MODE_INHERIT); } - - // The legacy version had no keylight/ambient modes - these are always on - properties.setKeyLightMode(COMPONENT_MODE_ENABLED); - properties.setAmbientLightMode(COMPONENT_MODE_ENABLED); } EntityItemPointer entity = addEntity(entityItemID, properties); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 3e6d19f430..8996665262 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -62,7 +62,7 @@ EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredP COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointRotations, getJointRotations); COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslationsSet, getJointTranslationsSet); COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslations, getJointTranslations); - + COPY_ENTITY_PROPERTY_TO_PROPERTIES(relayParentJoints, getRelayParentJoints); _animationProperties.getProperties(properties); return properties; } @@ -80,6 +80,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointRotations, setJointRotations); SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslationsSet, setJointTranslationsSet); SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslations, setJointTranslations); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(relayParentJoints, setRelayParentJoints); bool somethingChangedInAnimations = _animationProperties.setProperties(properties); @@ -115,6 +116,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL); READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL); READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); + READ_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, bool, setRelayParentJoints); int bytesFromAnimation; withWriteLock([&] { @@ -155,6 +157,7 @@ EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams& requestedProperties += PROP_JOINT_ROTATIONS; requestedProperties += PROP_JOINT_TRANSLATIONS_SET; requestedProperties += PROP_JOINT_TRANSLATIONS; + requestedProperties += PROP_RELAY_PARENT_JOINTS; return requestedProperties; } @@ -173,6 +176,7 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, getModelURL()); APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures()); + APPEND_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, getRelayParentJoints()); withReadLock([&] { _animationProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, @@ -267,9 +271,9 @@ void ModelEntityItem::updateFrameCount() { if (!getAnimationHold() && getAnimationIsPlaying()) { float deltaTime = (float)interval / (float)USECS_PER_SECOND; _currentFrame += (deltaTime * getAnimationFPS()); - if (_currentFrame > getAnimationLastFrame()) { - if (getAnimationLoop()) { - _currentFrame = getAnimationFirstFrame() + (int)(glm::floor(_currentFrame - getAnimationFirstFrame())) % (updatedFrameCount - 1); + if (_currentFrame > getAnimationLastFrame() + 1) { + if (getAnimationLoop() && getAnimationFirstFrame() != getAnimationLastFrame()) { + _currentFrame = getAnimationFirstFrame() + (int)(_currentFrame - getAnimationFirstFrame()) % updatedFrameCount; } else { _currentFrame = getAnimationLastFrame(); } @@ -586,6 +590,18 @@ QString ModelEntityItem::getModelURL() const { }); } +void ModelEntityItem::setRelayParentJoints(bool relayJoints) { + withWriteLock([&] { + _relayParentJoints = relayJoints; + }); +} + +bool ModelEntityItem::getRelayParentJoints() const { + return resultWithReadLock([&] { + return _relayParentJoints; + }); +} + QString ModelEntityItem::getCompoundShapeURL() const { return _compoundShapeURL.get(); } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 7fee022011..6169039f52 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -99,6 +99,9 @@ public: void setAnimationHold(bool hold); bool getAnimationHold() const; + void setRelayParentJoints(bool relayJoints); + bool getRelayParentJoints() const; + void setAnimationFirstFrame(float firstFrame); float getAnimationFirstFrame() const; @@ -157,6 +160,7 @@ protected: rgbColor _color; QString _modelURL; + bool _relayParentJoints; ThreadSafeValueCache _compoundShapeURL; diff --git a/libraries/fbx/CMakeLists.txt b/libraries/fbx/CMakeLists.txt index 683ddb52f7..e422af3629 100644 --- a/libraries/fbx/CMakeLists.txt +++ b/libraries/fbx/CMakeLists.txt @@ -1,7 +1,7 @@ set(TARGET_NAME fbx) setup_hifi_library() -link_hifi_libraries(shared model networking image) +link_hifi_libraries(shared graphics networking image) include_hifi_library_headers(gpu image) target_draco() diff --git a/libraries/fbx/src/FBX.h b/libraries/fbx/src/FBX.h index 50d40c35ac..e40b218344 100644 --- a/libraries/fbx/src/FBX.h +++ b/libraries/fbx/src/FBX.h @@ -25,8 +25,8 @@ #include #include -#include -#include +#include +#include static const QByteArray FBX_BINARY_PROLOG = "Kaydara FBX Binary "; static const int FBX_HEADER_BYTES_BEFORE_VERSION = 23; @@ -183,7 +183,7 @@ public: QString materialID; QString name; QString shadingModel; - model::MaterialPointer _material; + graphics::MaterialPointer _material; FBXTexture normalTexture; FBXTexture albedoTexture; @@ -238,7 +238,7 @@ public: unsigned int meshIndex; // the order the meshes appeared in the object file - model::MeshPointer _mesh; + graphics::MeshPointer _mesh; bool wasCompressed { false }; }; diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 659d6dfa1e..4bc5eb1b6d 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -72,7 +72,7 @@ Extents FBXGeometry::getUnscaledMeshExtents() const { return scaledExtents; } -// TODO: Move to model::Mesh when Sam's ready +// TODO: Move to graphics::Mesh when Sam's ready bool FBXGeometry::convexHullContains(const glm::vec3& point) const { if (!getUnscaledMeshExtents().containsPoint(point)) { return false; @@ -148,6 +148,59 @@ glm::vec3 parseVec3(const QString& string) { return value; } +enum RotationOrder { + OrderXYZ = 0, + OrderXZY, + OrderYZX, + OrderYXZ, + OrderZXY, + OrderZYX, + OrderSphericXYZ +}; + +bool haveReportedUnhandledRotationOrder = false; // Report error only once per FBX file. + +glm::vec3 convertRotationToXYZ(int rotationOrder, const glm::vec3& rotation) { + // Convert rotation with given rotation order to have order XYZ. + if (rotationOrder == OrderXYZ) { + return rotation; + } + + glm::quat xyzRotation; + + switch (rotationOrder) { + case OrderXZY: + xyzRotation = glm::quat(glm::radians(glm::vec3(0, rotation.y, 0))) + * (glm::quat(glm::radians(glm::vec3(0, 0, rotation.z))) * glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0)))); + break; + case OrderYZX: + xyzRotation = glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0))) + * (glm::quat(glm::radians(glm::vec3(0, 0, rotation.z))) * glm::quat(glm::radians(glm::vec3(0, rotation.y, 0)))); + break; + case OrderYXZ: + xyzRotation = glm::quat(glm::radians(glm::vec3(0, 0, rotation.z))) + * (glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0))) * glm::quat(glm::radians(glm::vec3(0, rotation.y, 0)))); + break; + case OrderZXY: + xyzRotation = glm::quat(glm::radians(glm::vec3(0, rotation.y, 0))) + * (glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0))) * glm::quat(glm::radians(glm::vec3(0, 0, rotation.z)))); + break; + case OrderZYX: + xyzRotation = glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0))) + * (glm::quat(glm::radians(glm::vec3(0, rotation.y, 0))) * glm::quat(glm::radians(glm::vec3(0, 0, rotation.z)))); + break; + default: + // FIXME: Handle OrderSphericXYZ. + if (!haveReportedUnhandledRotationOrder) { + qCDebug(modelformat) << "ERROR: Unhandled rotation order in FBX file:" << rotationOrder; + haveReportedUnhandledRotationOrder = true; + } + return rotation; + } + + return glm::degrees(safeEulerAngles(xyzRotation)); +} + QString processID(const QString& id) { // Blender (at least) prepends a type to the ID, so strip it out return id.mid(id.lastIndexOf(':') + 1); @@ -630,6 +683,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS glm::vec3 ambientColor; QString hifiGlobalNodeID; unsigned int meshIndex = 0; + haveReportedUnhandledRotationOrder = false; foreach (const FBXNode& child, node.children) { if (child.name == "FBXHeaderExtension") { @@ -731,6 +785,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS glm::vec3 translation; // NOTE: the euler angles as supplied by the FBX file are in degrees glm::vec3 rotationOffset; + int rotationOrder = OrderXYZ; // Default rotation order set in "Definitions" node is assumed to be XYZ. glm::vec3 preRotation, rotation, postRotation; glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f); glm::vec3 scalePivot, rotationPivot, scaleOffset; @@ -764,6 +819,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS index = 4; } if (properties) { + static const QVariant ROTATION_ORDER = QByteArray("RotationOrder"); static const QVariant GEOMETRIC_TRANSLATION = QByteArray("GeometricTranslation"); static const QVariant GEOMETRIC_ROTATION = QByteArray("GeometricRotation"); static const QVariant GEOMETRIC_SCALING = QByteArray("GeometricScaling"); @@ -790,6 +846,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS if (childProperty == LCL_TRANSLATION) { translation = getVec3(property.properties, index); + } else if (childProperty == ROTATION_ORDER) { + rotationOrder = property.properties.at(index).toInt(); + } else if (childProperty == ROTATION_OFFSET) { rotationOffset = getVec3(property.properties, index); @@ -797,13 +856,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS rotationPivot = getVec3(property.properties, index); } else if (childProperty == PRE_ROTATION) { - preRotation = getVec3(property.properties, index); + preRotation = convertRotationToXYZ(rotationOrder, getVec3(property.properties, index)); } else if (childProperty == LCL_ROTATION) { - rotation = getVec3(property.properties, index); + rotation = convertRotationToXYZ(rotationOrder, getVec3(property.properties, index)); } else if (childProperty == POST_ROTATION) { - postRotation = getVec3(property.properties, index); + postRotation = convertRotationToXYZ(rotationOrder, getVec3(property.properties, index)); } else if (childProperty == SCALING_PIVOT) { scalePivot = getVec3(property.properties, index); diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 34d63b098a..e446861627 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -27,8 +27,8 @@ #include #include -#include -#include +#include +#include class QIODevice; class FBXNode; diff --git a/libraries/fbx/src/FBXReader_Material.cpp b/libraries/fbx/src/FBXReader_Material.cpp index ef6496cd10..4aa3044934 100644 --- a/libraries/fbx/src/FBXReader_Material.cpp +++ b/libraries/fbx/src/FBXReader_Material.cpp @@ -279,7 +279,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) { } // Finally create the true material representation - material._material = std::make_shared(); + material._material = std::make_shared(); // Emissive color is the mix of emissiveColor with emissiveFactor auto emissive = material.emissiveColor * (isMaterialLambert ? 1.0f : material.emissiveFactor); // In lambert there is not emissiveFactor @@ -293,7 +293,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) { material._material->setRoughness(material.roughness); material._material->setMetallic(material.metallic); } else { - material._material->setRoughness(model::Material::shininessToRoughness(material.shininess)); + material._material->setRoughness(graphics::Material::shininessToRoughness(material.shininess)); float metallic = std::max(material.specularColor.x, std::max(material.specularColor.y, material.specularColor.z)); material._material->setMetallic(metallic); diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 309c421052..7299f0c71c 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -584,7 +584,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { } FBXMesh& fbxMesh = extractedMesh; - model::MeshPointer mesh(new model::Mesh()); + graphics::MeshPointer mesh(new graphics::Mesh()); // Grab the vertices in a buffer auto vb = std::make_shared(); @@ -603,7 +603,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { if (!blendShape.normals.empty() && blendShape.tangents.empty()) { // Fill with a dummy value to force tangents to be present if there are normals blendShape.tangents.reserve(blendShape.normals.size()); - std::fill_n(std::back_inserter(fbxMesh.tangents), blendShape.normals.size(), Vectors::UNIT_X); + std::fill_n(std::back_inserter(blendShape.tangents), blendShape.normals.size(), Vectors::UNIT_X); } } @@ -721,45 +721,45 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { if (normalsSize) { mesh->addAttribute(gpu::Stream::NORMAL, - model::BufferView(attribBuffer, normalsOffset, normalsAndTangentsSize, + graphics::BufferView(attribBuffer, normalsOffset, normalsAndTangentsSize, normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); mesh->addAttribute(gpu::Stream::TANGENT, - model::BufferView(attribBuffer, tangentsOffset, normalsAndTangentsSize, + graphics::BufferView(attribBuffer, tangentsOffset, normalsAndTangentsSize, normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); } if (colorsSize) { mesh->addAttribute(gpu::Stream::COLOR, - model::BufferView(attribBuffer, colorsOffset, colorsSize, FBX_COLOR_ELEMENT)); + graphics::BufferView(attribBuffer, colorsOffset, colorsSize, FBX_COLOR_ELEMENT)); } if (texCoordsSize) { mesh->addAttribute(gpu::Stream::TEXCOORD, - model::BufferView( attribBuffer, texCoordsOffset, texCoordsSize, + graphics::BufferView( attribBuffer, texCoordsOffset, texCoordsSize, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); } if (texCoords1Size) { mesh->addAttribute( gpu::Stream::TEXCOORD1, - model::BufferView(attribBuffer, texCoords1Offset, texCoords1Size, + graphics::BufferView(attribBuffer, texCoords1Offset, texCoords1Size, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); } else if (texCoordsSize) { mesh->addAttribute(gpu::Stream::TEXCOORD1, - model::BufferView(attribBuffer, texCoordsOffset, texCoordsSize, + graphics::BufferView(attribBuffer, texCoordsOffset, texCoordsSize, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); } if (clusterIndicesSize) { if (fbxMesh.clusters.size() < UINT8_MAX) { mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, - model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, + graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW))); } else { mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, - model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, + graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW))); } } if (clusterWeightsSize) { mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, - model::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize, + graphics::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize, gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW))); } @@ -780,12 +780,12 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { int indexNum = 0; int offset = 0; - std::vector< model::Mesh::Part > parts; + std::vector< graphics::Mesh::Part > parts; if (extractedMesh.parts.size() > 1) { indexNum = 0; } foreach(const FBXMeshPart& part, extractedMesh.parts) { - model::Mesh::Part modelPart(indexNum, 0, 0, model::Mesh::TRIANGLES); + graphics::Mesh::Part modelPart(indexNum, 0, 0, graphics::Mesh::TRIANGLES); if (part.quadTrianglesIndices.size()) { indexBuffer->setSubData(offset, @@ -813,7 +813,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { if (parts.size()) { auto pb = std::make_shared(); - pb->setData(parts.size() * sizeof(model::Mesh::Part), (const gpu::Byte*) parts.data()); + pb->setData(parts.size() * sizeof(graphics::Mesh::Part), (const gpu::Byte*) parts.data()); gpu::BufferView pbv(pb, gpu::Element(gpu::VEC4, gpu::UINT32, gpu::XYZW)); mesh->setPartBuffer(pbv); } else { @@ -821,7 +821,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { return; } - // model::Box box = + // graphics::Box box = mesh->evalPartBound(0); extractedMesh._mesh = mesh; diff --git a/libraries/fbx/src/GLTFReader.cpp b/libraries/fbx/src/GLTFReader.cpp index c8501688ac..0c04b3d733 100644 --- a/libraries/fbx/src/GLTFReader.cpp +++ b/libraries/fbx/src/GLTFReader.cpp @@ -748,7 +748,7 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) { QString& matid = materialIDs[i]; geometry.materials[matid] = FBXMaterial(); FBXMaterial& fbxMaterial = geometry.materials[matid]; - fbxMaterial._material = std::make_shared(); + fbxMaterial._material = std::make_shared(); setFBXMaterial(fbxMaterial, _file.materials[i]); } diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index 7fb916efde..ba93a49cb9 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -750,8 +750,8 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, objMaterial.opacity); FBXMaterial& fbxMaterial = geometry.materials[materialID]; fbxMaterial.materialID = materialID; - fbxMaterial._material = std::make_shared(); - model::MaterialPointer modelMaterial = fbxMaterial._material; + fbxMaterial._material = std::make_shared(); + graphics::MaterialPointer modelMaterial = fbxMaterial._material; if (!objMaterial.diffuseTextureFilename.isEmpty()) { fbxMaterial.albedoTexture.filename = objMaterial.diffuseTextureFilename; @@ -763,7 +763,7 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, modelMaterial->setEmissive(fbxMaterial.emissiveColor); modelMaterial->setAlbedo(fbxMaterial.diffuseColor); modelMaterial->setMetallic(glm::length(fbxMaterial.specularColor)); - modelMaterial->setRoughness(model::Material::shininessToRoughness(fbxMaterial.shininess)); + modelMaterial->setRoughness(graphics::Material::shininessToRoughness(fbxMaterial.shininess)); if (fbxMaterial.opacity <= 0.0f) { modelMaterial->setOpacity(1.0f); diff --git a/libraries/fbx/src/OBJWriter.cpp b/libraries/fbx/src/OBJWriter.cpp index e0d3d36b06..4441ae6649 100644 --- a/libraries/fbx/src/OBJWriter.cpp +++ b/libraries/fbx/src/OBJWriter.cpp @@ -11,7 +11,7 @@ #include #include -#include "model/Geometry.h" +#include "graphics/Geometry.h" #include "OBJWriter.h" #include "ModelFormatLogging.h" @@ -105,13 +105,13 @@ bool writeOBJToTextStream(QTextStream& out, QList meshes) { const gpu::BufferView& partBuffer = mesh->getPartBuffer(); const gpu::BufferView& indexBuffer = mesh->getIndexBuffer(); - model::Index partCount = (model::Index)mesh->getNumParts(); + graphics::Index partCount = (graphics::Index)mesh->getNumParts(); for (int partIndex = 0; partIndex < partCount; partIndex++) { - const model::Mesh::Part& part = partBuffer.get(partIndex); + const graphics::Mesh::Part& part = partBuffer.get(partIndex); out << "g part-" << nth++ << "\n"; - // model::Mesh::TRIANGLES + // graphics::Mesh::TRIANGLES // TODO -- handle other formats gpu::BufferView::Iterator indexItr = indexBuffer.cbegin(); indexItr += part._startIndex; diff --git a/libraries/fbx/src/OBJWriter.h b/libraries/fbx/src/OBJWriter.h index b6e20e1ae6..536e8cf837 100644 --- a/libraries/fbx/src/OBJWriter.h +++ b/libraries/fbx/src/OBJWriter.h @@ -15,9 +15,9 @@ #include #include -#include +#include -using MeshPointer = std::shared_ptr; +using MeshPointer = std::shared_ptr; bool writeOBJToTextStream(QTextStream& out, QList meshes); bool writeOBJToFile(QString path, QList meshes); diff --git a/libraries/model/CMakeLists.txt b/libraries/graphics/CMakeLists.txt similarity index 50% rename from libraries/model/CMakeLists.txt rename to libraries/graphics/CMakeLists.txt index da85b6aa3d..2b15604fdf 100755 --- a/libraries/model/CMakeLists.txt +++ b/libraries/graphics/CMakeLists.txt @@ -1,4 +1,4 @@ -set(TARGET_NAME model) -AUTOSCRIBE_SHADER_LIB(gpu model) +set(TARGET_NAME graphics) +AUTOSCRIBE_SHADER_LIB(gpu graphics) setup_hifi_library() link_hifi_libraries(shared ktx gpu image) \ No newline at end of file diff --git a/libraries/model/src/model/Asset.cpp b/libraries/graphics/src/graphics/Asset.cpp similarity index 83% rename from libraries/model/src/model/Asset.cpp rename to libraries/graphics/src/graphics/Asset.cpp index d839dad809..ef5f010b4e 100644 --- a/libraries/model/src/model/Asset.cpp +++ b/libraries/graphics/src/graphics/Asset.cpp @@ -1,6 +1,6 @@ // // Asset.cpp -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 08/21/2015. // Copyright 2015 High Fidelity, Inc. @@ -10,7 +10,7 @@ // #include "Asset.h" -using namespace model; +using namespace graphics; Asset::Asset() { } diff --git a/libraries/model/src/model/Asset.h b/libraries/graphics/src/graphics/Asset.h similarity index 97% rename from libraries/model/src/model/Asset.h rename to libraries/graphics/src/graphics/Asset.h index 51fc177538..86d98c1a69 100644 --- a/libraries/model/src/model/Asset.h +++ b/libraries/graphics/src/graphics/Asset.h @@ -1,6 +1,6 @@ // // Asset.h -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 08/21/2015. // Copyright 2015 High Fidelity, Inc. @@ -17,7 +17,7 @@ #include "Material.h" #include "Geometry.h" -namespace model { +namespace graphics { template class Table { diff --git a/libraries/model/src/model/Forward.h b/libraries/graphics/src/graphics/Forward.h similarity index 87% rename from libraries/model/src/model/Forward.h rename to libraries/graphics/src/graphics/Forward.h index 90f55fa64f..95d2d73099 100644 --- a/libraries/model/src/model/Forward.h +++ b/libraries/graphics/src/graphics/Forward.h @@ -1,6 +1,6 @@ // // Forward.h -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Bradley Austin Davis on 2017/06/21 // Copyright 2013-2017 High Fidelity, Inc. @@ -11,7 +11,7 @@ #ifndef hifi_model_Forward_h #define hifi_model_Forward_h -namespace model { +namespace graphics { class Mesh; using MeshPointer = std::shared_ptr; } diff --git a/libraries/model/src/model/Geometry.cpp b/libraries/graphics/src/graphics/Geometry.cpp similarity index 94% rename from libraries/model/src/model/Geometry.cpp rename to libraries/graphics/src/graphics/Geometry.cpp index 210b4ae8f3..ba5afcbc62 100755 --- a/libraries/model/src/model/Geometry.cpp +++ b/libraries/graphics/src/graphics/Geometry.cpp @@ -1,6 +1,6 @@ // // Geometry.cpp -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 12/5/2014. // Copyright 2014 High Fidelity, Inc. @@ -13,7 +13,7 @@ #include -using namespace model; +using namespace graphics; Mesh::Mesh() : _vertexBuffer(gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)), @@ -137,7 +137,7 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const { } -model::MeshPointer Mesh::map(std::function vertexFunc, +graphics::MeshPointer Mesh::map(std::function vertexFunc, std::function colorFunc, std::function normalFunc, std::function indexFunc) const { @@ -223,7 +223,7 @@ model::MeshPointer Mesh::map(std::function vertexFunc, indexDataCursor += sizeof(index); } - model::MeshPointer result(new model::Mesh()); + graphics::MeshPointer result(new graphics::Mesh()); gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ); gpu::Buffer* resultVertexBuffer = new gpu::Buffer(vertexSize, resultVertexData.get()); @@ -252,12 +252,12 @@ model::MeshPointer Mesh::map(std::function vertexFunc, // TODO -- shouldn't assume just one part - std::vector parts; - parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex - (model::Index)result->getNumIndices(), // numIndices - (model::Index)0, // baseVertex - model::Mesh::TRIANGLES)); // topology - result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), + std::vector parts; + parts.emplace_back(graphics::Mesh::Part((graphics::Index)0, // startIndex + (graphics::Index)result->getNumIndices(), // numIndices + (graphics::Index)0, // baseVertex + graphics::Mesh::TRIANGLES)); // topology + result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); return result; @@ -350,9 +350,9 @@ MeshPointer Mesh::createIndexedTriangles_P3F(uint32_t numVertices, uint32_t numI } - std::vector parts; - parts.push_back(model::Mesh::Part(0, numIndices, 0, model::Mesh::TRIANGLES)); - mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); + std::vector parts; + parts.push_back(graphics::Mesh::Part(0, numIndices, 0, graphics::Mesh::TRIANGLES)); + mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); return mesh; } diff --git a/libraries/model/src/model/Geometry.h b/libraries/graphics/src/graphics/Geometry.h similarity index 98% rename from libraries/model/src/model/Geometry.h rename to libraries/graphics/src/graphics/Geometry.h index 260de313ab..cd64a7c185 100755 --- a/libraries/model/src/model/Geometry.h +++ b/libraries/graphics/src/graphics/Geometry.h @@ -1,6 +1,6 @@ // // Geometry.h -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 12/5/2014. // Copyright 2014 High Fidelity, Inc. @@ -18,7 +18,7 @@ #include #include -namespace model { +namespace graphics { typedef gpu::BufferView::Index Index; typedef gpu::BufferView BufferView; typedef AABox Box; @@ -40,7 +40,7 @@ public: typedef gpu::Stream::Format VertexFormat; typedef std::map< Slot, BufferView > BufferViewMap; - typedef model::Vec3 Vec3; + typedef graphics::Vec3 Vec3; Mesh(); Mesh(const Mesh& mesh); diff --git a/libraries/model/src/model/ModelLogging.cpp b/libraries/graphics/src/graphics/GraphicsLogging.cpp similarity index 75% rename from libraries/model/src/model/ModelLogging.cpp rename to libraries/graphics/src/graphics/GraphicsLogging.cpp index 3b3fbed82c..9c46e89331 100644 --- a/libraries/model/src/model/ModelLogging.cpp +++ b/libraries/graphics/src/graphics/GraphicsLogging.cpp @@ -6,6 +6,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "ModelLogging.h" +#include "GraphicsLogging.h" -Q_LOGGING_CATEGORY(modelLog, "hifi.model") \ No newline at end of file +Q_LOGGING_CATEGORY(graphicsLog, "hifi.graphics") diff --git a/libraries/model/src/model/ModelLogging.h b/libraries/graphics/src/graphics/GraphicsLogging.h similarity index 81% rename from libraries/model/src/model/ModelLogging.h rename to libraries/graphics/src/graphics/GraphicsLogging.h index 33ed6fb059..29e3a7ffcd 100644 --- a/libraries/model/src/model/ModelLogging.h +++ b/libraries/graphics/src/graphics/GraphicsLogging.h @@ -1,5 +1,5 @@ // -// ModelLogging.h +// GraphicsLogging.h // hifi // // Created by Sam Gateau on 9/20/15. @@ -11,4 +11,4 @@ #include -Q_DECLARE_LOGGING_CATEGORY(modelLog) +Q_DECLARE_LOGGING_CATEGORY(graphicsLog) diff --git a/libraries/model/src/model/Haze.cpp b/libraries/graphics/src/graphics/Haze.cpp similarity index 99% rename from libraries/model/src/model/Haze.cpp rename to libraries/graphics/src/graphics/Haze.cpp index b56932e131..c788bc57db 100644 --- a/libraries/model/src/model/Haze.cpp +++ b/libraries/graphics/src/graphics/Haze.cpp @@ -1,6 +1,6 @@ // // Haze.cpp -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Nissim Hadar on 9/13/2017. // Copyright 2014 High Fidelity, Inc. @@ -12,7 +12,7 @@ #include #include "Haze.h" -using namespace model; +using namespace graphics; const float Haze::INITIAL_HAZE_RANGE{ 1000.0f }; const float Haze::INITIAL_HAZE_HEIGHT{ 200.0f }; diff --git a/libraries/model/src/model/Haze.h b/libraries/graphics/src/graphics/Haze.h similarity index 98% rename from libraries/model/src/model/Haze.h rename to libraries/graphics/src/graphics/Haze.h index 2a575eb151..608449a97e 100644 --- a/libraries/model/src/model/Haze.h +++ b/libraries/graphics/src/graphics/Haze.h @@ -1,6 +1,6 @@ // // MakeHaze.h -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Nissim Hadar on 9/13/2017. // Copyright 2014 High Fidelity, Inc. @@ -17,7 +17,7 @@ #include "Transform.h" #include "NumericalConstants.h" -namespace model { +namespace graphics { // Haze range is defined here as the range the visibility is reduced by 95% // Haze altitude is defined here as the altitude (above 0) that the haze is reduced by 95% diff --git a/libraries/model/src/model/Light.cpp b/libraries/graphics/src/graphics/Light.cpp similarity index 98% rename from libraries/model/src/model/Light.cpp rename to libraries/graphics/src/graphics/Light.cpp index 19da084f84..cb5209d4cf 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/graphics/src/graphics/Light.cpp @@ -1,6 +1,6 @@ // // Light.cpp -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 1/26/2014. // Copyright 2014 High Fidelity, Inc. @@ -10,7 +10,7 @@ // #include "Light.h" -using namespace model; +using namespace graphics; Light::Light() { updateLightRadius(); diff --git a/libraries/model/src/model/Light.h b/libraries/graphics/src/graphics/Light.h similarity index 99% rename from libraries/model/src/model/Light.h rename to libraries/graphics/src/graphics/Light.h index 4c82eb5d77..360e3f224e 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/graphics/src/graphics/Light.h @@ -1,6 +1,6 @@ // // Light.h -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 12/10/2014. // Copyright 2014 High Fidelity, Inc. @@ -19,7 +19,7 @@ #include "gpu/Resource.h" #include "gpu/Texture.h" -namespace model { +namespace graphics { typedef gpu::BufferView UniformBufferView; typedef gpu::TextureView TextureView; typedef glm::vec3 Vec3; diff --git a/libraries/model/src/model/Light.slh b/libraries/graphics/src/graphics/Light.slh similarity index 93% rename from libraries/model/src/model/Light.slh rename to libraries/graphics/src/graphics/Light.slh index 093a87adc8..6b24f89c3c 100644 --- a/libraries/model/src/model/Light.slh +++ b/libraries/graphics/src/graphics/Light.slh @@ -11,8 +11,8 @@ <@if not MODEL_LIGHT_SLH@> <@def MODEL_LIGHT_SLH@> -<@include model/LightVolume.shared.slh@> -<@include model/LightIrradiance.shared.slh@> +<@include graphics/LightVolume.shared.slh@> +<@include graphics/LightIrradiance.shared.slh@> // NOw lets define Light struct Light { @@ -30,7 +30,7 @@ float getLightIntensity(Light l) { return lightIrradiance_getIntensity(l.irradia vec3 getLightIrradiance(Light l) { return lightIrradiance_getIrradiance(l.irradiance); } // AMbient lighting needs extra info provided from a different Buffer -<@include model/SphericalHarmonics.shared.slh@> +<@include graphics/SphericalHarmonics.shared.slh@> // Light Ambient struct LightAmbient { vec4 _ambient; diff --git a/libraries/model/src/model/LightIrradiance.shared.slh b/libraries/graphics/src/graphics/LightIrradiance.shared.slh similarity index 100% rename from libraries/model/src/model/LightIrradiance.shared.slh rename to libraries/graphics/src/graphics/LightIrradiance.shared.slh diff --git a/libraries/model/src/model/LightVolume.shared.slh b/libraries/graphics/src/graphics/LightVolume.shared.slh similarity index 98% rename from libraries/model/src/model/LightVolume.shared.slh rename to libraries/graphics/src/graphics/LightVolume.shared.slh index a78667ed6c..3f0cb135f5 100644 --- a/libraries/model/src/model/LightVolume.shared.slh +++ b/libraries/graphics/src/graphics/LightVolume.shared.slh @@ -3,7 +3,7 @@ #define LightVolume_Shared_slh // Light.shared.slh -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 14/9/2016. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/model/src/model/Material.cpp b/libraries/graphics/src/graphics/Material.cpp similarity index 99% rename from libraries/model/src/model/Material.cpp rename to libraries/graphics/src/graphics/Material.cpp index 4e01c4b866..ea5bd331c9 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -1,6 +1,6 @@ // // Material.cpp -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 12/10/2014. // Copyright 2014 High Fidelity, Inc. @@ -12,7 +12,7 @@ #include "TextureMap.h" -using namespace model; +using namespace graphics; using namespace gpu; Material::Material() : diff --git a/libraries/model/src/model/Material.h b/libraries/graphics/src/graphics/Material.h similarity index 99% rename from libraries/model/src/model/Material.h rename to libraries/graphics/src/graphics/Material.h index 8851ef4ce9..cfbfaa61ea 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -1,6 +1,6 @@ // // Material.h -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 12/10/2014. // Copyright 2014 High Fidelity, Inc. @@ -20,7 +20,7 @@ #include -namespace model { +namespace graphics { class TextureMap; typedef std::shared_ptr< TextureMap > TextureMapPointer; diff --git a/libraries/model/src/model/Material.slh b/libraries/graphics/src/graphics/Material.slh similarity index 100% rename from libraries/model/src/model/Material.slh rename to libraries/graphics/src/graphics/Material.slh diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/graphics/src/graphics/Skybox.cpp similarity index 98% rename from libraries/model/src/model/Skybox.cpp rename to libraries/graphics/src/graphics/Skybox.cpp index fd3061afa5..6fb7226089 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/graphics/src/graphics/Skybox.cpp @@ -1,6 +1,6 @@ // // Skybox.cpp -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 5/4/2015. // Copyright 2015 High Fidelity, Inc. @@ -18,7 +18,7 @@ #include "skybox_vert.h" #include "skybox_frag.h" -using namespace model; +using namespace graphics; Skybox::Skybox() { Schema schema; diff --git a/libraries/model/src/model/Skybox.h b/libraries/graphics/src/graphics/Skybox.h similarity index 96% rename from libraries/model/src/model/Skybox.h rename to libraries/graphics/src/graphics/Skybox.h index 90896fd8c6..d06989a457 100755 --- a/libraries/model/src/model/Skybox.h +++ b/libraries/graphics/src/graphics/Skybox.h @@ -1,6 +1,6 @@ // // Skybox.h -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 5/4/2015. // Copyright 2015 High Fidelity, Inc. @@ -19,7 +19,7 @@ class ViewFrustum; namespace gpu { class Batch; } -namespace model { +namespace graphics { typedef glm::vec3 Color; diff --git a/libraries/model/src/model/SphericalHarmonics.shared.slh b/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh similarity index 97% rename from libraries/model/src/model/SphericalHarmonics.shared.slh rename to libraries/graphics/src/graphics/SphericalHarmonics.shared.slh index 664c9e52db..312824c5a3 100644 --- a/libraries/model/src/model/SphericalHarmonics.shared.slh +++ b/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh @@ -3,7 +3,7 @@ #define SphericalHarmonics_Shared_slh // SphericalHarmonics.shared.slh -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 14/9/2016. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/model/src/model/Stage.cpp b/libraries/graphics/src/graphics/Stage.cpp similarity index 99% rename from libraries/model/src/model/Stage.cpp rename to libraries/graphics/src/graphics/Stage.cpp index 5854162cfa..312ece6889 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/graphics/src/graphics/Stage.cpp @@ -1,6 +1,6 @@ // // Stage.cpp -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 2/24/2015. // Copyright 2014 High Fidelity, Inc. @@ -15,7 +15,7 @@ #include #include -using namespace model; +using namespace graphics; void EarthSunModel::updateAll() const { diff --git a/libraries/model/src/model/Stage.h b/libraries/graphics/src/graphics/Stage.h similarity index 99% rename from libraries/model/src/model/Stage.h rename to libraries/graphics/src/graphics/Stage.h index 5f48824568..55f6145ee0 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/graphics/src/graphics/Stage.h @@ -1,6 +1,6 @@ // // Stage.h -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 2/24/2015. // Copyright 2014 High Fidelity, Inc. @@ -16,7 +16,7 @@ #include "Light.h" #include "Skybox.h" -namespace model { +namespace graphics { typedef glm::dvec3 Vec3d; typedef glm::dvec4 Vec4d; diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/graphics/src/graphics/TextureMap.cpp similarity index 94% rename from libraries/model/src/model/TextureMap.cpp rename to libraries/graphics/src/graphics/TextureMap.cpp index b308dd72f8..e2f24d68ff 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/graphics/src/graphics/TextureMap.cpp @@ -1,6 +1,6 @@ // // TextureMap.cpp -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 5/6/2015. // Copyright 2014 High Fidelity, Inc. @@ -10,7 +10,7 @@ // #include "TextureMap.h" -using namespace model; +using namespace graphics; using namespace gpu; void TextureMap::setTextureSource(TextureSourcePointer& textureSource) { diff --git a/libraries/model/src/model/TextureMap.h b/libraries/graphics/src/graphics/TextureMap.h similarity index 95% rename from libraries/model/src/model/TextureMap.h rename to libraries/graphics/src/graphics/TextureMap.h index 1785d44730..1678d9df98 100755 --- a/libraries/model/src/model/TextureMap.h +++ b/libraries/graphics/src/graphics/TextureMap.h @@ -1,6 +1,6 @@ // // TextureMap.h -// libraries/model/src/model +// libraries/graphics/src/graphics // // Created by Sam Gateau on 5/6/2015. // Copyright 2014 High Fidelity, Inc. @@ -15,7 +15,7 @@ #include "Transform.h" -namespace model { +namespace graphics { class TextureMap { public: diff --git a/libraries/model/src/model/skybox.slf b/libraries/graphics/src/graphics/skybox.slf similarity index 100% rename from libraries/model/src/model/skybox.slf rename to libraries/graphics/src/graphics/skybox.slf diff --git a/libraries/model/src/model/skybox.slv b/libraries/graphics/src/graphics/skybox.slv similarity index 100% rename from libraries/model/src/model/skybox.slv rename to libraries/graphics/src/graphics/skybox.slv diff --git a/libraries/model-networking/CMakeLists.txt b/libraries/model-networking/CMakeLists.txt index db5563d7ea..696f4feb9a 100644 --- a/libraries/model-networking/CMakeLists.txt +++ b/libraries/model-networking/CMakeLists.txt @@ -1,4 +1,4 @@ set(TARGET_NAME model-networking) setup_hifi_library() -link_hifi_libraries(shared networking model fbx ktx image) +link_hifi_libraries(shared networking graphics fbx ktx image) include_hifi_library_headers(gpu) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 6a14e6d6b7..07f7283bfa 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -516,13 +516,13 @@ QUrl NetworkMaterial::getTextureUrl(const QUrl& baseUrl, const FBXTexture& textu } } -model::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture, +graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture, image::TextureUsage::Type type, MapChannel channel) { const auto url = getTextureUrl(baseUrl, fbxTexture); const auto texture = DependencyManager::get()->getTexture(url, type, fbxTexture.content, fbxTexture.maxNumPixels); _textures[channel] = Texture { fbxTexture.name, texture }; - auto map = std::make_shared(); + auto map = std::make_shared(); if (texture) { map->setTextureSource(texture->_textureSource); } @@ -531,18 +531,18 @@ model::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, c return map; } -model::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel) { +graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel) { const auto texture = DependencyManager::get()->getTexture(url, type); _textures[channel].texture = texture; - auto map = std::make_shared(); + auto map = std::make_shared(); map->setTextureSource(texture->_textureSource); return map; } NetworkMaterial::NetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl) : - model::Material(*material._material) + graphics::Material(*material._material) { _textures = Textures(MapChannel::NUM_MAP_CHANNELS); if (!material.albedoTexture.filename.isEmpty()) { diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index a122e03eb9..f650b3f2eb 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -15,8 +15,8 @@ #include #include -#include -#include +#include +#include #include "FBXReader.h" #include "TextureCache.h" @@ -38,7 +38,7 @@ public: Geometry(const Geometry& geometry); // Immutable over lifetime - using GeometryMeshes = std::vector>; + using GeometryMeshes = std::vector>; using GeometryMeshParts = std::vector>; // Mutable, but must retain structure of vector @@ -157,9 +157,9 @@ private: virtual ~ModelCache() = default; }; -class NetworkMaterial : public model::Material { +class NetworkMaterial : public graphics::Material { public: - using MapChannel = model::Material::MapChannel; + using MapChannel = graphics::Material::MapChannel; NetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl); @@ -185,9 +185,9 @@ protected: private: // Helpers for the ctors QUrl getTextureUrl(const QUrl& baseUrl, const FBXTexture& fbxTexture); - model::TextureMapPointer fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture, + graphics::TextureMapPointer fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture, image::TextureUsage::Type type, MapChannel channel); - model::TextureMapPointer fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel); + graphics::TextureMapPointer fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel); Transform _albedoTransform; Transform _lightmapTransform; diff --git a/libraries/model-networking/src/model-networking/SimpleMeshProxy.cpp b/libraries/model-networking/src/model-networking/SimpleMeshProxy.cpp index b44ea1ff56..741478789e 100644 --- a/libraries/model-networking/src/model-networking/SimpleMeshProxy.cpp +++ b/libraries/model-networking/src/model-networking/SimpleMeshProxy.cpp @@ -11,7 +11,7 @@ #include "SimpleMeshProxy.h" -#include +#include MeshPointer SimpleMeshProxy::getMeshPointer() const { return _mesh; diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index 5a96fcf5e6..742d003d02 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 21815e065a..e317f0f250 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -761,11 +762,21 @@ void AddressManager::refreshPreviousLookup() { } void AddressManager::copyAddress() { + if (QThread::currentThread() != qApp->thread()) { + QMetaObject::invokeMethod(this, "copyAddress"); + return; + } + // assume that the address is being copied because the user wants a shareable address QApplication::clipboard()->setText(currentShareableAddress().toString()); } void AddressManager::copyPath() { + if (QThread::currentThread() != qApp->thread()) { + QMetaObject::invokeMethod(this, "copyPath"); + return; + } + QApplication::clipboard()->setText(currentPath()); } diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index 2f3d896509..7302e0e997 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -31,6 +31,32 @@ const QString INDEX_PATH = "/"; const QString GET_PLACE = "/api/v1/places/%1"; +/**jsdoc + * The location API provides facilities related to your current location in the metaverse. + * + * @namespace location + * @property {Uuid} domainId - A UUID uniquely identifying the domain you're visiting. Is {@link Uuid|Uuid.NULL} if you're not + * connected to the domain. + * Read-only. + * @property {string} hostname - The name of the domain for your current metaverse address (e.g., "AvatarIsland", + * localhost, or an IP address). + * Read-only. + * @property {string} href - Your current metaverse address (e.g., "hifi://avatarisland/15,-10,26/0,0,0,1") + * regardless of whether or not you're connected to the domain. + * Read-only. + * @property {boolean} isConnected - true if you're connected to the domain in your current href + * metaverse address, otherwise false. + * Read-only. + * @property {string} pathname - The location and orientation in your current href metaverse address + * (e.g., "/15,-10,26/0,0,0,1"). + * Read-only. + * @property {string} placename - The place name in your current href metaverse address + * (e.g., "AvatarIsland"). Is blank if your hostname is an IP address. + * Read-only. + * @property {string} protocol - The protocol of your current href metaverse address (e.g., "hifi"). + * Read-only. + */ + class AddressManager : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY @@ -42,10 +68,77 @@ class AddressManager : public QObject, public Dependency { Q_PROPERTY(QString placename READ getPlaceName) Q_PROPERTY(QString domainId READ getDomainId) public: + + /**jsdoc + * Get Interface's protocol version. + * @function location.protocolVersion + * @returns {string} A string uniquely identifying the version of the metaverse protocol that Interface is using. + */ Q_INVOKABLE QString protocolVersion(); + using PositionGetter = std::function; using OrientationGetter = std::function; + /**jsdoc + *

The reasons for an address lookup via the metaverse API are defined by numeric values:

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
NameValueDescription
UserInput0User-typed input.
Back1Address from a {@link location.goBack|goBack} call.
Forward2Address from a {@link location.goForward|goForward} call.
StartupFromSettings3Initial location at Interface start-up from settings.
DomainPathResponse4A named path in the domain.
Internal5An internal attempt to resolve an alternative path.
AttemptedRefresh6A refresh after connecting to a domain.
Suggestions7Address from the Goto dialog.
VisitUserFromPAL8User from the People dialog.
+ * @typedef location.LookupTrigger + */ enum LookupTrigger { UserInput, Back, @@ -83,43 +176,240 @@ public: const QStack& getForwardStack() const { return _forwardStack; } public slots: + /**jsdoc + * Go to a specified metaverse address. + * @function location.handleLookupString + * @param {string} address - The address to go to: a "hifi:/" address, an IP address (e.g., + * "127.0.0.1" or "localhost"), a domain name, a named path on a domain (starts with + * "/"), a position or position and orientation, or a user (starts with "@"). + * @param {boolean} fromSuggestions=false - Set to true if the address is obtained from the "Goto" dialog. + * Helps ensure that user's location history is correctly maintained. + */ void handleLookupString(const QString& lookupString, bool fromSuggestions = false); - + + /**jsdoc + * Go to a position and orientation resulting from a lookup for a named path in the domain (set in the domain server's + * settings). + * @function location.goToViewpointForPath + * @param {string} path - The position and orientation corresponding to the named path. + * @param {string} namedPath - The named path that was looked up on the server. + * @deprecated This function is deprecated and will be removed. + */ + // This function is marked as deprecated in anticipation that it will not be included in the JavaScript API if and when the + // functions and signals that should be exposed are moved to a scripting interface class. + // // we currently expect this to be called from NodeList once handleLookupString has been called with a path bool goToViewpointForPath(const QString& viewpointString, const QString& pathString) { return handleViewpoint(viewpointString, false, DomainPathResponse, false, pathString); } + /**jsdoc + * Go back to the previous location in your navigation history, if there is one. + * @function location.goBack + */ void goBack(); + + /**jsdoc + * Go forward to the next location in your navigation history, if there is one. + * @function location.goForward + */ void goForward(); + + /**jsdoc + * Go to the local Sandbox server that's running on the same PC as Interface. + * @function location.goToLocalSandbox + * @param {string} path="" - The position and orientation to go to (e.g., "/0,0,0"). + * @param {location.LookupTrigger} trigger=StartupFromSettings - The reason for the function call. Helps ensure that user's + * location history is correctly maintained. + */ void goToLocalSandbox(QString path = "", LookupTrigger trigger = LookupTrigger::StartupFromSettings) { handleUrl(SANDBOX_HIFI_ADDRESS + path, trigger); } + + /**jsdoc + * Go to the default "welcome" metaverse address. + * @function location.goToEntry + * @param {location.LookupTrigger} trigger=StartupFromSettings - The reason for the function call. Helps ensure that user's + * location history is correctly maintained. + */ void goToEntry(LookupTrigger trigger = LookupTrigger::StartupFromSettings) { handleUrl(DEFAULT_HIFI_ADDRESS, trigger); } + /**jsdoc + * Go to the specified user's location. + * @function location.goToUser + * @param {string} username - The user's username. + * @param {boolean} matchOrientation=true - If true then go to a location just in front of the user and turn to face + * them, otherwise go to the user's exact location and orientation. + */ void goToUser(const QString& username, bool shouldMatchOrientation = true); + /**jsdoc + * Refresh the current address, e.g., after connecting to a domain in order to position the user to the desired location. + * @function location.refreshPreviousLookup + * @deprecated This function is deprecated and will be removed. + */ + // This function is marked as deprecated in anticipation that it will not be included in the JavaScript API if and when the + // functions and signals that should be exposed are moved to a scripting interface class. void refreshPreviousLookup(); + /**jsdoc + * Update your current metaverse location in Interface's {@link Settings} file as your last-known address. This can be used + * to ensure that you start up at that address if you exit Interface without a later address automatically being saved. + * @function location.storeCurrentAddress + */ void storeCurrentAddress(); + /**jsdoc + * Copy your current metaverse address (i.e., location.href property value) to the OS clipboard. + * @function location.copyAddress + */ void copyAddress(); + + /**jsdoc + * Copy your current metaverse location and orientation (i.e., location.pathname property value) to the OS + * clipboard. + * @function location.copyPath + */ void copyPath(); + /**jsdoc + * Retrieve and remember the place name for the given domain ID if the place name is not already known. + * @function location.lookupShareableNameForDomainID + * @param {Uuid} domainID - The UUID of the domain. + * @deprecated This function is deprecated and will be removed. + */ + // This function is marked as deprecated in anticipation that it will not be included in the JavaScript API if and when the + // functions and signals that should be exposed are moved to a scripting interface class. void lookupShareableNameForDomainID(const QUuid& domainID); signals: + /**jsdoc + * Triggered when looking up the details of a metaverse user or location to go to has completed (successfully or + * unsuccessfully). + * @function location.lookupResultsFinished + * @returns {Signal} + */ void lookupResultsFinished(); + + /**jsdoc + * Triggered when looking up the details of a metaverse user or location to go to has completed and the domain or user is + * offline. + * @function location.lookupResultIsOffline + * @returns {Signal} + */ void lookupResultIsOffline(); + + /**jsdoc + * Triggered when looking up the details of a metaverse user or location to go to has completed and the domain or user could + * not be found. + * @function location.lookupResultIsNotFound + * @returns {Signal} + */ void lookupResultIsNotFound(); + /**jsdoc + * Triggered when a request is made to go to an IP address. + * @function location.possibleDomainChangeRequired + * @param {string} hostName - The name of the domain to go do. + * @param {number} port - The integer number of the network port to connect to. + * @param {Uuid} domainID - The UUID of the domain to go to. + * @returns {Signal} + */ + // No example because this function isn't typically used in scripts. void possibleDomainChangeRequired(const QString& newHostname, quint16 newPort, const QUuid& domainID); + + /**jsdoc + * Triggered when a request is made to go to a named domain or user. + * @function location.possibleDomainChangeRequiredViaICEForID + * @param {string} iceServerHostName - IP address of the ICE server. + * @param {Uuid} domainID - The UUID of the domain to go to. + * @returns {Signal} + */ + // No example because this function isn't typically used in scripts. void possibleDomainChangeRequiredViaICEForID(const QString& iceServerHostname, const QUuid& domainID); + /**jsdoc + * Triggered when an attempt is made to send your avatar to a specified position on the current domain. For example, when + * you change domains or enter a position to go to in the "Goto" dialog. + * @function location.locationChangeRequired + * @param {Vec3} position - The position to go to. + * @param {boolean} hasOrientationChange - If true then a new orientation has been requested. + * @param {Quat} orientation - The orientation to change to. Is {@link Quat(0)|Quat.IDENTITY} if + * hasOrientationChange is false. + * @param {boolean} shouldFaceLocation - If true then the request is to go to a position near that specified + * and orient your avatar to face it. For example when you visit someone from the "People" dialog. + * @returns {Signal} + * @example Report location change requests. + * function onLocationChangeRequired(newPosition, hasOrientationChange, newOrientation, shouldFaceLocation) { + * print("Location change required:"); + * print("- New position = " + JSON.stringify(newPosition)); + * print("- Has orientation change = " + hasOrientationChange); + * print("- New orientation = " + JSON.stringify(newOrientation)); + * print("- Should face location = " + shouldFaceLocation); + * } + * + * location.locationChangeRequired.connect(onLocationChangeRequired); + */ void locationChangeRequired(const glm::vec3& newPosition, bool hasOrientationChange, const glm::quat& newOrientation, bool shouldFaceLocation); + + /**jsdoc + * Triggered when an attempt is made to send your avatar to a new named path on the domain (set in the domain server's + * settings). For example, when you enter a "/" followed by the path's name in the "GOTO" dialog. + * @function location.pathChangeRequired + * @param {string} path - The name of the path to go to. + * @returns {Signal} + * @example Report path change requests. + * function onPathChangeRequired(newPath) { + * print("onPathChangeRequired: newPath = " + newPath); + * } + * + * location.pathChangeRequired.connect(onPathChangeRequired); + */ void pathChangeRequired(const QString& newPath); + + /**jsdoc + * Triggered when you navigate to a new domain. + * @function location.hostChanged + * @param {string} hostname - The new domain's host name. + * @returns {Signal} + * @example Report when you navigate to a new domain. + * function onHostChanged(host) { + * print("Host changed to: " + host); + * } + * + * location.hostChanged.connect(onHostChanged); + */ void hostChanged(const QString& newHost); + /**jsdoc + * Triggered when there's a change in whether or not there's a previous location that can be navigated to using + * {@link location.goBack|goBack}. (Reflects changes in the state of the "Goto" dialog's back arrow.) + * @function location.goBackPossible + * @param {boolean} isPossible - true if there's a previous location to navigate to, otherwise + * false. + * @returns {Signal} + * @example Report when ability to navigate back changes. + * function onGoBackPossible(isPossible) { + * print("Go back possible: " + isPossible); + * } + * + * location.goBackPossible.connect(onGoBackPossible); + */ void goBackPossible(bool isPossible); + + /**jsdoc + * Triggered when there's a change in whether or not there's a forward location that can be navigated to using + * {@link location.goForward|goForward}. (Reflects changes in the state of the "Goto" dialog's forward arrow.) + * @function location.goForwardPossible + * @param {boolean} isPossible - true if there's a forward location to navigate to, otherwise + * false. + * @returns {Signal} + * @example Report when ability to navigate forward changes. + * function onGoForwardPossible(isPossible) { + * print("Go forward possible: " + isPossible); + * } + * + * location.goForwardPossible.connect(onGoForwardPossible); + */ void goForwardPossible(bool isPossible); protected: diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 5a72006a8c..1c18125433 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -437,7 +437,7 @@ void NodeList::sendPendingDSPathQuery() { QString pendingPath = _domainHandler.getPendingPath(); if (!pendingPath.isEmpty()) { - qCDebug(networking) << "Attemping to send pending query to DS for path" << pendingPath; + qCDebug(networking) << "Attempting to send pending query to DS for path" << pendingPath; // this is a slot triggered if we just established a network link with a DS and want to send a path query sendDSPathQuery(_domainHandler.getPendingPath()); diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index db670c0a88..711aeb2cc2 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -30,7 +30,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityEdit: case PacketType::EntityData: case PacketType::EntityPhysics: - return static_cast(EntityVersion::ZoneStageRemoved); + return static_cast(EntityVersion::SoftEntities); case PacketType::EntityQuery: return static_cast(EntityQueryPacketVersion::RemovedJurisdictions); diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index acc1ff01db..458666571c 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -205,7 +205,8 @@ enum class EntityVersion : PacketVersion { StaticCertJsonVersionOne, OwnershipChallengeFix, ZoneLightInheritModes = 82, - ZoneStageRemoved + ZoneStageRemoved, + SoftEntities }; enum class EntityScriptCallMethodVersion : PacketVersion { diff --git a/libraries/physics/CMakeLists.txt b/libraries/physics/CMakeLists.txt index e219d3dbcd..ad082c1a6e 100644 --- a/libraries/physics/CMakeLists.txt +++ b/libraries/physics/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME physics) setup_hifi_library() -link_hifi_libraries(shared fbx entities model) +link_hifi_libraries(shared fbx entities graphics) include_hifi_library_headers(networking) include_hifi_library_headers(gpu) include_hifi_library_headers(avatars) diff --git a/libraries/physics/src/CollisionRenderMeshCache.cpp b/libraries/physics/src/CollisionRenderMeshCache.cpp index 40a8a4aff9..6f66b9af10 100644 --- a/libraries/physics/src/CollisionRenderMeshCache.cpp +++ b/libraries/physics/src/CollisionRenderMeshCache.cpp @@ -21,7 +21,7 @@ const int32_t MAX_HULL_INDICES = 6 * MAX_HULL_POINTS; const int32_t MAX_HULL_NORMALS = MAX_HULL_INDICES; float tempVertices[MAX_HULL_NORMALS]; -model::Index tempIndexBuffer[MAX_HULL_INDICES]; +graphics::Index tempIndexBuffer[MAX_HULL_INDICES]; bool copyShapeToMesh(const btTransform& transform, const btConvexShape* shape, gpu::BufferView& vertices, gpu::BufferView& indices, gpu::BufferView& parts, @@ -40,21 +40,21 @@ bool copyShapeToMesh(const btTransform& transform, const btConvexShape* shape, assert(numHullVertices <= MAX_HULL_POINTS); { // new part - model::Mesh::Part part; - part._startIndex = (model::Index)indices.getNumElements(); - part._numIndices = (model::Index)numHullIndices; + graphics::Mesh::Part part; + part._startIndex = (graphics::Index)indices.getNumElements(); + part._numIndices = (graphics::Index)numHullIndices; // FIXME: the render code cannot handle the case where part._baseVertex != 0 //part._baseVertex = vertices.getNumElements(); // DOES NOT WORK part._baseVertex = 0; - gpu::BufferView::Size numBytes = sizeof(model::Mesh::Part); + gpu::BufferView::Size numBytes = sizeof(graphics::Mesh::Part); const gpu::Byte* data = reinterpret_cast(&part); parts._buffer->append(numBytes, data); parts._size = parts._buffer->getSize(); } const int32_t SIZE_OF_VEC3 = 3 * sizeof(float); - model::Index indexOffset = (model::Index)vertices.getNumElements(); + graphics::Index indexOffset = (graphics::Index)vertices.getNumElements(); { // new indices const uint32_t* hullIndices = hull.getIndexPointer(); @@ -64,7 +64,7 @@ bool copyShapeToMesh(const btTransform& transform, const btConvexShape* shape, tempIndexBuffer[i] = hullIndices[i] + indexOffset; } const gpu::Byte* data = reinterpret_cast(tempIndexBuffer); - gpu::BufferView::Size numBytes = (gpu::BufferView::Size)(sizeof(model::Index) * numHullIndices); + gpu::BufferView::Size numBytes = (gpu::BufferView::Size)(sizeof(graphics::Index) * numHullIndices); indices._buffer->append(numBytes, data); indices._size = indices._buffer->getSize(); } @@ -105,8 +105,8 @@ bool copyShapeToMesh(const btTransform& transform, const btConvexShape* shape, return true; } -model::MeshPointer createMeshFromShape(const void* pointer) { - model::MeshPointer mesh; +graphics::MeshPointer createMeshFromShape(const void* pointer) { + graphics::MeshPointer mesh; if (!pointer) { return mesh; } @@ -147,7 +147,7 @@ model::MeshPointer createMeshFromShape(const void* pointer) { } } if (numSuccesses > 0) { - mesh = std::make_shared(); + mesh = std::make_shared(); mesh->setVertexBuffer(vertices); mesh->setIndexBuffer(indices); mesh->setPartBuffer(parts); @@ -167,8 +167,8 @@ CollisionRenderMeshCache::~CollisionRenderMeshCache() { _pendingGarbage.clear(); } -model::MeshPointer CollisionRenderMeshCache::getMesh(CollisionRenderMeshCache::Key key) { - model::MeshPointer mesh; +graphics::MeshPointer CollisionRenderMeshCache::getMesh(CollisionRenderMeshCache::Key key) { + graphics::MeshPointer mesh; if (key) { CollisionMeshMap::const_iterator itr = _meshMap.find(key); if (itr == _meshMap.end()) { diff --git a/libraries/physics/src/CollisionRenderMeshCache.h b/libraries/physics/src/CollisionRenderMeshCache.h index 10b2440db2..c5b643c0cc 100644 --- a/libraries/physics/src/CollisionRenderMeshCache.h +++ b/libraries/physics/src/CollisionRenderMeshCache.h @@ -16,7 +16,7 @@ #include #include -#include +#include class CollisionRenderMeshCache { @@ -27,7 +27,7 @@ public: ~CollisionRenderMeshCache(); /// \return pointer to geometry - model::MeshPointer getMesh(Key key); + graphics::MeshPointer getMesh(Key key); /// \return true if geometry was found and released bool releaseMesh(Key key); @@ -40,7 +40,7 @@ public: bool hasMesh(Key key) const { return _meshMap.find(key) == _meshMap.end(); } private: - using CollisionMeshMap = std::unordered_map; + using CollisionMeshMap = std::unordered_map; CollisionMeshMap _meshMap; std::vector _pendingGarbage; }; diff --git a/libraries/procedural/CMakeLists.txt b/libraries/procedural/CMakeLists.txt index daf6fefccc..9ec7cb6431 100644 --- a/libraries/procedural/CMakeLists.txt +++ b/libraries/procedural/CMakeLists.txt @@ -1,5 +1,5 @@ set(TARGET_NAME procedural) -AUTOSCRIBE_SHADER_LIB(gpu model) +AUTOSCRIBE_SHADER_LIB(gpu graphics) setup_hifi_library() -link_hifi_libraries(shared gpu networking model model-networking ktx image) +link_hifi_libraries(shared gpu networking graphics model-networking ktx image) diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index 9544759037..f0c60e2101 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -15,10 +15,10 @@ #include #include -#include -#include +#include +#include -ProceduralSkybox::ProceduralSkybox() : model::Skybox() { +ProceduralSkybox::ProceduralSkybox() : graphics::Skybox() { _procedural._vertexSource = skybox_vert; _procedural._fragmentSource = skybox_frag; // Adjust the pipeline state for background using the stencil test diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.h b/libraries/procedural/src/procedural/ProceduralSkybox.h index 5a1133a766..5db1078a5f 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.h +++ b/libraries/procedural/src/procedural/ProceduralSkybox.h @@ -13,11 +13,11 @@ #ifndef hifi_ProceduralSkybox_h #define hifi_ProceduralSkybox_h -#include +#include #include "Procedural.h" -class ProceduralSkybox: public model::Skybox { +class ProceduralSkybox: public graphics::Skybox { public: ProceduralSkybox(); diff --git a/libraries/render-utils/CMakeLists.txt b/libraries/render-utils/CMakeLists.txt index 94232c81b2..6be3057c93 100644 --- a/libraries/render-utils/CMakeLists.txt +++ b/libraries/render-utils/CMakeLists.txt @@ -1,9 +1,9 @@ set(TARGET_NAME render-utils) -AUTOSCRIBE_SHADER_LIB(gpu model render) +AUTOSCRIBE_SHADER_LIB(gpu graphics render) # pull in the resources.qrc file qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc") setup_hifi_library(Widgets OpenGL Network Qml Quick Script) -link_hifi_libraries(shared ktx gpu model model-networking render animation fbx image procedural) +link_hifi_libraries(shared ktx gpu graphics model-networking render animation fbx image procedural) include_hifi_library_headers(networking) include_hifi_library_headers(octree) include_hifi_library_headers(audio) diff --git a/libraries/render-utils/src/BackgroundStage.cpp b/libraries/render-utils/src/BackgroundStage.cpp index 2d2c0ed150..493c28d840 100644 --- a/libraries/render-utils/src/BackgroundStage.cpp +++ b/libraries/render-utils/src/BackgroundStage.cpp @@ -64,8 +64,8 @@ void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, auto backgroundStage = renderContext->_scene->getStage(); assert(backgroundStage); - model::SunSkyStagePointer background; - model::SkyboxPointer skybox; + graphics::SunSkyStagePointer background; + graphics::SkyboxPointer skybox; if (backgroundStage->_currentFrame._backgrounds.size()) { auto backgroundId = backgroundStage->_currentFrame._backgrounds.front(); auto background = backgroundStage->getBackground(backgroundId); @@ -76,7 +76,7 @@ void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, /* auto backgroundMode = skyStage->getBackgroundMode(); switch (backgroundMode) { - case model::SunSkyStage::SKY_DEFAULT: { + case graphics::SunSkyStage::SKY_DEFAULT: { auto scene = DependencyManager::get()->getStage(); auto sceneKeyLight = scene->getKeyLight(); @@ -88,7 +88,7 @@ void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, // fall through: render a skybox (if available), or the defaults (if requested) } - case model::SunSkyStage::SKY_BOX: {*/ + case graphics::SunSkyStage::SKY_BOX: {*/ if (skybox && !skybox->empty()) { PerformanceTimer perfTimer("skybox"); auto args = renderContext->args; @@ -118,7 +118,7 @@ void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, // fall through: render defaults (if requested) // } /* - case model::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE: { + case graphics::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE: { if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) { auto scene = DependencyManager::get()->getStage(); auto sceneKeyLight = scene->getKeyLight(); diff --git a/libraries/render-utils/src/BackgroundStage.h b/libraries/render-utils/src/BackgroundStage.h index 4e0e09db5b..db876b1993 100644 --- a/libraries/render-utils/src/BackgroundStage.h +++ b/libraries/render-utils/src/BackgroundStage.h @@ -11,7 +11,7 @@ #ifndef hifi_render_utils_BackgroundStage_h #define hifi_render_utils_BackgroundStage_h -#include +#include #include #include #include @@ -30,8 +30,8 @@ public: static const Index INVALID_INDEX; static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; } - using BackgroundPointer = model::SunSkyStagePointer; - using Backgrounds = render::indexed_container::IndexedPointerVector; + using BackgroundPointer = graphics::SunSkyStagePointer; + using Backgrounds = render::indexed_container::IndexedPointerVector; using BackgroundMap = std::unordered_map; using BackgroundIndices = std::vector; diff --git a/libraries/render-utils/src/DeferredBufferRead.slh b/libraries/render-utils/src/DeferredBufferRead.slh index fbca241bb9..3cbed3fcef 100644 --- a/libraries/render-utils/src/DeferredBufferRead.slh +++ b/libraries/render-utils/src/DeferredBufferRead.slh @@ -46,6 +46,15 @@ struct DeferredFragment { float depthVal; }; +<@if not GETFRESNEL0@> +<@def GETFRESNEL0@> +vec3 getFresnelF0(float metallic, vec3 metalF0) { + // Enable continuous metallness value by lerping between dielectric + // and metal fresnel F0 value based on the "metallic" parameter + return mix(vec3(0.03), metalF0, metallic); +} +<@endif@> + DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) { vec4 normalVal; vec4 diffuseVal; @@ -73,13 +82,7 @@ DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) { frag.scattering = specularVal.x; } - if (frag.metallic <= 0.5) { - frag.metallic = 0.0; - frag.fresnel = vec3(0.03); // Default Di-electric fresnel value - } else { - frag.fresnel = vec3(diffuseVal.xyz); - frag.metallic = 1.0; - } + frag.fresnel = getFresnelF0(frag.metallic, diffuseVal.xyz); return frag; } @@ -106,14 +109,7 @@ DeferredFragment unpackDeferredFragmentNoPositionNoAmbient(vec2 texcoord) { //frag.emissive = specularVal.xyz; frag.obscurance = 1.0; - - if (frag.metallic <= 0.5) { - frag.metallic = 0.0; - frag.fresnel = vec3(0.03); // Default Di-electric fresnel value - } else { - frag.fresnel = vec3(diffuseVal.xyz); - frag.metallic = 1.0; - } + frag.fresnel = getFresnelF0(frag.metallic, diffuseVal.xyz); return frag; } diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index de2d41be6b..2901b4796e 100644 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -11,7 +11,7 @@ <@if not DEFERRED_GLOBAL_LIGHT_SLH@> <@def DEFERRED_GLOBAL_LIGHT_SLH@> -<@include model/Light.slh@> +<@include graphics/Light.slh@> <@include LightingModel.slh@> <$declareLightBuffer()$> @@ -65,10 +65,12 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness <$prepareGlobalLight($supportScattering$)$> + SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir); + // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; - evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance + evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> ); @@ -79,7 +81,7 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness // Directional vec3 directionalDiffuse; vec3 directionalSpecular; - evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation + evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> ); @@ -110,10 +112,12 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu ) { <$prepareGlobalLight($supportScattering$)$> + SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir); + // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; - evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance + evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> @@ -123,7 +127,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu vec3 directionalDiffuse; vec3 directionalSpecular; - evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation + evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> @@ -174,19 +178,21 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) { <$prepareGlobalLight()$> + SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir); + color += emissive * isEmissiveEnabled(); // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; - evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); + evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance); color += ambientDiffuse; color += ambientSpecular / opacity; // Directional vec3 directionalDiffuse; vec3 directionalSpecular; - evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); + evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation); color += directionalDiffuse; color += directionalSpecular / opacity; @@ -199,19 +205,21 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze( { <$prepareGlobalLight()$> + SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir); + color += emissive * isEmissiveEnabled(); // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; - evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); + evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance); color += ambientDiffuse; color += ambientSpecular / opacity; // Directional vec3 directionalDiffuse; vec3 directionalSpecular; - evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); + evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation); color += directionalDiffuse; color += directionalSpecular / opacity; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 81a33f17e3..b4fc2fd32d 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -103,13 +103,13 @@ void DeferredLightingEffect::init() { void DeferredLightingEffect::setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) { PerformanceTimer perfTimer("DLE->setupBatch()"); - model::LightPointer keySunLight; + graphics::LightPointer keySunLight; auto lightStage = args->_scene->getStage(); if (lightStage) { keySunLight = lightStage->getCurrentKeyLight(); } - model::LightPointer keyAmbiLight; + graphics::LightPointer keyAmbiLight; if (lightStage) { keyAmbiLight = lightStage->getCurrentAmbientLight(); } @@ -229,9 +229,9 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo #include -model::MeshPointer DeferredLightingEffect::getPointLightMesh() { +graphics::MeshPointer DeferredLightingEffect::getPointLightMesh() { if (!_pointLightMesh) { - _pointLightMesh = std::make_shared(); + _pointLightMesh = std::make_shared(); // let's use a icosahedron auto solid = geometry::icosahedron(); @@ -256,19 +256,19 @@ model::MeshPointer DeferredLightingEffect::getPointLightMesh() { delete[] indexData; - std::vector parts; - parts.push_back(model::Mesh::Part(0, nbIndices, 0, model::Mesh::TRIANGLES)); - parts.push_back(model::Mesh::Part(0, nbIndices, 0, model::Mesh::LINE_STRIP)); // outline version + std::vector parts; + parts.push_back(graphics::Mesh::Part(0, nbIndices, 0, graphics::Mesh::TRIANGLES)); + parts.push_back(graphics::Mesh::Part(0, nbIndices, 0, graphics::Mesh::LINE_STRIP)); // outline version - _pointLightMesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); + _pointLightMesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); } return _pointLightMesh; } -model::MeshPointer DeferredLightingEffect::getSpotLightMesh() { +graphics::MeshPointer DeferredLightingEffect::getSpotLightMesh() { if (!_spotLightMesh) { - _spotLightMesh = std::make_shared(); + _spotLightMesh = std::make_shared(); int slices = 16; int rings = 3; @@ -353,12 +353,12 @@ model::MeshPointer DeferredLightingEffect::getSpotLightMesh() { delete[] indexData; - std::vector parts; - parts.push_back(model::Mesh::Part(0, indices, 0, model::Mesh::TRIANGLES)); - parts.push_back(model::Mesh::Part(0, indices, 0, model::Mesh::LINE_STRIP)); // outline version + std::vector parts; + parts.push_back(graphics::Mesh::Part(0, indices, 0, graphics::Mesh::TRIANGLES)); + parts.push_back(graphics::Mesh::Part(0, indices, 0, graphics::Mesh::LINE_STRIP)); // outline version - _spotLightMesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); + _spotLightMesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); } return _spotLightMesh; } @@ -439,7 +439,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, const DeferredFrameTransformPointer& frameTransform, const DeferredFramebufferPointer& deferredFramebuffer, const LightingModelPointer& lightingModel, - const model::HazePointer& haze, + const graphics::HazePointer& haze, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource) { @@ -513,7 +513,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto keyLight = lightAndShadow.first; - model::LightPointer keyAmbientLight; + graphics::LightPointer keyAmbientLight; if (lightStage && lightStage->_currentFrame._ambientLights.size()) { keyAmbientLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front()); } @@ -744,12 +744,12 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) { if (lightStage) { // Allocate a default global light directional and ambient - auto lp = std::make_shared(); - lp->setType(model::Light::SUN); + auto lp = std::make_shared(); + lp->setType(graphics::Light::SUN); lp->setDirection(glm::vec3(-1.0f)); lp->setColor(glm::vec3(1.0f)); lp->setIntensity(1.0f); - lp->setType(model::Light::SUN); + lp->setType(graphics::Light::SUN); lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset::OLD_TOWN_SQUARE); lp->setAmbientIntensity(0.5f); @@ -771,7 +771,7 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) { auto backgroundStage = renderContext->_scene->getStage(); if (backgroundStage) { - auto background = std::make_shared(); + auto background = std::make_shared(); background->setSkybox(_defaultSkybox); // capture deault background @@ -786,7 +786,7 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) { auto hazeStage = renderContext->_scene->getStage(); if (hazeStage) { - auto haze = std::make_shared(); + auto haze = std::make_shared(); _defaultHaze = haze; _defaultHazeID = hazeStage->addHaze(_defaultHaze); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 212d17db12..6d2c0a6819 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -17,8 +17,8 @@ #include #include -#include "model/Light.h" -#include "model/Geometry.h" +#include "graphics/Light.h" +#include "graphics/Geometry.h" #include @@ -61,10 +61,10 @@ private: bool _shadowMapEnabled{ false }; bool _ambientOcclusionEnabled{ false }; - model::MeshPointer _pointLightMesh; - model::MeshPointer getPointLightMesh(); - model::MeshPointer _spotLightMesh; - model::MeshPointer getSpotLightMesh(); + graphics::MeshPointer _pointLightMesh; + graphics::MeshPointer getPointLightMesh(); + graphics::MeshPointer _spotLightMesh; + graphics::MeshPointer getSpotLightMesh(); gpu::PipelinePointer _directionalSkyboxLight; gpu::PipelinePointer _directionalAmbientSphereLight; @@ -121,7 +121,7 @@ public: const DeferredFrameTransformPointer& frameTransform, const DeferredFramebufferPointer& deferredFramebuffer, const LightingModelPointer& lightingModel, - const model::HazePointer& haze, + const graphics::HazePointer& haze, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource); @@ -158,7 +158,7 @@ class RenderDeferred { public: using Inputs = render::VaryingSet8 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, - AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer, model::HazePointer>; + AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer, graphics::HazePointer>; using Config = RenderDeferredConfig; using JobModel = render::Job::ModelI; @@ -184,13 +184,13 @@ public: void run(const render::RenderContextPointer& renderContext); protected: - model::LightPointer _defaultLight; + graphics::LightPointer _defaultLight; LightStage::Index _defaultLightID{ LightStage::INVALID_INDEX }; - model::SunSkyStagePointer _defaultBackground; + graphics::SunSkyStagePointer _defaultBackground; BackgroundStage::Index _defaultBackgroundID{ BackgroundStage::INVALID_INDEX }; - model::HazePointer _defaultHaze{ nullptr }; + graphics::HazePointer _defaultHaze{ nullptr }; HazeStage::Index _defaultHazeID{ HazeStage::INVALID_INDEX }; - model::SkyboxPointer _defaultSkybox { new ProceduralSkybox() }; + graphics::SkyboxPointer _defaultSkybox { new ProceduralSkybox() }; gpu::TexturePointer _defaultSkyboxTexture; gpu::TexturePointer _defaultSkyboxAmbientTexture; }; diff --git a/libraries/render-utils/src/DrawHaze.cpp b/libraries/render-utils/src/DrawHaze.cpp index da07f5bd9b..64a106a09c 100644 --- a/libraries/render-utils/src/DrawHaze.cpp +++ b/libraries/render-utils/src/DrawHaze.cpp @@ -78,12 +78,12 @@ void HazeConfig::setHazeBackgroundBlend(const float value) { } MakeHaze::MakeHaze() { - _haze = std::make_shared(); + _haze = std::make_shared(); } void MakeHaze::configure(const Config& config) { _haze->setHazeColor(config.hazeColor); - _haze->setHazeGlareBlend(model::Haze::convertGlareAngleToPower(config.hazeGlareAngle)); + _haze->setHazeGlareBlend(graphics::Haze::convertGlareAngleToPower(config.hazeGlareAngle)); _haze->setHazeGlareColor(config.hazeGlareColor); _haze->setHazeBaseReference(config.hazeBaseReference); @@ -94,16 +94,16 @@ void MakeHaze::configure(const Config& config) { _haze->setModulateColorActive(config.isModulateColorActive); _haze->setHazeEnableGlare(config.isHazeEnableGlare); - _haze->setHazeRangeFactor(model::Haze::convertHazeRangeToHazeRangeFactor(config.hazeRange)); - _haze->setHazeAltitudeFactor(model::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight)); + _haze->setHazeRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeRange)); + _haze->setHazeAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight)); - _haze->setHazeKeyLightRangeFactor(model::Haze::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange)); - _haze->setHazeKeyLightAltitudeFactor(model::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude)); + _haze->setHazeKeyLightRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange)); + _haze->setHazeKeyLightAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude)); _haze->setHazeBackgroundBlend(config.hazeBackgroundBlend); } -void MakeHaze::run(const render::RenderContextPointer& renderContext, model::HazePointer& haze) { +void MakeHaze::run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze) { haze = _haze; } @@ -168,7 +168,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu auto hazeStage = args->_scene->getStage(); if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) { - model::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front()); + graphics::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front()); if (hazePointer) { batch.setUniformBuffer(HazeEffect_ParamsSlot, hazePointer->getHazeParametersBuffer()); } else { @@ -181,7 +181,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu auto lightStage = args->_scene->getStage(); if (lightStage) { - model::LightPointer keyLight; + graphics::LightPointer keyLight; keyLight = lightStage->getCurrentKeyLight(); if (keyLight) { batch.setUniformBuffer(HazeEffect_LightingMapSlot, keyLight->getLightSchemaBuffer()); diff --git a/libraries/render-utils/src/DrawHaze.h b/libraries/render-utils/src/DrawHaze.h index f158daa0c6..e7d4e15d77 100644 --- a/libraries/render-utils/src/DrawHaze.h +++ b/libraries/render-utils/src/DrawHaze.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include "SurfaceGeometryPass.h" @@ -51,11 +51,11 @@ class MakeHazeConfig : public render::Job::Config { public: MakeHazeConfig() : render::Job::Config() {} - glm::vec3 hazeColor{ model::Haze::INITIAL_HAZE_COLOR }; - float hazeGlareAngle{ model::Haze::INITIAL_HAZE_GLARE_ANGLE }; + glm::vec3 hazeColor{ graphics::Haze::INITIAL_HAZE_COLOR }; + float hazeGlareAngle{ graphics::Haze::INITIAL_HAZE_GLARE_ANGLE }; - glm::vec3 hazeGlareColor{ model::Haze::INITIAL_HAZE_GLARE_COLOR }; - float hazeBaseReference{ model::Haze::INITIAL_HAZE_BASE_REFERENCE }; + glm::vec3 hazeGlareColor{ graphics::Haze::INITIAL_HAZE_GLARE_COLOR }; + float hazeBaseReference{ graphics::Haze::INITIAL_HAZE_BASE_REFERENCE }; bool isHazeActive{ false }; bool isAltitudeBased{ false }; @@ -63,13 +63,13 @@ public: bool isModulateColorActive{ false }; bool isHazeEnableGlare{ false }; - float hazeRange{ model::Haze::INITIAL_HAZE_RANGE }; - float hazeHeight{ model::Haze::INITIAL_HAZE_HEIGHT }; + float hazeRange{ graphics::Haze::INITIAL_HAZE_RANGE }; + float hazeHeight{ graphics::Haze::INITIAL_HAZE_HEIGHT }; - float hazeKeyLightRange{ model::Haze::INITIAL_KEY_LIGHT_RANGE }; - float hazeKeyLightAltitude{ model::Haze::INITIAL_KEY_LIGHT_ALTITUDE }; + float hazeKeyLightRange{ graphics::Haze::INITIAL_KEY_LIGHT_RANGE }; + float hazeKeyLightAltitude{ graphics::Haze::INITIAL_KEY_LIGHT_ALTITUDE }; - float hazeBackgroundBlend{ model::Haze::INITIAL_HAZE_BACKGROUND_BLEND }; + float hazeBackgroundBlend{ graphics::Haze::INITIAL_HAZE_BACKGROUND_BLEND }; public slots: void setHazeColor(const glm::vec3 value) { hazeColor = value; emit dirty(); } @@ -99,15 +99,15 @@ signals: class MakeHaze { public: using Config = MakeHazeConfig; - using JobModel = render::Job::ModelO; + using JobModel = render::Job::ModelO; MakeHaze(); void configure(const Config& config); - void run(const render::RenderContextPointer& renderContext, model::HazePointer& haze); + void run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze); private: - model::HazePointer _haze; + graphics::HazePointer _haze; }; class HazeConfig : public render::Job::Config { @@ -115,11 +115,11 @@ public: HazeConfig() : render::Job::Config(true) {} // attributes - glm::vec3 hazeColor{ model::Haze::INITIAL_HAZE_COLOR }; - float hazeGlareAngle{ model::Haze::INITIAL_HAZE_GLARE_ANGLE }; + glm::vec3 hazeColor{ graphics::Haze::INITIAL_HAZE_COLOR }; + float hazeGlareAngle{ graphics::Haze::INITIAL_HAZE_GLARE_ANGLE }; - glm::vec3 hazeGlareColor{ model::Haze::INITIAL_HAZE_GLARE_COLOR }; - float hazeBaseReference{ model::Haze::INITIAL_HAZE_BASE_REFERENCE }; + glm::vec3 hazeGlareColor{ graphics::Haze::INITIAL_HAZE_GLARE_COLOR }; + float hazeBaseReference{ graphics::Haze::INITIAL_HAZE_BASE_REFERENCE }; bool isHazeActive{ false }; // Setting this to true will set haze to on bool isAltitudeBased{ false }; @@ -127,13 +127,13 @@ public: bool isModulateColorActive{ false }; bool isHazeEnableGlare{ false }; - float hazeRange{ model::Haze::INITIAL_HAZE_RANGE }; - float hazeHeight{ model::Haze::INITIAL_HAZE_HEIGHT }; + float hazeRange{ graphics::Haze::INITIAL_HAZE_RANGE }; + float hazeHeight{ graphics::Haze::INITIAL_HAZE_HEIGHT }; - float hazeKeyLightRange{ model::Haze::INITIAL_KEY_LIGHT_RANGE }; - float hazeKeyLightAltitude{ model::Haze::INITIAL_KEY_LIGHT_ALTITUDE }; + float hazeKeyLightRange{ graphics::Haze::INITIAL_KEY_LIGHT_RANGE }; + float hazeKeyLightAltitude{ graphics::Haze::INITIAL_KEY_LIGHT_ALTITUDE }; - float hazeBackgroundBlend{ model::Haze::INITIAL_HAZE_BACKGROUND_BLEND }; + float hazeBackgroundBlend{ graphics::Haze::INITIAL_HAZE_BACKGROUND_BLEND }; // methods void setHazeColor(const glm::vec3 value); @@ -159,7 +159,7 @@ public: class DrawHaze { public: - using Inputs = render::VaryingSet5; + using Inputs = render::VaryingSet5; using Config = HazeConfig; using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/ForwardGlobalLight.slh b/libraries/render-utils/src/ForwardGlobalLight.slh index aba0498ef5..e86f0c7fe3 100644 --- a/libraries/render-utils/src/ForwardGlobalLight.slh +++ b/libraries/render-utils/src/ForwardGlobalLight.slh @@ -11,7 +11,7 @@ <@if not DEFERRED_GLOBAL_LIGHT_SLH@> <@def DEFERRED_GLOBAL_LIGHT_SLH@> -<@include model/Light.slh@> +<@include graphics/Light.slh@> <@include LightingModel.slh@> <$declareLightBuffer()$> @@ -65,10 +65,12 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness <$prepareGlobalLight($supportScattering$)$> + SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir); + // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; - evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance + evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> ); @@ -79,7 +81,7 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness // Directional vec3 directionalDiffuse; vec3 directionalSpecular; - evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation + evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> ); @@ -109,10 +111,12 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu ) { <$prepareGlobalLight($supportScattering$)$> + SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir); + // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; - evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance + evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> @@ -124,7 +128,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu // Directional vec3 directionalDiffuse; vec3 directionalSpecular; - evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation + evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> @@ -173,19 +177,21 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) { <$prepareGlobalLight()$> + SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir); + color += emissive * isEmissiveEnabled(); // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; - evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); + evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance); color += ambientDiffuse; color += ambientSpecular / opacity; // Directional vec3 directionalDiffuse; vec3 directionalSpecular; - evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); + evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation); color += directionalDiffuse; color += directionalSpecular / opacity; diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 2616d08600..1fd6ca2980 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -31,7 +31,7 @@ #include "gpu/StandardShaderLib.h" -#include "model/TextureMap.h" +#include "graphics/TextureMap.h" #include "render/Args.h" #include "standardTransformPNTC_vert.h" diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 0585cc9e55..31aa4b10ea 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -28,8 +28,8 @@ #include -#include -#include +#include +#include class SimpleProgramKey; diff --git a/libraries/render-utils/src/Haze.slf b/libraries/render-utils/src/Haze.slf index 0270aa58f0..2d7daf1f98 100644 --- a/libraries/render-utils/src/Haze.slf +++ b/libraries/render-utils/src/Haze.slf @@ -12,7 +12,7 @@ <@include DeferredTransform.slh@> <$declareDeferredFrameTransform()$> -<@include model/Light.slh@> +<@include graphics/Light.slh@> <@include LightingModel.slh@> <$declareLightBuffer()$> diff --git a/libraries/render-utils/src/HazeStage.cpp b/libraries/render-utils/src/HazeStage.cpp index 016282d16f..e56b715b8c 100644 --- a/libraries/render-utils/src/HazeStage.cpp +++ b/libraries/render-utils/src/HazeStage.cpp @@ -17,12 +17,12 @@ std::string HazeStage::_stageName { "HAZE_STAGE"}; const HazeStage::Index HazeStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX }; FetchHazeStage::FetchHazeStage() { - _haze = std::make_shared(); + _haze = std::make_shared(); } void FetchHazeStage::configure(const Config& config) { _haze->setHazeColor(config.hazeColor); - _haze->setHazeGlareBlend(model::Haze::convertGlareAngleToPower(config.hazeGlareAngle)); + _haze->setHazeGlareBlend(graphics::Haze::convertGlareAngleToPower(config.hazeGlareAngle)); _haze->setHazeGlareColor(config.hazeGlareColor); _haze->setHazeBaseReference(config.hazeBaseReference); @@ -33,11 +33,11 @@ void FetchHazeStage::configure(const Config& config) { _haze->setModulateColorActive(config.isModulateColorActive); _haze->setHazeEnableGlare(config.isHazeEnableGlare); - _haze->setHazeRangeFactor(model::Haze::convertHazeRangeToHazeRangeFactor(config.hazeRange)); - _haze->setHazeAltitudeFactor(model::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight)); + _haze->setHazeRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeRange)); + _haze->setHazeAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight)); - _haze->setHazeKeyLightRangeFactor(model::Haze::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange)); - _haze->setHazeKeyLightAltitudeFactor(model::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude)); + _haze->setHazeKeyLightRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange)); + _haze->setHazeKeyLightAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude)); _haze->setHazeBackgroundBlend(config.hazeBackgroundBlend); } @@ -86,7 +86,7 @@ void HazeStageSetup::run(const render::RenderContextPointer& renderContext) { } } -void FetchHazeStage::run(const render::RenderContextPointer& renderContext, model::HazePointer& haze) { +void FetchHazeStage::run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze) { auto hazeStage = renderContext->_scene->getStage(); assert(hazeStage); diff --git a/libraries/render-utils/src/HazeStage.h b/libraries/render-utils/src/HazeStage.h index c355f06644..8f137cb280 100644 --- a/libraries/render-utils/src/HazeStage.h +++ b/libraries/render-utils/src/HazeStage.h @@ -11,7 +11,7 @@ #ifndef hifi_render_utils_HazeStage_h #define hifi_render_utils_HazeStage_h -#include +#include #include #include #include @@ -19,7 +19,7 @@ #include #include -#include +#include // Haze stage to set up haze-related rendering tasks class HazeStage : public render::Stage { @@ -31,8 +31,8 @@ public: static const Index INVALID_INDEX; static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; } - using HazePointer = model::HazePointer; - using Hazes = render::indexed_container::IndexedPointerVector; + using HazePointer = graphics::HazePointer; + using Hazes = render::indexed_container::IndexedPointerVector; using HazeMap = std::unordered_map; using HazeIndices = std::vector; @@ -106,11 +106,11 @@ class FetchHazeConfig : public render::Job::Config { public: FetchHazeConfig() : render::Job::Config() {} - glm::vec3 hazeColor{ model::Haze::INITIAL_HAZE_COLOR }; - float hazeGlareAngle{ model::Haze::INITIAL_HAZE_GLARE_ANGLE }; + glm::vec3 hazeColor{ graphics::Haze::INITIAL_HAZE_COLOR }; + float hazeGlareAngle{ graphics::Haze::INITIAL_HAZE_GLARE_ANGLE }; - glm::vec3 hazeGlareColor{ model::Haze::INITIAL_HAZE_GLARE_COLOR }; - float hazeBaseReference{ model::Haze::INITIAL_HAZE_BASE_REFERENCE }; + glm::vec3 hazeGlareColor{ graphics::Haze::INITIAL_HAZE_GLARE_COLOR }; + float hazeBaseReference{ graphics::Haze::INITIAL_HAZE_BASE_REFERENCE }; bool isHazeActive{ false }; bool isAltitudeBased{ false }; @@ -118,13 +118,13 @@ public: bool isModulateColorActive{ false }; bool isHazeEnableGlare{ false }; - float hazeRange{ model::Haze::INITIAL_HAZE_RANGE }; - float hazeHeight{ model::Haze::INITIAL_HAZE_HEIGHT }; + float hazeRange{ graphics::Haze::INITIAL_HAZE_RANGE }; + float hazeHeight{ graphics::Haze::INITIAL_HAZE_HEIGHT }; - float hazeKeyLightRange{ model::Haze::INITIAL_KEY_LIGHT_RANGE }; - float hazeKeyLightAltitude{ model::Haze::INITIAL_KEY_LIGHT_ALTITUDE }; + float hazeKeyLightRange{ graphics::Haze::INITIAL_KEY_LIGHT_RANGE }; + float hazeKeyLightAltitude{ graphics::Haze::INITIAL_KEY_LIGHT_ALTITUDE }; - float hazeBackgroundBlend{ model::Haze::INITIAL_HAZE_BACKGROUND_BLEND }; + float hazeBackgroundBlend{ graphics::Haze::INITIAL_HAZE_BACKGROUND_BLEND }; public slots: void setHazeColor(const glm::vec3 value) { hazeColor = value; emit dirty(); } @@ -154,15 +154,15 @@ signals: class FetchHazeStage { public: using Config = FetchHazeConfig; - using JobModel = render::Job::ModelO; + using JobModel = render::Job::ModelO; FetchHazeStage(); void configure(const Config& config); - void run(const render::RenderContextPointer& renderContext, model::HazePointer& haze); + void run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze); private: - model::HazePointer _haze; + graphics::HazePointer _haze; gpu::PipelinePointer _hazePipeline; }; #endif diff --git a/libraries/render-utils/src/LightAmbient.slh b/libraries/render-utils/src/LightAmbient.slh index 5f74b46d3e..eb565d60e4 100644 --- a/libraries/render-utils/src/LightAmbient.slh +++ b/libraries/render-utils/src/LightAmbient.slh @@ -16,22 +16,27 @@ uniform samplerCube skyboxMap; vec4 evalSkyboxLight(vec3 direction, float lod) { // textureQueryLevels is not available until #430, so we require explicit lod // float mipmapLevel = lod * textureQueryLevels(skyboxMap); + float filterLod = textureQueryLod(skyboxMap, direction).x; + // Keep texture filtering LOD as limit to prevent aliasing on specular reflection + lod = max(lod, filterLod); return textureLod(skyboxMap, direction, lod); } <@endfunc@> <@func declareEvalAmbientSpecularIrradiance(supportAmbientSphere, supportAmbientMap, supportIfAmbientMapElseAmbientSphere)@> -vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, float gloss) { - return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * pow(1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5.0); +vec3 fresnelSchlickAmbient(vec3 fresnelColor, float ndotd, float gloss) { + float f = pow(1.0 - ndotd, 5.0); + return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * f; +// return fresnelColor + (vec3(1.0) - fresnelColor) * f; } <@if supportAmbientMap@> <$declareSkyboxMap()$> <@endif@> -vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, vec3 fragEyeDir, vec3 fragNormal, float roughness) { - vec3 direction = -reflect(fragEyeDir, fragNormal); +vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, SurfaceData surface) { + vec3 lightDir = -reflect(surface.eyeDir, surface.normal); vec3 specularLight; <@if supportIfAmbientMapElseAmbientSphere@> if (getLightHasAmbientMap(ambient)) @@ -39,8 +44,10 @@ vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, vec3 fragEyeDir, vec3 f <@if supportAmbientMap@> { float levels = getLightAmbientMapNumMips(ambient); - float lod = min(((roughness)* levels), levels); - specularLight = evalSkyboxLight(direction, lod).xyz; + float m = 12.0 / (1.0+11.0*surface.roughness); + float lod = levels - m; + lod = max(lod, 0); + specularLight = evalSkyboxLight(lightDir, lod).xyz; } <@endif@> <@if supportIfAmbientMapElseAmbientSphere@> @@ -48,11 +55,11 @@ vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, vec3 fragEyeDir, vec3 f <@endif@> <@if supportAmbientSphere@> { - specularLight = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), direction).xyz; + specularLight = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), lightDir).xyz; } <@endif@> - return specularLight; + return specularLight; } <@endfunc@> @@ -66,21 +73,21 @@ float curvatureAO(in float k) { } <@endif@> -void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambient, vec3 eyeDir, vec3 normal, - float roughness, float metallic, vec3 fresnel, vec3 albedo, float obscurance +void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambient, SurfaceData surface, + float metallic, vec3 fresnelF0, vec3 albedo, float obscurance <@if supportScattering@> , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature <@endif@> ) { // Fresnel - vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, eyeDir, normal, 1.0 - roughness); + vec3 ambientFresnel = fresnelSchlickAmbient(fresnelF0, surface.ndotv, 1.0-surface.roughness); // Diffuse from ambient - diffuse = (1.0 - metallic) * (vec3(1.0) - ambientFresnel) * sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), normal).xyz; + diffuse = (1.0 - metallic) * (vec3(1.0) - ambientFresnel) * sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), surface.normal).xyz; // Specular highlight from ambient - specular = evalAmbientSpecularIrradiance(ambient, eyeDir, normal, roughness) * ambientFresnel; + specular = evalAmbientSpecularIrradiance(ambient, surface) * ambientFresnel; <@if supportScattering@> if (scattering * isScatteringEnabled() > 0.0) { @@ -92,7 +99,7 @@ void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambie // Diffuse from ambient diffuse = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), lowNormalCurvature.xyz).xyz; - + diffuse /= 3.1415926; specular = vec3(0.0); } <@endif@> @@ -107,8 +114,9 @@ void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambie diffuse *= albedo; } - diffuse *= lightEnergy * isDiffuseEnabled() * isAmbientEnabled(); - specular *= lightEnergy * isSpecularEnabled() * isAmbientEnabled(); + lightEnergy *= isAmbientEnabled(); + diffuse *= lightEnergy * isDiffuseEnabled(); + specular *= lightEnergy * isSpecularEnabled(); } <@endfunc@> diff --git a/libraries/render-utils/src/LightDirectional.slh b/libraries/render-utils/src/LightDirectional.slh index 749709c600..b6e1720a2c 100644 --- a/libraries/render-utils/src/LightDirectional.slh +++ b/libraries/render-utils/src/LightDirectional.slh @@ -12,7 +12,7 @@ <@func declareLightingDirectional(supportScattering)@> void evalLightingDirectional(out vec3 diffuse, out vec3 specular, vec3 lightDir, vec3 lightIrradiance, - vec3 eyeDir, vec3 normal, float roughness, + SurfaceData surface, float metallic, vec3 fresnel, vec3 albedo, float shadow <@if supportScattering@> , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature @@ -22,14 +22,17 @@ void evalLightingDirectional(out vec3 diffuse, out vec3 specular, vec3 lightDir, // Attenuation vec3 lightEnergy = shadow * lightIrradiance; - evalFragShading(diffuse, specular, normal, -lightDir, eyeDir, metallic, fresnel, roughness, albedo + updateSurfaceDataWithLight(surface, -lightDir); + + evalFragShading(diffuse, specular, metallic, fresnel, surface, albedo <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> ); - diffuse *= lightEnergy * isDiffuseEnabled() * isDirectionalEnabled(); - specular *= lightEnergy * isSpecularEnabled() * isDirectionalEnabled(); + lightEnergy *= isDirectionalEnabled(); + diffuse *= lightEnergy * isDiffuseEnabled(); + specular *= lightEnergy * isSpecularEnabled(); } <@endfunc@> diff --git a/libraries/render-utils/src/LightPayload.cpp b/libraries/render-utils/src/LightPayload.cpp index afa17bee19..09334faa13 100644 --- a/libraries/render-utils/src/LightPayload.cpp +++ b/libraries/render-utils/src/LightPayload.cpp @@ -40,7 +40,7 @@ namespace render { } LightPayload::LightPayload() : - _light(std::make_shared()) + _light(std::make_shared()) { } @@ -109,7 +109,7 @@ namespace render { } KeyLightPayload::KeyLightPayload() : -_light(std::make_shared()) +_light(std::make_shared()) { } diff --git a/libraries/render-utils/src/LightPayload.h b/libraries/render-utils/src/LightPayload.h index b55373c9a8..44b79ce10c 100644 --- a/libraries/render-utils/src/LightPayload.h +++ b/libraries/render-utils/src/LightPayload.h @@ -12,7 +12,7 @@ #define hifi_LightPayload_h -#include +#include #include #include "LightStage.h" #include "TextureCache.h" @@ -26,14 +26,14 @@ public: ~LightPayload(); void render(RenderArgs* args); - model::LightPointer editLight() { _needUpdate = true; return _light; } + graphics::LightPointer editLight() { _needUpdate = true; return _light; } render::Item::Bound& editBound() { _needUpdate = true; return _bound; } void setVisible(bool visible) { _isVisible = visible; } bool isVisible() const { return _isVisible; } protected: - model::LightPointer _light; + graphics::LightPointer _light; render::Item::Bound _bound; LightStagePointer _stage; LightStage::Index _index { LightStage::INVALID_INDEX }; @@ -56,7 +56,7 @@ public: ~KeyLightPayload(); void render(RenderArgs* args); - model::LightPointer editLight() { _needUpdate = true; return _light; } + graphics::LightPointer editLight() { _needUpdate = true; return _light; } render::Item::Bound& editBound() { _needUpdate = true; return _bound; } void setVisible(bool visible) { _isVisible = visible; } @@ -69,7 +69,7 @@ public: bool _pendingAmbientTexture { false }; protected: - model::LightPointer _light; + graphics::LightPointer _light; render::Item::Bound _bound; LightStagePointer _stage; LightStage::Index _index { LightStage::INVALID_INDEX }; diff --git a/libraries/render-utils/src/LightPoint.slh b/libraries/render-utils/src/LightPoint.slh index 7e389e11f6..91a1260fcc 100644 --- a/libraries/render-utils/src/LightPoint.slh +++ b/libraries/render-utils/src/LightPoint.slh @@ -12,7 +12,7 @@ <@func declareLightingPoint(supportScattering)@> void evalLightingPoint(out vec3 diffuse, out vec3 specular, Light light, - vec4 fragLightDirLen, vec3 fragEyeDir, vec3 normal, float roughness, + vec4 fragLightDirLen, SurfaceData surface, float metallic, vec3 fresnel, vec3 albedo, float shadow <@if supportScattering@> , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature @@ -23,19 +23,22 @@ void evalLightingPoint(out vec3 diffuse, out vec3 specular, Light light, float fragLightDistance = fragLightDirLen.w; vec3 fragLightDir = fragLightDirLen.xyz; + updateSurfaceDataWithLight(surface, fragLightDir); + // Eval attenuation float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); vec3 lightEnergy = radialAttenuation * shadow * getLightIrradiance(light); // Eval shading - evalFragShading(diffuse, specular, normal, fragLightDir, fragEyeDir, metallic, fresnel, roughness, albedo + evalFragShading(diffuse, specular, metallic, fresnel, surface, albedo <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> ); - diffuse *= lightEnergy * isDiffuseEnabled() * isPointEnabled(); - specular *= lightEnergy * isSpecularEnabled() * isPointEnabled(); + lightEnergy *= isPointEnabled(); + diffuse *= lightEnergy * isDiffuseEnabled(); + specular *= lightEnergy * isSpecularEnabled(); if (isShowLightContour() > 0.0) { // Show edge diff --git a/libraries/render-utils/src/LightSpot.slh b/libraries/render-utils/src/LightSpot.slh index 8627dae0eb..73c5bd9559 100644 --- a/libraries/render-utils/src/LightSpot.slh +++ b/libraries/render-utils/src/LightSpot.slh @@ -12,7 +12,7 @@ <@func declareLightingSpot(supportScattering)@> void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light, - vec4 fragLightDirLen, float cosSpotAngle, vec3 fragEyeDir, vec3 normal, float roughness, + vec4 fragLightDirLen, float cosSpotAngle, SurfaceData surface, float metallic, vec3 fresnel, vec3 albedo, float shadow <@if supportScattering@> , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature @@ -23,6 +23,7 @@ void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light, float fragLightDistance = fragLightDirLen.w; vec3 fragLightDir = fragLightDirLen.xyz; + updateSurfaceDataWithLight(surface, fragLightDir); // Eval attenuation float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); @@ -30,14 +31,15 @@ void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light, vec3 lightEnergy = angularAttenuation * radialAttenuation * shadow *getLightIrradiance(light); // Eval shading - evalFragShading(diffuse, specular, normal, fragLightDir, fragEyeDir, metallic, fresnel, roughness, albedo + evalFragShading(diffuse, specular, metallic, fresnel, surface, albedo <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> ); - diffuse *= lightEnergy * isDiffuseEnabled() * isSpotEnabled(); - specular *= lightEnergy * isSpecularEnabled() * isSpotEnabled(); + lightEnergy *= isSpotEnabled(); + diffuse *= lightEnergy * isDiffuseEnabled(); + specular *= lightEnergy * isSpecularEnabled(); if (isShowLightContour() > 0.0) { // Show edges diff --git a/libraries/render-utils/src/LightStage.cpp b/libraries/render-utils/src/LightStage.cpp index 42b161ba74..f146cd6e0a 100644 --- a/libraries/render-utils/src/LightStage.cpp +++ b/libraries/render-utils/src/LightStage.cpp @@ -29,32 +29,32 @@ const LightStage::Index LightStage::INVALID_INDEX { render::indexed_container::I LightStage::LightStage() { // Add off lights - const LightPointer ambientOffLight { std::make_shared() }; + const LightPointer ambientOffLight { std::make_shared() }; ambientOffLight->setAmbientIntensity(0.0f); - ambientOffLight->setColor(model::Vec3(0.0)); + ambientOffLight->setColor(graphics::Vec3(0.0)); ambientOffLight->setIntensity(0.0f); - ambientOffLight->setType(model::Light::Type::AMBIENT); + ambientOffLight->setType(graphics::Light::Type::AMBIENT); _ambientOffLightId = addLight(ambientOffLight); - const LightPointer pointOffLight { std::make_shared() }; + const LightPointer pointOffLight { std::make_shared() }; pointOffLight->setAmbientIntensity(0.0f); - pointOffLight->setColor(model::Vec3(0.0)); + pointOffLight->setColor(graphics::Vec3(0.0)); pointOffLight->setIntensity(0.0f); - pointOffLight->setType(model::Light::Type::POINT); + pointOffLight->setType(graphics::Light::Type::POINT); _pointOffLightId = addLight(pointOffLight); - const LightPointer spotOffLight { std::make_shared() }; + const LightPointer spotOffLight { std::make_shared() }; spotOffLight->setAmbientIntensity(0.0f); - spotOffLight->setColor(model::Vec3(0.0)); + spotOffLight->setColor(graphics::Vec3(0.0)); spotOffLight->setIntensity(0.0f); - spotOffLight->setType(model::Light::Type::SPOT); + spotOffLight->setType(graphics::Light::Type::SPOT); _spotOffLightId = addLight(spotOffLight); - const LightPointer sunOffLight { std::make_shared() }; + const LightPointer sunOffLight { std::make_shared() }; sunOffLight->setAmbientIntensity(0.0f); - sunOffLight->setColor(model::Vec3(0.0)); + sunOffLight->setColor(graphics::Vec3(0.0)); sunOffLight->setIntensity(0.0f); - sunOffLight->setType(model::Light::Type::SUN); + sunOffLight->setType(graphics::Light::Type::SUN); _sunOffLightId = addLight(sunOffLight); // Set default light to the off ambient light (until changed) @@ -123,7 +123,7 @@ float LightStage::Shadow::Cascade::computeFarDistance(const ViewFrustum& viewFru return far; } -LightStage::Shadow::Shadow(model::LightPointer light, float maxDistance, unsigned int cascadeCount) : +LightStage::Shadow::Shadow(graphics::LightPointer light, float maxDistance, unsigned int cascadeCount) : _light{ light } { cascadeCount = std::min(cascadeCount, (unsigned int)SHADOW_CASCADE_MAX_COUNT); Schema schema; @@ -404,14 +404,14 @@ LightStage::Index LightStage::getShadowId(Index lightId) const { } void LightStage::updateLightArrayBuffer(Index lightId) { - auto lightSize = sizeof(model::Light::LightSchema); + auto lightSize = sizeof(graphics::Light::LightSchema); if (!_lightArrayBuffer) { _lightArrayBuffer = std::make_shared(lightSize); } assert(checkLightId(lightId)); - if (lightId > (Index)_lightArrayBuffer->getNumTypedElements()) { + if (lightId > (Index)_lightArrayBuffer->getNumTypedElements()) { _lightArrayBuffer->resize(lightSize * (lightId + 10)); } @@ -419,7 +419,7 @@ void LightStage::updateLightArrayBuffer(Index lightId) { auto light = _lights._elements[lightId]; if (light) { const auto& lightSchema = light->getLightSchemaBuffer().get(); - _lightArrayBuffer->setSubData(lightId, lightSchema); + _lightArrayBuffer->setSubData(lightId, lightSchema); } else { // this should not happen ? } diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index 3dcae550f7..d1a8680706 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -17,7 +17,7 @@ #include -#include +#include #include #include @@ -35,8 +35,8 @@ public: static const Index INVALID_INDEX; static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; } - using LightPointer = model::LightPointer; - using Lights = render::indexed_container::IndexedPointerVector; + using LightPointer = graphics::LightPointer; + using Lights = render::indexed_container::IndexedPointerVector; using LightMap = std::unordered_map; using LightIndices = std::vector; @@ -75,7 +75,7 @@ public: float left, float right, float bottom, float top, float viewMaxShadowDistance) const; }; - Shadow(model::LightPointer light, float maxDistance, unsigned int cascadeCount = 1); + Shadow(graphics::LightPointer light, float maxDistance, unsigned int cascadeCount = 1); void setKeylightFrustum(const ViewFrustum& viewFrustum, float nearDepth = 1.0f, float farDepth = 1000.0f); @@ -91,7 +91,7 @@ public: float getMaxDistance() const { return _maxDistance; } void setMaxDistance(float value); - const model::LightPointer& getLight() const { return _light; } + const graphics::LightPointer& getLight() const { return _light; } protected: @@ -101,7 +101,7 @@ public: static const glm::mat4 _biasMatrix; - model::LightPointer _light; + graphics::LightPointer _light; float _maxDistance; Cascades _cascades; @@ -165,12 +165,12 @@ public: Frame() {} void clear() { _pointLights.clear(); _spotLights.clear(); _sunLights.clear(); _ambientLights.clear(); } - void pushLight(LightStage::Index index, model::Light::Type type) { + void pushLight(LightStage::Index index, graphics::Light::Type type) { switch (type) { - case model::Light::POINT: { pushPointLight(index); break; } - case model::Light::SPOT: { pushSpotLight(index); break; } - case model::Light::SUN: { pushSunLight(index); break; } - case model::Light::AMBIENT: { pushAmbientLight(index); break; } + case graphics::Light::POINT: { pushPointLight(index); break; } + case graphics::Light::SPOT: { pushSpotLight(index); break; } + case graphics::Light::SUN: { pushSunLight(index); break; } + case graphics::Light::AMBIENT: { pushAmbientLight(index); break; } default: { break; } } } diff --git a/libraries/render-utils/src/LightingModel.slh b/libraries/render-utils/src/LightingModel.slh index 521c4894dc..7d08fdabaf 100644 --- a/libraries/render-utils/src/LightingModel.slh +++ b/libraries/render-utils/src/LightingModel.slh @@ -77,6 +77,30 @@ float isWireframeEnabled() { <@endfunc@> <$declareLightingModel()$> +struct SurfaceData { + vec3 normal; + vec3 eyeDir; + vec3 lightDir; + vec3 halfDir; + float roughness; + float roughness2; + float roughness4; + float ndotv; + float ndotl; + float ndoth; + float ldoth; + float smithInvG1NdotV; +}; + +<@if not GETFRESNEL0@> +<@def GETFRESNEL0@> +vec3 getFresnelF0(float metallic, vec3 metalF0) { + // Enable continuous metallness value by lerping between dielectric + // and metal fresnel F0 value based on the "metallic" parameter + return mix(vec3(0.03), metalF0, metallic); +} +<@endif@> + <@func declareBeckmannSpecular()@> uniform sampler2D scatteringSpecularBeckmann; @@ -85,17 +109,13 @@ float fetchSpecularBeckmann(float ndoth, float roughness) { return pow(2.0 * texture(scatteringSpecularBeckmann, vec2(ndoth, roughness)).r, 10.0); } -vec2 skinSpecular(vec3 N, vec3 L, vec3 V, float roughness, float intensity) { +vec2 skinSpecular(SurfaceData surface, float intensity) { vec2 result = vec2(0.0, 1.0); - float ndotl = dot(N, L); - if (ndotl > 0.0) { - vec3 h = L + V; - vec3 H = normalize(h); - float ndoth = dot(N, H); - float PH = fetchSpecularBeckmann(ndoth, roughness); - float F = fresnelSchlickScalar(0.028, H, V); - float frSpec = max(PH * F / dot(h, h), 0.0); - result.x = ndotl * intensity * frSpec; + if (surface.ndotl > 0.0) { + float PH = fetchSpecularBeckmann(surface.ndoth, surface.roughness); + float F = fresnelSchlickScalar(0.028, surface); + float frSpec = max(PH * F / dot(surface.halfDir, surface.halfDir), 0.0); + result.x = surface.ndotl * intensity * frSpec; result.y -= F; } @@ -105,117 +125,136 @@ vec2 skinSpecular(vec3 N, vec3 L, vec3 V, float roughness, float intensity) { <@func declareEvalPBRShading()@> -vec3 fresnelSchlickColor(vec3 fresnelColor, vec3 lightDir, vec3 halfDir) { - float base = 1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0); +float evalSmithInvG1(float roughness4, float ndotd) { + return ndotd + sqrt(roughness4+ndotd*ndotd*(1.0-roughness4)); +} + +SurfaceData initSurfaceData(float roughness, vec3 normal, vec3 eyeDir) { + SurfaceData surface; + surface.eyeDir = eyeDir; + surface.normal = normal; + surface.roughness = mix(0.01, 1.0, roughness); + surface.roughness2 = surface.roughness * surface.roughness; + surface.roughness4 = surface.roughness2 * surface.roughness2; + surface.ndotv = clamp(dot(normal, eyeDir), 0.0, 1.0); + surface.smithInvG1NdotV = evalSmithInvG1(surface.roughness4, surface.ndotv); + + // These values will be set when we know the light direction, in updateSurfaceDataWithLight + surface.ndoth = 0.0; + surface.ndotl = 0.0; + surface.ldoth = 0.0; + surface.lightDir = vec3(0,0,1); + surface.halfDir = vec3(0,0,1); + + return surface; +} + +void updateSurfaceDataWithLight(inout SurfaceData surface, vec3 lightDir) { + surface.lightDir = lightDir; + surface.halfDir = normalize(surface.eyeDir + lightDir); + vec3 dots; + dots.x = dot(surface.normal, surface.halfDir); + dots.y = dot(surface.normal, surface.lightDir); + dots.z = dot(surface.halfDir, surface.lightDir); + dots = clamp(dots, vec3(0), vec3(1)); + surface.ndoth = dots.x; + surface.ndotl = dots.y; + surface.ldoth = dots.z; +} + +vec3 fresnelSchlickColor(vec3 fresnelColor, SurfaceData surface) { + float base = 1.0 - surface.ldoth; //float exponential = pow(base, 5.0); float base2 = base * base; float exponential = base * base2 * base2; return vec3(exponential) + fresnelColor * (1.0 - exponential); } -float fresnelSchlickScalar(float fresnelScalar, vec3 lightDir, vec3 halfDir) { - float base = 1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0); +float fresnelSchlickScalar(float fresnelScalar, SurfaceData surface) { + float base = 1.0 - surface.ldoth; //float exponential = pow(base, 5.0); float base2 = base * base; float exponential = base * base2 * base2; return (exponential) + fresnelScalar * (1.0 - exponential); } -float specularDistribution(float roughness, vec3 normal, vec3 halfDir) { - float ndoth = clamp(dot(halfDir, normal), 0.0, 1.0); -// float gloss2 = pow(0.001 + roughness, 4); - float gloss2 = (0.001 + roughness); - gloss2 *= gloss2; // pow 2 - gloss2 *= gloss2; // pow 4 - float denom = (ndoth * ndoth*(gloss2 - 1.0) + 1.0); - float power = gloss2 / (3.14159 * denom * denom); +float specularDistribution(SurfaceData surface) { + // See https://www.khronos.org/assets/uploads/developers/library/2017-web3d/glTF-2.0-Launch_Jun17.pdf + // for details of equations, especially page 20 + float denom = (surface.ndoth*surface.ndoth * (surface.roughness4 - 1.0) + 1.0); + denom *= denom; + // Add geometric factors G1(n,l) and G1(n,v) + float smithInvG1NdotL = evalSmithInvG1(surface.roughness4, surface.ndotl); + denom *= surface.smithInvG1NdotV * smithInvG1NdotL; + // Don't divide by PI as it will be done later + float power = surface.roughness4 / denom; return power; } -float specularDistributionGloss(float gloss2, vec3 normal, vec3 halfDir) { - float ndoth = clamp(dot(halfDir, normal), 0.0, 1.0); -// float gloss2 = pow(0.001 + roughness, 4); - float denom = (ndoth * ndoth*(gloss2 - 1.0) + 1.0); - float power = gloss2 / (3.14159 * denom * denom); - return power; -} - -// Frag Shading returns the diffuse amount as W and the specular rgb as xyz -vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, float roughness) { - // Diffuse Lighting - float diffuse = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); - - // Specular Lighting - vec3 halfDir = normalize(fragEyeDir + fragLightDir); - vec3 fresnelColor = fresnelSchlickColor(fresnel, fragLightDir, halfDir); - float power = specularDistribution(roughness, fragNormal, halfDir); - vec3 specular = fresnelColor * power * diffuse; - - return vec4(specular, (1.0 - metallic) * diffuse * (1.0 - fresnelColor.x)); -} // Frag Shading returns the diffuse amount as W and the specular rgb as xyz -vec4 evalPBRShadingDielectric(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float roughness, float fresnel) { - // Diffuse Lighting - float diffuse = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); +vec4 evalPBRShading(float metallic, vec3 fresnel, SurfaceData surface) { + // Incident angle attenuation + float angleAttenuation = surface.ndotl; // Specular Lighting - vec3 halfDir = normalize(fragEyeDir + fragLightDir); - float fresnelScalar = fresnelSchlickScalar(fresnel, fragLightDir, halfDir); - float power = specularDistribution(roughness, fragNormal, halfDir); - vec3 specular = vec3(fresnelScalar) * power * diffuse; + vec3 fresnelColor = fresnelSchlickColor(fresnel, surface); + float power = specularDistribution(surface); + vec3 specular = fresnelColor * power * angleAttenuation; + float diffuse = (1.0 - metallic) * angleAttenuation * (1.0 - fresnelColor.x); - return vec4(specular, diffuse * (1.0 - fresnelScalar)); + diffuse /= 3.1415926; + // Diffuse is divided by PI but specular isn't because an infinitesimal volume light source + // has a multiplier of PI, says Naty Hoffman. + // (see http://blog.selfshadow.com/publications/s2013-shading-course/hoffman/s2013_pbs_physics_math_notes.pdf + // page 23 paragraph "Punctual light sources") + + return vec4(specular, diffuse); } -vec4 evalPBRShadingMetallic(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float roughness, vec3 fresnel) { - // Diffuse Lighting - float diffuse = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); +// Frag Shading returns the diffuse amount as W and the specular rgb as xyz +vec4 evalPBRShadingDielectric(SurfaceData surface, float fresnel) { + // Incident angle attenuation + float angleAttenuation = surface.ndotl; // Specular Lighting - vec3 halfDir = normalize(fragEyeDir + fragLightDir); - vec3 fresnelColor = fresnelSchlickColor(fresnel, fragLightDir, halfDir); - float power = specularDistribution(roughness, fragNormal, halfDir); - vec3 specular = fresnelColor * power * diffuse; + float fresnelScalar = fresnelSchlickScalar(fresnel, surface); + float power = specularDistribution(surface); + vec3 specular = vec3(fresnelScalar) * power * angleAttenuation; + float diffuse = angleAttenuation * (1.0 - fresnelScalar); + diffuse /= 3.1415926; + // Diffuse is divided by PI but specular isn't because an infinitesimal volume light source + // has a multiplier of PI, says Naty Hoffman. + // (see http://blog.selfshadow.com/publications/s2013-shading-course/hoffman/s2013_pbs_physics_math_notes.pdf + // page 23 paragraph "Punctual light sources") + return vec4(specular, diffuse); +} + +vec4 evalPBRShadingMetallic(SurfaceData surface, vec3 fresnel) { + // Incident angle attenuation + float angleAttenuation = surface.ndotl; + + // Specular Lighting + vec3 fresnelColor = fresnelSchlickColor(fresnel, surface); + float power = specularDistribution(surface); + vec3 specular = fresnelColor * power * angleAttenuation; + + // Specular isn't divided by PI because an infinitesimal volume light source + // has a multiplier of PI, says Naty Hoffman. + // (see http://blog.selfshadow.com/publications/s2013-shading-course/hoffman/s2013_pbs_physics_math_notes.pdf + // page 23 paragraph "Punctual light sources") return vec4(specular, 0.f); } -// Frag Shading returns the diffuse amount as W and the specular rgb as xyz -vec4 evalPBRShadingGloss(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, float gloss2) { - // Diffuse Lighting - float diffuse = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); - - // Specular Lighting - vec3 halfDir = normalize(fragEyeDir + fragLightDir); - vec3 fresnelColor = fresnelSchlickColor(fresnel, fragLightDir, halfDir); - float power = specularDistributionGloss(gloss2, fragNormal, halfDir); - vec3 specular = fresnelColor * power * diffuse; - - return vec4(specular, (1.0 - metallic) * diffuse * (1.0 - fresnelColor.x)); -} - <@endfunc@> <$declareEvalPBRShading()$> -// Return xyz the specular/reflection component and w the diffuse component -//vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, float roughness) { -// return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, roughness); -//} - void evalFragShading(out vec3 diffuse, out vec3 specular, - vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, - float metallic, vec3 fresnel, float roughness, vec3 albedo) { - vec4 shading = evalPBRShading(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, roughness); + float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo) { + vec4 shading = evalPBRShading(metallic, fresnel, surface); diffuse = vec3(shading.w); if (isAlbedoEnabled() > 0.0) { diffuse *= albedo; @@ -229,22 +268,19 @@ void evalFragShading(out vec3 diffuse, out vec3 specular, void evalFragShading(out vec3 diffuse, out vec3 specular, - vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, - float metallic, vec3 fresnel, float roughness, vec3 albedo, + float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature) { if (scattering * isScatteringEnabled() > 0.0) { - vec3 brdf = evalSkinBRDF(fragLightDir, fragNormal, midNormalCurvature.xyz, lowNormalCurvature.xyz, lowNormalCurvature.w); - float NdotL = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); - diffuse = mix(vec3(NdotL), brdf, scattering); + vec3 brdf = evalSkinBRDF(surface.lightDir, surface.normal, midNormalCurvature.xyz, lowNormalCurvature.xyz, lowNormalCurvature.w); + diffuse = mix(vec3(surface.ndotl), brdf, scattering); // Specular Lighting - vec3 halfDir = normalize(fragEyeDir + fragLightDir); - vec2 specularBrdf = skinSpecular(fragNormal, fragLightDir, fragEyeDir, roughness, 1.0); + vec2 specularBrdf = skinSpecular(surface, 1.0); diffuse *= specularBrdf.y; specular = vec3(specularBrdf.x); } else { - vec4 shading = evalPBRShadingGloss(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, roughness); + vec4 shading = evalPBRShading(metallic, fresnel, surface); diffuse = vec3(shading.w); specular = shading.xyz; } @@ -253,17 +289,15 @@ void evalFragShading(out vec3 diffuse, out vec3 specular, void evalFragShadingScattering(out vec3 diffuse, out vec3 specular, - vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, - float metallic, vec3 fresnel, float roughness, vec3 albedo + float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo ,float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature ) { - vec3 brdf = evalSkinBRDF(fragLightDir, fragNormal, midNormalCurvature.xyz, lowNormalCurvature.xyz, lowNormalCurvature.w); - float NdotL = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); + vec3 brdf = evalSkinBRDF(surface.lightDir, surface.normal, midNormalCurvature.xyz, lowNormalCurvature.xyz, lowNormalCurvature.w); + float NdotL = surface.ndotl; diffuse = mix(vec3(NdotL), brdf, scattering); // Specular Lighting - vec3 halfDir = normalize(fragEyeDir + fragLightDir); - vec2 specularBrdf = skinSpecular(fragNormal, fragLightDir, fragEyeDir, roughness, 1.0); + vec2 specularBrdf = skinSpecular(surface, 1.0); diffuse *= specularBrdf.y; specular = vec3(specularBrdf.x); @@ -271,10 +305,9 @@ void evalFragShadingScattering(out vec3 diffuse, out vec3 specular, } void evalFragShadingGloss(out vec3 diffuse, out vec3 specular, - vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, - float metallic, vec3 fresnel, float gloss, vec3 albedo + float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo ) { - vec4 shading = evalPBRShadingGloss(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, gloss); + vec4 shading = evalPBRShading(metallic, fresnel, surface); diffuse = vec3(shading.w); diffuse *= mix(vec3(1.0), albedo, isAlbedoEnabled()); specular = shading.xyz; diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index d6ab2ff416..c506887fc4 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -45,17 +45,17 @@ template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderAr } } -MeshPartPayload::MeshPartPayload(const std::shared_ptr& mesh, int partIndex, model::MaterialPointer material) { +MeshPartPayload::MeshPartPayload(const std::shared_ptr& mesh, int partIndex, graphics::MaterialPointer material) { updateMeshPart(mesh, partIndex); updateMaterial(material); } -void MeshPartPayload::updateMeshPart(const std::shared_ptr& drawMesh, int partIndex) { +void MeshPartPayload::updateMeshPart(const std::shared_ptr& drawMesh, int partIndex) { _drawMesh = drawMesh; if (_drawMesh) { auto vertexFormat = _drawMesh->getVertexFormat(); _hasColorAttrib = vertexFormat->hasAttribute(gpu::Stream::COLOR); - _drawPart = _drawMesh->getPartBuffer().get(partIndex); + _drawPart = _drawMesh->getPartBuffer().get(partIndex); _localBound = _drawMesh->evalPartBound(partIndex); } } @@ -67,7 +67,7 @@ void MeshPartPayload::updateTransform(const Transform& transform, const Transfor _worldBound.transform(_drawTransform); } -void MeshPartPayload::updateMaterial(model::MaterialPointer drawMaterial) { +void MeshPartPayload::updateMaterial(graphics::MaterialPointer drawMaterial) { _drawMaterial = drawMaterial; } @@ -90,7 +90,7 @@ Item::Bound MeshPartPayload::getBound() const { } ShapeKey MeshPartPayload::getShapeKey() const { - model::MaterialKey drawMaterialKey; + graphics::MaterialKey drawMaterialKey; if (_drawMaterial) { drawMaterialKey = _drawMaterial->getKey(); } @@ -156,7 +156,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat // Albedo if (materialKey.isAlbedoMap()) { - auto itr = textureMaps.find(model::MaterialKey::ALBEDO_MAP); + auto itr = textureMaps.find(graphics::MaterialKey::ALBEDO_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, itr->second->getTextureView()); } else { @@ -166,7 +166,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat // Roughness map if (materialKey.isRoughnessMap()) { - auto itr = textureMaps.find(model::MaterialKey::ROUGHNESS_MAP); + auto itr = textureMaps.find(graphics::MaterialKey::ROUGHNESS_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, itr->second->getTextureView()); @@ -178,7 +178,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat // Normal map if (materialKey.isNormalMap()) { - auto itr = textureMaps.find(model::MaterialKey::NORMAL_MAP); + auto itr = textureMaps.find(graphics::MaterialKey::NORMAL_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, itr->second->getTextureView()); @@ -190,7 +190,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat // Metallic map if (materialKey.isMetallicMap()) { - auto itr = textureMaps.find(model::MaterialKey::METALLIC_MAP); + auto itr = textureMaps.find(graphics::MaterialKey::METALLIC_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, itr->second->getTextureView()); @@ -202,7 +202,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat // Occlusion map if (materialKey.isOcclusionMap()) { - auto itr = textureMaps.find(model::MaterialKey::OCCLUSION_MAP); + auto itr = textureMaps.find(graphics::MaterialKey::OCCLUSION_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, itr->second->getTextureView()); @@ -214,7 +214,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat // Scattering map if (materialKey.isScatteringMap()) { - auto itr = textureMaps.find(model::MaterialKey::SCATTERING_MAP); + auto itr = textureMaps.find(graphics::MaterialKey::SCATTERING_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::SCATTERING, itr->second->getTextureView()); @@ -226,7 +226,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat // Emissive / Lightmap if (materialKey.isLightmapMap()) { - auto itr = textureMaps.find(model::MaterialKey::LIGHTMAP_MAP); + auto itr = textureMaps.find(graphics::MaterialKey::LIGHTMAP_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, itr->second->getTextureView()); @@ -234,7 +234,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getGrayTexture()); } } else if (materialKey.isEmissiveMap()) { - auto itr = textureMaps.find(model::MaterialKey::EMISSIVE_MAP); + auto itr = textureMaps.find(graphics::MaterialKey::EMISSIVE_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, itr->second->getTextureView()); @@ -439,7 +439,7 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, bool isWireframe return; } - model::MaterialKey drawMaterialKey; + graphics::MaterialKey drawMaterialKey; if (_drawMaterial) { drawMaterialKey = _drawMaterial->getKey(); } diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 8d36395610..8160b9f009 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -19,7 +19,7 @@ #include #include -#include +#include #include "Model.h" @@ -28,17 +28,17 @@ class Model; class MeshPartPayload { public: MeshPartPayload() {} - MeshPartPayload(const std::shared_ptr& mesh, int partIndex, model::MaterialPointer material); + MeshPartPayload(const std::shared_ptr& mesh, int partIndex, graphics::MaterialPointer material); typedef render::Payload Payload; typedef Payload::DataPointer Pointer; - virtual void updateMeshPart(const std::shared_ptr& drawMesh, int partIndex); + virtual void updateMeshPart(const std::shared_ptr& drawMesh, int partIndex); virtual void notifyLocationChanged() {} void updateTransform(const Transform& transform, const Transform& offsetTransform); - virtual void updateMaterial(model::MaterialPointer drawMaterial); + virtual void updateMaterial(graphics::MaterialPointer drawMaterial); // Render Item interface virtual render::ItemKey getKey() const; @@ -58,13 +58,13 @@ public: int _partIndex = 0; bool _hasColorAttrib { false }; - model::Box _localBound; - model::Box _adjustedLocalBound; - mutable model::Box _worldBound; - std::shared_ptr _drawMesh; + graphics::Box _localBound; + graphics::Box _adjustedLocalBound; + mutable graphics::Box _worldBound; + std::shared_ptr _drawMesh; - std::shared_ptr _drawMaterial; - model::Mesh::Part _drawPart; + std::shared_ptr _drawMaterial; + graphics::Mesh::Part _drawPart; size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; } size_t getMaterialTextureSize() { return _drawMaterial ? _drawMaterial->getTextureSize() : 0; } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 9c1c579341..6922e95d39 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -46,7 +46,7 @@ float Model::FAKE_DIMENSION_PLACEHOLDER = -1.0f; #define HTTP_INVALID_COM "http://invalid.com" const int NUM_COLLISION_HULL_COLORS = 24; -std::vector _collisionMaterials; +std::vector _collisionMaterials; void initCollisionMaterials() { // generates bright colors in red, green, blue, yellow, magenta, and cyan spectrums @@ -72,8 +72,8 @@ void initCollisionMaterials() { // so they don't tend to group together for large models for (int i = 0; i < sectionWidth; ++i) { for (int j = 0; j < numComponents; ++j) { - model::MaterialPointer material; - material = std::make_shared(); + graphics::MaterialPointer material; + material = std::make_shared(); int index = j * sectionWidth + i; float red = component[index]; float green = component[(index + greenPhase) % NUM_COLLISION_HULL_COLORS]; @@ -145,7 +145,13 @@ void Model::setTransformNoUpdateRenderItems(const Transform& transform) { } Transform Model::getTransform() const { - if (_spatiallyNestableOverride) { + if (_overrideModelTransform) { + Transform transform; + transform.setTranslation(getOverrideTranslation()); + transform.setRotation(getOverrideRotation()); + transform.setScale(getScale()); + return transform; + } else if (_spatiallyNestableOverride) { bool success; Transform transform = _spatiallyNestableOverride->getTransform(success); if (success) { @@ -559,7 +565,7 @@ MeshProxyList Model::getMeshes() const { offset.postTranslate(_offset); glm::mat4 offsetMat = offset.getMatrix(); - for (std::shared_ptr mesh : meshes) { + for (std::shared_ptr mesh : meshes) { if (!mesh) { continue; } @@ -1259,25 +1265,6 @@ void Model::updateClusterMatrices() { } } -void Model::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::quat& targetRotation, float priority) { - const FBXGeometry& geometry = getFBXGeometry(); - const QVector& freeLineage = geometry.joints.at(endIndex).freeLineage; - glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset); - _rig.inverseKinematics(endIndex, targetPosition, targetRotation, priority, freeLineage, parentTransform); -} - -bool Model::restoreJointPosition(int jointIndex, float fraction, float priority) { - const FBXGeometry& geometry = getFBXGeometry(); - const QVector& freeLineage = geometry.joints.at(jointIndex).freeLineage; - return _rig.restoreJointPosition(jointIndex, fraction, priority, freeLineage); -} - -float Model::getLimbLength(int jointIndex) const { - const FBXGeometry& geometry = getFBXGeometry(); - const QVector& freeLineage = geometry.joints.at(jointIndex).freeLineage; - return _rig.getLimbLength(jointIndex, freeLineage, _scale, geometry.joints); -} - bool Model::maybeStartBlender() { if (isLoaded()) { const FBXGeometry& fbxGeometry = getFBXGeometry(); @@ -1381,6 +1368,14 @@ void Model::deleteGeometry() { _collisionGeometry.reset(); } +void Model::overrideModelTransformAndOffset(const Transform& transform, const glm::vec3& offset) { + _overrideTranslation = transform.getTranslation(); + _overrideRotation = transform.getRotation(); + _overrideModelTransform = true; + setScale(transform.getScale()); + setOffset(offset); +} + AABox Model::getRenderableMeshBound() const { if (!isLoaded()) { return AABox(); @@ -1481,7 +1476,7 @@ void Model::createCollisionRenderItemSet() { // Create the render payloads int numParts = (int)mesh->getNumParts(); for (int partIndex = 0; partIndex < numParts; partIndex++) { - model::MaterialPointer& material = _collisionMaterials[partIndex % NUM_COLLISION_HULL_COLORS]; + graphics::MaterialPointer& material = _collisionMaterials[partIndex % NUM_COLLISION_HULL_COLORS]; auto payload = std::make_shared(mesh, partIndex, material); payload->updateTransform(identity, offset); _collisionRenderItems << payload; @@ -1495,7 +1490,7 @@ bool Model::isRenderable() const { class CollisionRenderGeometry : public Geometry { public: - CollisionRenderGeometry(model::MeshPointer mesh) { + CollisionRenderGeometry(graphics::MeshPointer mesh) { _fbxGeometry = std::make_shared(); std::shared_ptr meshes = std::make_shared(); meshes->push_back(mesh); @@ -1504,7 +1499,7 @@ public: } }; -void Model::setCollisionMesh(model::MeshPointer mesh) { +void Model::setCollisionMesh(graphics::MeshPointer mesh) { if (mesh) { _collisionGeometry = std::make_shared(mesh); } else { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 623f869666..560aa82f0c 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -199,8 +199,6 @@ public: /// Returns the index of the parent of the indexed joint, or -1 if not found. int getParentJointIndex(int jointIndex) const; - void inverseKinematics(int jointIndex, glm::vec3 position, const glm::quat& rotation, float priority); - /// Returns the extents of the model in its bind pose. Extents getBindExtents() const; @@ -212,10 +210,15 @@ public: void setTranslation(const glm::vec3& translation); void setRotation(const glm::quat& rotation); + void overrideModelTransformAndOffset(const Transform& transform, const glm::vec3& offset); + bool isOverridingModelTransformAndOffset() { return _overrideModelTransform; }; + void stopTransformAndOffsetOverride() { _overrideModelTransform = false; }; void setTransformNoUpdateRenderItems(const Transform& transform); // temporary HACK const glm::vec3& getTranslation() const { return _translation; } const glm::quat& getRotation() const { return _rotation; } + const glm::vec3& getOverrideTranslation() const { return _overrideTranslation; } + const glm::quat& getOverrideRotation() const { return _overrideRotation; } glm::vec3 getNaturalDimensions() const; @@ -240,7 +243,7 @@ public: // returns 'true' if needs fullUpdate after geometry change virtual bool updateGeometry(); - void setCollisionMesh(model::MeshPointer mesh); + void setCollisionMesh(graphics::MeshPointer mesh); void setLoadingPriority(float priority) { _loadingPriority = priority; } @@ -343,6 +346,9 @@ protected: glm::quat _rotation; glm::vec3 _scale; + glm::vec3 _overrideTranslation; + glm::quat _overrideRotation; + // For entity models this is the translation for the minimum extent of the model (in original mesh coordinate space) // to the model's registration point. For avatar models this is the translation from the avatar's hips, as determined // by the default pose, to the origin. @@ -368,16 +374,6 @@ protected: void computeMeshPartLocalBounds(); virtual void updateRig(float deltaTime, glm::mat4 parentTransform); - /// Restores the indexed joint to its default position. - /// \param fraction the fraction of the default position to apply (i.e., 0.25f to slerp one fourth of the way to - /// the original position - /// \return true if the joint was found - bool restoreJointPosition(int jointIndex, float fraction = 1.0f, float priority = 0.0f); - - /// Computes and returns the extended length of the limb terminating at the specified joint and starting at the joint's - /// first free ancestor. - float getLimbLength(int jointIndex) const; - /// Allow sub classes to force invalidating the bboxes void invalidCalculatedMeshBoxes() { _triangleSetsValid = false; @@ -403,6 +399,7 @@ protected: QMutex _mutex; + bool _overrideModelTransform { false }; bool _triangleSetsValid { false }; void calculateTriangleSets(); QVector _modelSpaceMeshTriangleSets; // model space triangles for all sub meshes diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index f860c0494e..8b97f902ac 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -338,7 +338,7 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& // Setup haze iff curretn zone has haze auto hazeStage = args->_scene->getStage(); if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) { - model::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front()); + graphics::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front()); batch.setUniformBuffer(render::ShapePipeline::Slot::HAZE_MODEL, hazePointer->getHazeParametersBuffer()); } diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 7f644add72..2eb063e9e8 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -546,7 +546,7 @@ void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderArgs* a if (pipeline.locations->materialBufferUnit >= 0) { // Create a default schema static bool isMaterialSet = false; - static model::Material material; + static graphics::Material material; if (!isMaterialSet) { material.setAlbedo(vec3(1.0f)); material.setOpacity(1.0f); diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 2e5b7132e4..d83dfd73a5 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -271,7 +271,7 @@ void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderCon // Set the keylight render args args->pushViewFrustum(*(globalShadow->getCascade(_cascadeIndex).getFrustum())); args->_renderMode = RenderArgs::SHADOW_RENDER_MODE; - if (lightStage->getCurrentKeyLight()->getType() == model::Light::SUN) { + if (lightStage->getCurrentKeyLight()->getType() == graphics::Light::SUN) { const float shadowSizeScale = 1e16f; // Set the size scale to a ridiculously high value to prevent small object culling which assumes // the view frustum is a perspective projection. But this isn't the case for the sun which diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index f71111b64e..de8de9abcf 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -26,7 +26,7 @@ void PrepareStencil::configure(const Config& config) { _forceDraw = config.forceDraw; } -model::MeshPointer PrepareStencil::getMesh() { +graphics::MeshPointer PrepareStencil::getMesh() { if (!_mesh) { std::vector vertices { @@ -36,7 +36,7 @@ model::MeshPointer PrepareStencil::getMesh() { { 1.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f } }; std::vector indices { 0, 7, 1, 1, 3, 2, 3, 5, 4, 5, 7, 6 }; - _mesh = model::Mesh::createIndexedTriangles_P3F((uint32_t) vertices.size(), (uint32_t) indices.size(), vertices.data(), indices.data()); + _mesh = graphics::Mesh::createIndexedTriangles_P3F((uint32_t) vertices.size(), (uint32_t) indices.size(), vertices.data(), indices.data()); } return _mesh; } @@ -95,7 +95,7 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F batch.setInputStream(0, mesh->getVertexStream()); // Draw - auto part = mesh->getPartBuffer().get(0); + auto part = mesh->getPartBuffer().get(0); batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex); } else { batch.setPipeline(getPaintStencilPipeline()); @@ -129,7 +129,7 @@ void PrepareStencil::testNoAA(gpu::State& state) { } // Pass if this area WAS marked as BACKGROUND -// (see: model/src/Skybox.cpp, procedural/src/ProceduralSkybox.cpp) +// (see: graphics/src/Skybox.cpp, procedural/src/ProceduralSkybox.cpp) void PrepareStencil::testBackground(gpu::State& state) { state.setStencilTest(true, 0x00, gpu::State::StencilTest(STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index fc258b607a..a8e4d1e1f2 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -14,7 +14,7 @@ #include #include -#include +#include class PrepareStencilConfig : public render::Job::Config { Q_OBJECT @@ -63,8 +63,8 @@ private: gpu::PipelinePointer _paintStencilPipeline; gpu::PipelinePointer getPaintStencilPipeline(); - model::MeshPointer _mesh; - model::MeshPointer getMesh(); + graphics::MeshPointer _mesh; + graphics::MeshPointer getMesh(); int _maskMode { 0 }; bool _forceDraw { false }; diff --git a/libraries/render-utils/src/SubsurfaceScattering.slh b/libraries/render-utils/src/SubsurfaceScattering.slh index 201ec2291a..233dfd7a0c 100644 --- a/libraries/render-utils/src/SubsurfaceScattering.slh +++ b/libraries/render-utils/src/SubsurfaceScattering.slh @@ -63,38 +63,6 @@ vec3 scatter(float r) { <@endfunc@> -<@func declareSkinSpecularLighting()@> - -uniform sampler2D scatteringSpecularBeckmann; - -float fetchSpecularBeckmann(float ndoth, float roughness) { - return pow( 2.0 * texture(scatteringSpecularBeckmann, vec2(ndoth, roughness)).r, 10.0); -} - -float fresnelReflectance(vec3 H, vec3 V, float Fo) { - float base = 1.0 - dot(V, H); - float exponential = pow(base, 5.0); - return exponential + Fo * (1.0 - exponential); -} - -float skinSpecular(vec3 N, vec3 L, vec3 V, float roughness, float intensity) { - float result = 0.0; - float ndotl = dot(N, L); - if (ndotl > 0.0) { - vec3 h = L + V; - vec3 H = normalize(h); - float ndoth = dot(N, H); - float PH = fetchSpecularBeckmann(ndoth, roughness); - float F = fresnelReflectance(H, V, 0.028); - float frSpec = max(PH * F / dot(h, h), 0.0); - result = ndotl * intensity * frSpec; - } - - return result; -} - -<@endfunc@> - <@func declareSubsurfaceScatteringIntegrate(NumIntegrationSteps)@> diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index c0d01c2eaf..c39e6068b7 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -145,14 +145,14 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I auto deferredTransform = inputs; auto lightStage = context->_scene->getStage(LightStage::getName()); - std::vector keyLightStack; + std::vector keyLightStack; if (lightStage && lightStage->_currentFrame._sunLights.size()) { for (auto index : lightStage->_currentFrame._sunLights) { keyLightStack.push_back(lightStage->getLight(index)); } } - std::vector ambientLightStack; + std::vector ambientLightStack; if (lightStage && lightStage->_currentFrame._ambientLights.size()) { for (auto index : lightStage->_currentFrame._ambientLights) { ambientLightStack.push_back(lightStage->getLight(index)); @@ -160,7 +160,7 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I } auto backgroundStage = context->_scene->getStage(BackgroundStage::getName()); - std::vector skyboxStack; + std::vector skyboxStack; if (backgroundStage && backgroundStage->_currentFrame._backgrounds.size()) { for (auto index : backgroundStage->_currentFrame._backgrounds) { auto background = backgroundStage->getBackground(index); diff --git a/libraries/render-utils/src/deferred_light_point.slv b/libraries/render-utils/src/deferred_light_point.slv index 88da7dd04c..2b75ee3915 100644 --- a/libraries/render-utils/src/deferred_light_point.slv +++ b/libraries/render-utils/src/deferred_light_point.slv @@ -18,7 +18,7 @@ <$declareStandardTransform()$> -<@include model/Light.slh@> +<@include graphics/Light.slh@> <$declareLightBuffer(256)$> diff --git a/libraries/render-utils/src/deferred_light_spot.slv b/libraries/render-utils/src/deferred_light_spot.slv index f6dc7faaf1..7e3e45b3b6 100644 --- a/libraries/render-utils/src/deferred_light_spot.slv +++ b/libraries/render-utils/src/deferred_light_spot.slv @@ -18,7 +18,7 @@ <$declareStandardTransform()$> -<@include model/Light.slh@> +<@include graphics/Light.slh@> <$declareLightBuffer(256)$> uniform lightIndexBuffer { diff --git a/libraries/render-utils/src/forward_model.slf b/libraries/render-utils/src/forward_model.slf index 7b708a1d24..41ff4afc81 100644 --- a/libraries/render-utils/src/forward_model.slf +++ b/libraries/render-utils/src/forward_model.slf @@ -16,7 +16,7 @@ <@include ForwardGlobalLight.slh@> <$declareEvalSkyboxGlobalColor()$> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include gpu/Transform.slh@> <$declareStandardCameraTransform()$> diff --git a/libraries/render-utils/src/forward_model_normal_map.slf b/libraries/render-utils/src/forward_model_normal_map.slf index a199483b9f..e5fcab4945 100644 --- a/libraries/render-utils/src/forward_model_normal_map.slf +++ b/libraries/render-utils/src/forward_model_normal_map.slf @@ -14,7 +14,7 @@ <@include ForwardBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, _SCRIBE_NULL, EMISSIVE, OCCLUSION, SCATTERING)$> diff --git a/libraries/render-utils/src/forward_model_normal_specular_map.slf b/libraries/render-utils/src/forward_model_normal_specular_map.slf index ca6bbec3da..01a4251e8d 100644 --- a/libraries/render-utils/src/forward_model_normal_specular_map.slf +++ b/libraries/render-utils/src/forward_model_normal_specular_map.slf @@ -14,7 +14,7 @@ <@include ForwardBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION)$> diff --git a/libraries/render-utils/src/forward_model_specular_map.slf b/libraries/render-utils/src/forward_model_specular_map.slf index d2fdd18794..77d34d4309 100644 --- a/libraries/render-utils/src/forward_model_specular_map.slf +++ b/libraries/render-utils/src/forward_model_specular_map.slf @@ -14,7 +14,7 @@ <@include ForwardBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC, EMISSIVE, OCCLUSION)$> diff --git a/libraries/render-utils/src/forward_model_translucent.slf b/libraries/render-utils/src/forward_model_translucent.slf index 906393db1f..7f752d893a 100644 --- a/libraries/render-utils/src/forward_model_translucent.slf +++ b/libraries/render-utils/src/forward_model_translucent.slf @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include ForwardGlobalLight.slh@> diff --git a/libraries/render-utils/src/forward_model_unlit.slf b/libraries/render-utils/src/forward_model_unlit.slf index fb760467c9..72ee61e28c 100644 --- a/libraries/render-utils/src/forward_model_unlit.slf +++ b/libraries/render-utils/src/forward_model_unlit.slf @@ -14,7 +14,7 @@ <@include ForwardBufferWrite.slh@> <@include LightingModel.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO)$> diff --git a/libraries/render-utils/src/lightClusters_drawClusterContent.slf b/libraries/render-utils/src/lightClusters_drawClusterContent.slf index 447f8bd634..739709418d 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterContent.slf +++ b/libraries/render-utils/src/lightClusters_drawClusterContent.slf @@ -15,7 +15,7 @@ <@include DeferredBufferRead.slh@> -<@include model/Light.slh@> +<@include graphics/Light.slh@> <$declareLightBuffer(256)$> <@include LightClusterGrid.slh@> diff --git a/libraries/render-utils/src/local_lights_drawOutline.slf b/libraries/render-utils/src/local_lights_drawOutline.slf index 3aa210a241..56ce1e61a5 100644 --- a/libraries/render-utils/src/local_lights_drawOutline.slf +++ b/libraries/render-utils/src/local_lights_drawOutline.slf @@ -18,7 +18,7 @@ <$declareDeferredCurvature()$> // Everything about light -<@include model/Light.slh@> +<@include graphics/Light.slh@> <$declareLightBuffer(128)$> <@include LightingModel.slh@> diff --git a/libraries/render-utils/src/local_lights_shading.slf b/libraries/render-utils/src/local_lights_shading.slf index c6310cb079..c3208de726 100644 --- a/libraries/render-utils/src/local_lights_shading.slf +++ b/libraries/render-utils/src/local_lights_shading.slf @@ -18,7 +18,7 @@ <$declareDeferredCurvature()$> // Everything about light -<@include model/Light.slh@> +<@include graphics/Light.slh@> <$declareLightBuffer(256)$> <@include LightingModel.slh@> @@ -84,9 +84,8 @@ void main(void) { // Frag to eye vec vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - - // Compute the rougness into gloss2 once: - float fragGloss2 = pow(frag.roughness + 0.001, 4.0); + + SurfaceData surface = initSurfaceData(frag.roughness, frag.normal, fragEyeDir); bool withScattering = (frag.scattering * isScatteringEnabled() > 0.0); int numLightTouching = 0; @@ -119,16 +118,18 @@ void main(void) { float fragLightDistance = fragLightDirLen.w; vec3 fragLightDir = fragLightDirLen.xyz; + updateSurfaceDataWithLight(surface, fragLightDir); + // Eval attenuation float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); vec3 lightEnergy = radialAttenuation * getLightIrradiance(light); // Eval shading if (withScattering) { - evalFragShadingScattering(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo + evalFragShadingScattering(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo ,frag.scattering, midNormalCurvature, lowNormalCurvature ); } else { - evalFragShadingGloss(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, fragGloss2, frag.albedo); + evalFragShadingGloss(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo); } diffuse *= lightEnergy * isDiffuseEnabled(); @@ -173,6 +174,8 @@ void main(void) { float fragLightDistance = fragLightDirLen.w; vec3 fragLightDir = fragLightDirLen.xyz; + updateSurfaceDataWithLight(surface, fragLightDir); + // Eval attenuation float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); float angularAttenuation = lightIrradiance_evalLightSpotAttenuation(light.irradiance, cosSpotAngle); @@ -180,10 +183,10 @@ void main(void) { // Eval shading if (withScattering) { - evalFragShadingScattering(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo + evalFragShadingScattering(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo ,frag.scattering, midNormalCurvature, lowNormalCurvature ); } else { - evalFragShadingGloss(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, fragGloss2, frag.albedo); + evalFragShadingGloss(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo); } diffuse *= lightEnergy * isDiffuseEnabled(); diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index daeead65ec..4747b69278 100644 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -13,7 +13,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$> diff --git a/libraries/render-utils/src/model_fade.slf b/libraries/render-utils/src/model_fade.slf index d232667660..40c156a3a4 100644 --- a/libraries/render-utils/src/model_fade.slf +++ b/libraries/render-utils/src/model_fade.slf @@ -13,7 +13,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$> diff --git a/libraries/render-utils/src/model_lightmap.slf b/libraries/render-utils/src/model_lightmap.slf index 3a8cfde290..b22a1029f9 100644 --- a/libraries/render-utils/src/model_lightmap.slf +++ b/libraries/render-utils/src/model_lightmap.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS)$> diff --git a/libraries/render-utils/src/model_lightmap_fade.slf b/libraries/render-utils/src/model_lightmap_fade.slf index 92d00a2046..55cb24d35d 100644 --- a/libraries/render-utils/src/model_lightmap_fade.slf +++ b/libraries/render-utils/src/model_lightmap_fade.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS)$> diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slf b/libraries/render-utils/src/model_lightmap_normal_map.slf index 81de1e5d5b..1510ea9ba3 100644 --- a/libraries/render-utils/src/model_lightmap_normal_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL)$> diff --git a/libraries/render-utils/src/model_lightmap_normal_map_fade.slf b/libraries/render-utils/src/model_lightmap_normal_map_fade.slf index 825e84d666..6b63943a9a 100644 --- a/libraries/render-utils/src/model_lightmap_normal_map_fade.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map_fade.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL)$> diff --git a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf index 944da27b01..3a66aaad3d 100644 --- a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC)$> diff --git a/libraries/render-utils/src/model_lightmap_normal_specular_map_fade.slf b/libraries/render-utils/src/model_lightmap_normal_specular_map_fade.slf index 791d5bf552..b785a8a6ab 100644 --- a/libraries/render-utils/src/model_lightmap_normal_specular_map_fade.slf +++ b/libraries/render-utils/src/model_lightmap_normal_specular_map_fade.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC)$> diff --git a/libraries/render-utils/src/model_lightmap_specular_map.slf b/libraries/render-utils/src/model_lightmap_specular_map.slf index 4dbc10a834..1c97d435bd 100644 --- a/libraries/render-utils/src/model_lightmap_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_specular_map.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC)$> diff --git a/libraries/render-utils/src/model_lightmap_specular_map_fade.slf b/libraries/render-utils/src/model_lightmap_specular_map_fade.slf index e82018eefb..1adedb9328 100644 --- a/libraries/render-utils/src/model_lightmap_specular_map_fade.slf +++ b/libraries/render-utils/src/model_lightmap_specular_map_fade.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC)$> diff --git a/libraries/render-utils/src/model_normal_map.slf b/libraries/render-utils/src/model_normal_map.slf index 063950609a..bed85b4b15 100644 --- a/libraries/render-utils/src/model_normal_map.slf +++ b/libraries/render-utils/src/model_normal_map.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, _SCRIBE_NULL, EMISSIVE, OCCLUSION, SCATTERING)$> diff --git a/libraries/render-utils/src/model_normal_map_fade.slf b/libraries/render-utils/src/model_normal_map_fade.slf index d8b864260c..5a166b1c2c 100644 --- a/libraries/render-utils/src/model_normal_map_fade.slf +++ b/libraries/render-utils/src/model_normal_map_fade.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, _SCRIBE_NULL, EMISSIVE, OCCLUSION, SCATTERING)$> diff --git a/libraries/render-utils/src/model_normal_specular_map.slf b/libraries/render-utils/src/model_normal_specular_map.slf index 9e079b33a0..3eb3d43fdc 100644 --- a/libraries/render-utils/src/model_normal_specular_map.slf +++ b/libraries/render-utils/src/model_normal_specular_map.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION)$> diff --git a/libraries/render-utils/src/model_normal_specular_map_fade.slf b/libraries/render-utils/src/model_normal_specular_map_fade.slf index 5492b24763..0985d5d493 100644 --- a/libraries/render-utils/src/model_normal_specular_map_fade.slf +++ b/libraries/render-utils/src/model_normal_specular_map_fade.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION)$> diff --git a/libraries/render-utils/src/model_specular_map.slf b/libraries/render-utils/src/model_specular_map.slf index 47b5e3389d..e65dbaeda6 100644 --- a/libraries/render-utils/src/model_specular_map.slf +++ b/libraries/render-utils/src/model_specular_map.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC, EMISSIVE, OCCLUSION)$> diff --git a/libraries/render-utils/src/model_specular_map_fade.slf b/libraries/render-utils/src/model_specular_map_fade.slf index 6eb56c0929..17173d8bc3 100644 --- a/libraries/render-utils/src/model_specular_map_fade.slf +++ b/libraries/render-utils/src/model_specular_map_fade.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC, EMISSIVE, OCCLUSION)$> diff --git a/libraries/render-utils/src/model_translucent.slf b/libraries/render-utils/src/model_translucent.slf index 38f162fdc3..0924389dba 100644 --- a/libraries/render-utils/src/model_translucent.slf +++ b/libraries/render-utils/src/model_translucent.slf @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include DeferredGlobalLight.slh@> @@ -50,13 +50,7 @@ void main(void) { <$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>; float metallic = getMaterialMetallic(mat); - vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value - if (metallic <= 0.5) { - metallic = 0.0; - } else { - fresnel = albedo; - metallic = 1.0; - } + vec3 fresnel = getFresnelF0(metallic, albedo); vec3 emissive = getMaterialEmissive(mat); <$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>; diff --git a/libraries/render-utils/src/model_translucent_fade.slf b/libraries/render-utils/src/model_translucent_fade.slf index 9d5477304c..8ac442476f 100644 --- a/libraries/render-utils/src/model_translucent_fade.slf +++ b/libraries/render-utils/src/model_translucent_fade.slf @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include DeferredGlobalLight.slh@> @@ -60,13 +60,7 @@ void main(void) { <$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>; float metallic = getMaterialMetallic(mat); - vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value - if (metallic <= 0.5) { - metallic = 0.0; - } else { - fresnel = albedo; - metallic = 1.0; - } + vec3 fresnel = getFresnelF0(metallic, albedo); vec3 emissive = getMaterialEmissive(mat); <$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>; diff --git a/libraries/render-utils/src/model_translucent_unlit.slf b/libraries/render-utils/src/model_translucent_unlit.slf index b397cea5aa..4c3a0f0195 100644 --- a/libraries/render-utils/src/model_translucent_unlit.slf +++ b/libraries/render-utils/src/model_translucent_unlit.slf @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$> diff --git a/libraries/render-utils/src/model_translucent_unlit_fade.slf b/libraries/render-utils/src/model_translucent_unlit_fade.slf index 6a77efe4ca..210060d54d 100644 --- a/libraries/render-utils/src/model_translucent_unlit_fade.slf +++ b/libraries/render-utils/src/model_translucent_unlit_fade.slf @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$> diff --git a/libraries/render-utils/src/model_unlit.slf b/libraries/render-utils/src/model_unlit.slf index 750b51fe8c..ccfc7d4935 100644 --- a/libraries/render-utils/src/model_unlit.slf +++ b/libraries/render-utils/src/model_unlit.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> <@include LightingModel.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO)$> diff --git a/libraries/render-utils/src/model_unlit_fade.slf b/libraries/render-utils/src/model_unlit_fade.slf index 0fe9f2ebac..65c97f9e21 100644 --- a/libraries/render-utils/src/model_unlit_fade.slf +++ b/libraries/render-utils/src/model_unlit_fade.slf @@ -14,7 +14,7 @@ <@include DeferredBufferWrite.slh@> <@include LightingModel.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include Fade.slh@> <$declareFadeFragment()$> diff --git a/libraries/render-utils/src/overlay3D.slf b/libraries/render-utils/src/overlay3D.slf index 0cb3340845..dcded917b4 100644 --- a/libraries/render-utils/src/overlay3D.slf +++ b/libraries/render-utils/src/overlay3D.slf @@ -12,7 +12,7 @@ // -<@include model/Light.slh@> +<@include graphics/Light.slh@> <$declareLightBuffer()$> <$declareLightAmbientBuffer()$> @@ -40,12 +40,14 @@ vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 a vec3 fragEyeDir; <$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$> + SurfaceData surface = initSurfaceData(roughness, normal, fragEyeDir); + vec3 color = opacity * albedo * getLightColor(light) * getLightAmbientIntensity(ambient); // Directional vec3 directionalDiffuse; vec3 directionalSpecular; - evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); + evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation); color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled(); diff --git a/libraries/render-utils/src/overlay3D_model.slf b/libraries/render-utils/src/overlay3D_model.slf index bb0d84a513..d4de0ee69f 100644 --- a/libraries/render-utils/src/overlay3D_model.slf +++ b/libraries/render-utils/src/overlay3D_model.slf @@ -14,7 +14,7 @@ <@include DeferredGlobalLight.slh@> <$declareEvalSkyboxGlobalColor()$> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include gpu/Transform.slh@> <$declareStandardCameraTransform()$> @@ -46,13 +46,7 @@ void main(void) { albedo *= _color; float metallic = getMaterialMetallic(mat); - vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value - if (metallic <= 0.5) { - metallic = 0.0; - } else { - fresnel = albedo; - metallic = 1.0; - } + vec3 fresnel = getFresnelF0(metallic, albedo); float roughness = getMaterialRoughness(mat); <$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>; diff --git a/libraries/render-utils/src/overlay3D_model_translucent.slf b/libraries/render-utils/src/overlay3D_model_translucent.slf index b26e70f465..8dd3a81443 100644 --- a/libraries/render-utils/src/overlay3D_model_translucent.slf +++ b/libraries/render-utils/src/overlay3D_model_translucent.slf @@ -13,7 +13,7 @@ <@include DeferredGlobalLight.slh@> <$declareEvalGlobalLightingAlphaBlended()$> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include gpu/Transform.slh@> <$declareStandardCameraTransform()$> @@ -44,13 +44,7 @@ void main(void) { albedo *= _color; float metallic = getMaterialMetallic(mat); - vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value - if (metallic <= 0.5) { - metallic = 0.0; - } else { - fresnel = albedo; - metallic = 1.0; - } + vec3 fresnel = getFresnelF0(metallic, albedo); float roughness = getMaterialRoughness(mat); <$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>; diff --git a/libraries/render-utils/src/overlay3D_model_translucent_unlit.slf b/libraries/render-utils/src/overlay3D_model_translucent_unlit.slf index 3dd8138272..3b79818cd9 100644 --- a/libraries/render-utils/src/overlay3D_model_translucent_unlit.slf +++ b/libraries/render-utils/src/overlay3D_model_translucent_unlit.slf @@ -12,7 +12,7 @@ // <@include LightingModel.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO)$> diff --git a/libraries/render-utils/src/overlay3D_model_unlit.slf b/libraries/render-utils/src/overlay3D_model_unlit.slf index 80c2bb971e..eab975e810 100644 --- a/libraries/render-utils/src/overlay3D_model_unlit.slf +++ b/libraries/render-utils/src/overlay3D_model_unlit.slf @@ -12,7 +12,7 @@ // <@include LightingModel.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include MaterialTextures.slh@> <$declareMaterialTextures(ALBEDO)$> diff --git a/libraries/render-utils/src/overlay3D_translucent.slf b/libraries/render-utils/src/overlay3D_translucent.slf index 9bdac2d21f..64035ac984 100644 --- a/libraries/render-utils/src/overlay3D_translucent.slf +++ b/libraries/render-utils/src/overlay3D_translucent.slf @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include model/Light.slh@> +<@include graphics/Light.slh@> <$declareLightBuffer()$> <$declareLightAmbientBuffer()$> @@ -40,12 +40,14 @@ vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 a vec3 fragEyeDir; <$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$> + SurfaceData surface = initSurfaceData(roughness, normal, fragEyeDir); + vec3 color = opacity * albedo * getLightColor(light) * getLightAmbientIntensity(ambient); // Directional vec3 directionalDiffuse; vec3 directionalSpecular; - evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); + evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation); color += directionalDiffuse; color += directionalSpecular / opacity; diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index fd45c6c134..7b32541c63 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -13,7 +13,7 @@ // <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> // the interpolated normal in vec3 _normal; diff --git a/libraries/render-utils/src/simple_fade.slf b/libraries/render-utils/src/simple_fade.slf index 245d32e81e..ce9251b9a5 100644 --- a/libraries/render-utils/src/simple_fade.slf +++ b/libraries/render-utils/src/simple_fade.slf @@ -13,7 +13,7 @@ // <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include Fade.slh@> <$declareFadeFragmentInstanced()$> diff --git a/libraries/render-utils/src/simple_textured.slf b/libraries/render-utils/src/simple_textured.slf index 550f6546fd..34fcbc77dc 100644 --- a/libraries/render-utils/src/simple_textured.slf +++ b/libraries/render-utils/src/simple_textured.slf @@ -14,7 +14,7 @@ <@include gpu/Color.slh@> <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> // the albedo texture uniform sampler2D originalTexture; diff --git a/libraries/render-utils/src/simple_textured_fade.slf b/libraries/render-utils/src/simple_textured_fade.slf index 025fe5fca6..2061cabdfc 100644 --- a/libraries/render-utils/src/simple_textured_fade.slf +++ b/libraries/render-utils/src/simple_textured_fade.slf @@ -14,7 +14,7 @@ <@include gpu/Color.slh@> <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include graphics/Material.slh@> <@include Fade.slh@> diff --git a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf index 981993615c..ad6918d727 100644 --- a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf +++ b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf @@ -12,7 +12,7 @@ <@include DeferredBufferRead.slh@> -<@include model/Light.slh@> +<@include graphics/Light.slh@> <$declareLightBuffer()$> <$declareDeferredCurvature()$> diff --git a/libraries/render-utils/src/zone_drawAmbient.slf b/libraries/render-utils/src/zone_drawAmbient.slf index f104e5be44..3407fe8467 100644 --- a/libraries/render-utils/src/zone_drawAmbient.slf +++ b/libraries/render-utils/src/zone_drawAmbient.slf @@ -10,7 +10,7 @@ // <@include zone_draw.slh@> -<@include model/Light.slh@> +<@include graphics/Light.slh@> <@include LightingModel.slh@> <$declareLightAmbientBuffer()$> diff --git a/libraries/render-utils/src/zone_drawKeyLight.slf b/libraries/render-utils/src/zone_drawKeyLight.slf index e96239b6dc..ea11c775b4 100644 --- a/libraries/render-utils/src/zone_drawKeyLight.slf +++ b/libraries/render-utils/src/zone_drawKeyLight.slf @@ -10,7 +10,7 @@ // <@include zone_draw.slh@> -<@include model/Light.slh@> +<@include graphics/Light.slh@> <@include LightingModel.slh@> <$declareLightBuffer()$> diff --git a/libraries/render/CMakeLists.txt b/libraries/render/CMakeLists.txt index 8fd05bd320..1d88c3e5f5 100644 --- a/libraries/render/CMakeLists.txt +++ b/libraries/render/CMakeLists.txt @@ -1,8 +1,8 @@ set(TARGET_NAME render) -AUTOSCRIBE_SHADER_LIB(gpu model) +AUTOSCRIBE_SHADER_LIB(gpu graphics) setup_hifi_library() # render needs octree only for getAccuracyAngle(float, int) -link_hifi_libraries(shared ktx gpu model octree) +link_hifi_libraries(shared ktx gpu graphics octree) target_nsight() diff --git a/libraries/render/src/render/Item.h b/libraries/render/src/render/Item.h index 77f5910b9e..e977c95fa0 100644 --- a/libraries/render/src/render/Item.h +++ b/libraries/render/src/render/Item.h @@ -25,7 +25,7 @@ #include "Args.h" -#include +#include #include "ShapePipeline.h" namespace render { diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index 87296b187f..478e4c4765 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -16,6 +16,6 @@ if (NOT ANDROID) endif () -link_hifi_libraries(shared networking octree gpu procedural model model-networking ktx recording avatars fbx entities controllers animation audio physics image midi) +link_hifi_libraries(shared networking octree gpu procedural graphics model-networking ktx recording avatars fbx entities controllers animation audio physics image midi) # ui includes gl, but link_hifi_libraries does not use transitive includes, so gl must be explicit include_hifi_library_headers(gl) diff --git a/libraries/script-engine/src/AssetScriptingInterface.cpp b/libraries/script-engine/src/AssetScriptingInterface.cpp index 25e8c0dcf3..e0e04a1e25 100644 --- a/libraries/script-engine/src/AssetScriptingInterface.cpp +++ b/libraries/script-engine/src/AssetScriptingInterface.cpp @@ -16,9 +16,11 @@ #include #include #include -#include #include +#include "ScriptEngineLogging.h" + + AssetScriptingInterface::AssetScriptingInterface(QScriptEngine* engine) : _engine(engine) { @@ -53,10 +55,32 @@ void AssetScriptingInterface::setMapping(QString path, QString hash, QScriptValu setMappingRequest->start(); } +void AssetScriptingInterface::getMapping(QString path, QScriptValue callback) { + auto request = DependencyManager::get()->createGetMappingRequest(path); + QObject::connect(request, &GetMappingRequest::finished, this, [=](GetMappingRequest* request) mutable { + auto result = request->getError(); + if (callback.isFunction()) { + if (result == GetMappingRequest::NotFound) { + QScriptValueList args { "", true }; + callback.call(_engine->currentContext()->thisObject(), args); + } else if (result == GetMappingRequest::NoError) { + QScriptValueList args { request->getHash(), true }; + callback.call(_engine->currentContext()->thisObject(), args); + } else { + qCDebug(scriptengine) << "error -- " << request->getError() << " -- " << request->getErrorString(); + QScriptValueList args { "", false }; + callback.call(_engine->currentContext()->thisObject(), args); + } + request->deleteLater(); + } + }); + request->start(); +} void AssetScriptingInterface::downloadData(QString urlString, QScriptValue callback) { if (!urlString.startsWith(ATP_SCHEME)) { + qCDebug(scriptengine) << "AssetScriptingInterface::downloadData url must be of form atp:"; return; } diff --git a/libraries/script-engine/src/AssetScriptingInterface.h b/libraries/script-engine/src/AssetScriptingInterface.h index 2812be65f9..dded2ef21d 100644 --- a/libraries/script-engine/src/AssetScriptingInterface.h +++ b/libraries/script-engine/src/AssetScriptingInterface.h @@ -75,7 +75,24 @@ public: * @param {string} error */ Q_INVOKABLE void setMapping(QString path, QString hash, QScriptValue callback); - + + /**jsdoc + * Look up a path to hash mapping within the connected domain's asset server + * @function Assets.getMapping + * @static + * @param path {string} + * @param callback {Assets~getMappingCallback} + */ + + /**jsdoc + * Called when getMapping is complete. + * @callback Assets~getMappingCallback + * @param assetID {string} hash value if found, else an empty string + * @param success {boolean} false for errors other than "not found", else true + */ + Q_INVOKABLE void getMapping(QString path, QScriptValue callback); + + Q_INVOKABLE void setBakingEnabled(QString path, bool enabled, QScriptValue callback); #if (PR_BUILD || DEV_BUILD) diff --git a/libraries/script-engine/src/ModelScriptingInterface.cpp b/libraries/script-engine/src/ModelScriptingInterface.cpp index e58afeaba8..c693083ebf 100644 --- a/libraries/script-engine/src/ModelScriptingInterface.cpp +++ b/libraries/script-engine/src/ModelScriptingInterface.cpp @@ -102,7 +102,7 @@ QScriptValue ModelScriptingInterface::appendMeshes(MeshProxyList in) { indexStartOffset += numVertices; } - model::MeshPointer result(new model::Mesh()); + graphics::MeshPointer result(new graphics::Mesh()); gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ); gpu::Buffer* combinedVertexBuffer = new gpu::Buffer(combinedVertexSize, combinedVertexData.get()); @@ -130,12 +130,12 @@ QScriptValue ModelScriptingInterface::appendMeshes(MeshProxyList in) { gpu::BufferView combinedIndexesBufferView(combinedIndexesBufferPointer, indexElement); result->setIndexBuffer(combinedIndexesBufferView); - std::vector parts; - parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex - (model::Index)result->getNumIndices(), // numIndices - (model::Index)0, // baseVertex - model::Mesh::TRIANGLES)); // topology - result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), + std::vector parts; + parts.emplace_back(graphics::Mesh::Part((graphics::Index)0, // startIndex + (graphics::Index)result->getNumIndices(), // numIndices + (graphics::Index)0, // baseVertex + graphics::Mesh::TRIANGLES)); // topology + result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); @@ -153,7 +153,7 @@ QScriptValue ModelScriptingInterface::transformMesh(glm::mat4 transform, MeshPro } const auto inverseTransposeTransform = glm::inverse(glm::transpose(transform)); - model::MeshPointer result = mesh->map([&](glm::vec3 position){ return glm::vec3(transform * glm::vec4(position, 1.0f)); }, + graphics::MeshPointer result = mesh->map([&](glm::vec3 position){ return glm::vec3(transform * glm::vec4(position, 1.0f)); }, [&](glm::vec3 color){ return color; }, [&](glm::vec3 normal){ return glm::vec3(inverseTransposeTransform * glm::vec4(normal, 0.0f)); }, [&](uint32_t index){ return index; }); @@ -199,7 +199,7 @@ QScriptValue ModelScriptingInterface::getVertex(MeshProxy* meshProxy, int vertex QScriptValue ModelScriptingInterface::newMesh(const QVector& vertices, const QVector& normals, const QVector& faces) { - model::MeshPointer mesh(new model::Mesh()); + graphics::MeshPointer mesh(new graphics::Mesh()); // vertices auto vertexBuffer = std::make_shared(vertices.size() * sizeof(glm::vec3), (gpu::Byte*)vertices.data()); @@ -236,12 +236,12 @@ QScriptValue ModelScriptingInterface::newMesh(const QVector& vertices mesh->setIndexBuffer(indexBufferView); // parts - std::vector parts; - parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex - (model::Index)faces.size() * 3, // numIndices - (model::Index)0, // baseVertex - model::Mesh::TRIANGLES)); // topology - mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), + std::vector parts; + parts.emplace_back(graphics::Mesh::Part((graphics::Index)0, // startIndex + (graphics::Index)faces.size() * 3, // numIndices + (graphics::Index)0, // baseVertex + graphics::Mesh::TRIANGLES)); // topology + mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp index 3883b948df..7b36b815fb 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.cpp +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -112,17 +112,17 @@ bool SceneScripting::Stage::isSunModelEnabled() const { void SceneScripting::Stage::setBackgroundMode(const QString& mode) { if (mode == QString("inherit")) { - _skyStage->setBackgroundMode(model::SunSkyStage::NO_BACKGROUND); + _skyStage->setBackgroundMode(graphics::SunSkyStage::NO_BACKGROUND); } else if (mode == QString("skybox")) { - _skyStage->setBackgroundMode(model::SunSkyStage::SKY_BOX); + _skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_BOX); } } QString SceneScripting::Stage::getBackgroundMode() const { switch (_skyStage->getBackgroundMode()) { - case model::SunSkyStage::NO_BACKGROUND: + case graphics::SunSkyStage::NO_BACKGROUND: return QString("inherit"); - case model::SunSkyStage::SKY_BOX: + case graphics::SunSkyStage::SKY_BOX: return QString("skybox"); default: return QString("inherit"); @@ -131,7 +131,7 @@ QString SceneScripting::Stage::getBackgroundMode() const { SceneScriptingInterface::SceneScriptingInterface() : _stage{ new SceneScripting::Stage{ _skyStage } } { // Let's make sure the sunSkyStage is using a proceduralSkybox - _skyStage->setSkybox(model::SkyboxPointer(new ProceduralSkybox())); + _skyStage->setSkybox(graphics::SkyboxPointer(new ProceduralSkybox())); } void SceneScriptingInterface::setShouldRenderAvatars(bool shouldRenderAvatars) { @@ -148,6 +148,6 @@ void SceneScriptingInterface::setShouldRenderEntities(bool shouldRenderEntities) } } -model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const { +graphics::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const { return _skyStage; } diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 7bc22eb3e6..07b8c22ca6 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -15,7 +15,7 @@ #include // QObject #include // Dependency -#include "model/Stage.h" +#include "graphics/Stage.h" // TODO: if QT moc ever supports nested classes, subclass these to the interface instead of namespacing namespace SceneScripting { @@ -23,7 +23,7 @@ namespace SceneScripting { Q_OBJECT public: - Location(model::SunSkyStagePointer skyStage) : _skyStage{ skyStage } {} + Location(graphics::SunSkyStagePointer skyStage) : _skyStage{ skyStage } {} Q_PROPERTY(float longitude READ getLongitude WRITE setLongitude) Q_PROPERTY(float latitude READ getLatitude WRITE setLatitude) @@ -37,7 +37,7 @@ namespace SceneScripting { void setAltitude(float altitude); protected: - model::SunSkyStagePointer _skyStage; + graphics::SunSkyStagePointer _skyStage; }; using LocationPointer = std::unique_ptr; @@ -45,7 +45,7 @@ namespace SceneScripting { Q_OBJECT public: - Time(model::SunSkyStagePointer skyStage) : _skyStage{ skyStage } {} + Time(graphics::SunSkyStagePointer skyStage) : _skyStage{ skyStage } {} Q_PROPERTY(float hour READ getHour WRITE setHour) Q_PROPERTY(int day READ getDay WRITE setDay) @@ -56,7 +56,7 @@ namespace SceneScripting { void setDay(int day); protected: - model::SunSkyStagePointer _skyStage; + graphics::SunSkyStagePointer _skyStage; }; using TimePointer = std::unique_ptr