From 5046f4c1acad0464da474de69ab128bea1fa5eb4 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 6 Jul 2015 13:19:42 -0700 Subject: [PATCH 01/49] Update upgrade dialog - Strip out "
"s - Show information for all new versions since current, not just latest - Display scrollbar if content too long to show all at once - "version" / "versions" behind depending on if one or more - Align buttons with heading and text - Darken text so that is more readable --- interface/resources/qml/UpdateDialog.qml | 31 ++++++++++++------------ interface/src/ui/UpdateDialog.cpp | 18 +++++++++++--- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/interface/resources/qml/UpdateDialog.qml b/interface/resources/qml/UpdateDialog.qml index e5216ff619..5d901002f7 100644 --- a/interface/resources/qml/UpdateDialog.qml +++ b/interface/resources/qml/UpdateDialog.qml @@ -1,5 +1,6 @@ import Hifi 1.0 import QtQuick 2.3 +import QtQuick.Controls 1.3 import QtQuick.Controls.Styles 1.3 import QtGraphicalEffects 1.0 import "controls" @@ -85,33 +86,31 @@ DialogContainer { } } - Flickable { + ScrollView { id: scrollArea anchors { top: dialogTitle.bottom + topMargin: updateDialog.closeMargin + left: dialogTitle.left } - contentWidth: updateDialog.inputWidth - contentHeight: backgroundRectangle.height - (dialogTitle.height * 2.5) width: updateDialog.inputWidth - height: backgroundRectangle.height - (dialogTitle.height * 2.5) - flickableDirection: Flickable.VerticalFlick - clip: true - - TextEdit { + height: backgroundRectangle.height - (dialogTitle.height * 2.5) - updateDialog.closeMargin + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + verticalScrollBarPolicy: Qt.ScrollBarAsNeeded + + Text { id: releaseNotes - wrapMode: TextEdit.Wrap - width: parent.width - readOnly: true + wrapMode: Text.Wrap + width: parent.width - updateDialog.closeMargin text: updateDialog.releaseNotes font.pixelSize: 14 - color: hifi.colors.text + color: "#000000" anchors { left: parent.left - leftMargin: updateDialog.borderWidth } } } - + Rectangle { id: downloadButton width: updateDialog.buttonWidth @@ -122,7 +121,7 @@ DialogContainer { top: scrollArea.bottom topMargin: 10 right: backgroundRectangle.right - rightMargin: 15 + rightMargin: updateDialog.borderWidth } Text { text: "Upgrade" @@ -169,4 +168,4 @@ DialogContainer { } } } -} \ No newline at end of file +} diff --git a/interface/src/ui/UpdateDialog.cpp b/interface/src/ui/UpdateDialog.cpp index 69dfc343d9..12ac6dfd6c 100644 --- a/interface/src/ui/UpdateDialog.cpp +++ b/interface/src/ui/UpdateDialog.cpp @@ -24,9 +24,21 @@ UpdateDialog::UpdateDialog(QQuickItem* parent) : int currentVersion = QCoreApplication::applicationVersion().toInt(); int latestVersion = applicationUpdater.data()->getBuildData().lastKey(); int versionsBehind = latestVersion - currentVersion; - _updateAvailableDetails = "v" + QString::number(latestVersion) + " released on " + applicationUpdater.data()->getBuildData()[latestVersion]["releaseTime"]; - _updateAvailableDetails += "\nYou are " + QString::number(versionsBehind) + " versions behind"; - _releaseNotes = applicationUpdater.data()->getBuildData()[latestVersion]["releaseNotes"]; + _updateAvailableDetails = "v" + QString::number(latestVersion) + " released on " + + applicationUpdater.data()->getBuildData()[latestVersion]["releaseTime"]; + _updateAvailableDetails += "\nYou are " + QString::number(versionsBehind) + " version" + + (versionsBehind > 1 ? "s" : "") + " behind"; + + _releaseNotes = ""; + for (int i = latestVersion; i > currentVersion; i--) { + QString releaseNotes = applicationUpdater.data()->getBuildData()[i]["releaseNotes"]; + releaseNotes.remove("
"); + releaseNotes.remove(QRegExp("^\n")); + _releaseNotes += releaseNotes; + if (i > currentVersion + 1) { + _releaseNotes += "\n\n"; + } + } } const QString& UpdateDialog::updateAvailableDetails() const { From 46e58cd1064b8fec3630a32782390e73bdcf378b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 7 Jul 2015 13:56:47 -0700 Subject: [PATCH 02/49] Rework dialog container and layout --- interface/resources/qml/UpdateDialog.qml | 171 +++++++++++------------ 1 file changed, 78 insertions(+), 93 deletions(-) diff --git a/interface/resources/qml/UpdateDialog.qml b/interface/resources/qml/UpdateDialog.qml index 5d901002f7..f0188d5221 100644 --- a/interface/resources/qml/UpdateDialog.qml +++ b/interface/resources/qml/UpdateDialog.qml @@ -7,11 +7,14 @@ import "controls" import "styles" DialogContainer { - HifiConstants { id: hifi } id: root + HifiConstants { id: hifi } + objectName: "UpdateDialog" - implicitWidth: updateDialog.width - implicitHeight: updateDialog.height + + implicitWidth: updateDialog.implicitWidth + implicitHeight: updateDialog.implicitHeight + x: parent ? parent.width / 2 - width / 2 : 0 y: parent ? parent.height / 2 - height / 2 : 0 @@ -33,6 +36,16 @@ DialogContainer { signal triggerBuildDownload signal closeUpdateDialog + Rectangle { + id: backgroundRectangle + color: "#2c86b1" + opacity: 0.85 + radius: updateDialog.closeMargin * 2 + + width: updateDialog.inputWidth + updateDialog.borderWidth * 2 + height: updateDialog.inputHeight * 6 + updateDialog.closeMargin * 2 + } + Column { id: mainContent width: updateDialog.inputWidth @@ -43,72 +56,76 @@ DialogContainer { } Rectangle { - id: backgroundRectangle - color: "#2c86b1" - opacity: 0.85 - radius: updateDialog.closeMargin * 2 - - width: updateDialog.inputWidth + updateDialog.borderWidth * 2 - height: updateDialog.inputHeight * 6 + updateDialog.closeMargin * 2 - - Rectangle { - id: dialogTitle - width: updateDialog.inputWidth - height: updateDialog.inputHeight - radius: height / 2 - color: "#ebebeb" - + id: dialogTitle + width: updateDialog.inputWidth + height: updateDialog.inputHeight + radius: height / 2 + color: "#ebebeb" + + Text { + id: updateAvailableText + text: "Update Available" anchors { - top: parent.top - topMargin: updateDialog.inputSpacing - horizontalCenter: parent.horizontalCenter - } - - Text { - id: updateAvailableText - text: "Update Available" - anchors { - verticalCenter: parent.verticalCenter - left: parent.left - leftMargin: updateDialog.inputSpacing - } - } - - Text { - text: updateDialog.updateAvailableDetails - font.pixelSize: 14 - color: hifi.colors.text - anchors { - verticalCenter: parent.verticalCenter - left: updateAvailableText.right - leftMargin: 13 - } + verticalCenter: parent.verticalCenter + left: parent.left + leftMargin: updateDialog.inputSpacing } } - - ScrollView { - id: scrollArea + + Text { + text: updateDialog.updateAvailableDetails + font.pixelSize: 14 + color: hifi.colors.text anchors { - top: dialogTitle.bottom - topMargin: updateDialog.closeMargin - left: dialogTitle.left + verticalCenter: parent.verticalCenter + left: updateAvailableText.right + leftMargin: 13 } - width: updateDialog.inputWidth - height: backgroundRectangle.height - (dialogTitle.height * 2.5) - updateDialog.closeMargin - horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff - verticalScrollBarPolicy: Qt.ScrollBarAsNeeded + } + } + + ScrollView { + id: scrollArea + width: updateDialog.inputWidth + height: backgroundRectangle.height - (dialogTitle.height * 2.5) - updateDialog.closeMargin + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + verticalScrollBarPolicy: Qt.ScrollBarAsNeeded + + Text { + id: releaseNotes + wrapMode: Text.Wrap + width: parent.width - updateDialog.closeMargin + text: updateDialog.releaseNotes + font.pixelSize: 14 + color: "#000000" + } + } + + Row { + anchors.right: parent.right + spacing: updateDialog.inputSpacing + + Rectangle { + id: cancelButton + width: updateDialog.buttonWidth + height: updateDialog.buttonHeight + radius: updateDialog.buttonRadius + color: "red" Text { - id: releaseNotes - wrapMode: Text.Wrap - width: parent.width - updateDialog.closeMargin - text: updateDialog.releaseNotes - font.pixelSize: 14 - color: "#000000" + text: "Cancel" anchors { - left: parent.left + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter } } + + MouseArea { + id: cancelButtonAction + anchors.fill: parent + onClicked: updateDialog.closeDialog() + cursorShape: "PointingHandCursor" + } } Rectangle { @@ -117,12 +134,7 @@ DialogContainer { height: updateDialog.buttonHeight radius: updateDialog.buttonRadius color: "green" - anchors { - top: scrollArea.bottom - topMargin: 10 - right: backgroundRectangle.right - rightMargin: updateDialog.borderWidth - } + Text { text: "Upgrade" anchors { @@ -130,6 +142,7 @@ DialogContainer { horizontalCenter: parent.horizontalCenter } } + MouseArea { id: downloadButtonAction anchors.fill: parent @@ -137,34 +150,6 @@ DialogContainer { cursorShape: "PointingHandCursor" } } - - Rectangle { - id: cancelButton - width: updateDialog.buttonWidth - height: updateDialog.buttonHeight - radius: updateDialog.buttonRadius - color: "red" - anchors { - top: scrollArea.bottom - topMargin: 10 - right: downloadButton.left - rightMargin: 15 - } - - Text { - text: "Cancel" - anchors { - verticalCenter: parent.verticalCenter - horizontalCenter: parent.horizontalCenter - } - } - MouseArea { - id: cancelButtonAction - anchors.fill: parent - onClicked: updateDialog.closeDialog() - cursorShape: "PointingHandCursor" - } - } } } } From 085d87e0352ba10c23bb90d4f0e2bfc0fb124696 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 7 Jul 2015 14:16:45 -0700 Subject: [PATCH 03/49] Make background squared, white, and dragable --- interface/resources/qml/UpdateDialog.qml | 28 ++++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/UpdateDialog.qml b/interface/resources/qml/UpdateDialog.qml index f0188d5221..3f5036c6cc 100644 --- a/interface/resources/qml/UpdateDialog.qml +++ b/interface/resources/qml/UpdateDialog.qml @@ -17,7 +17,9 @@ DialogContainer { x: parent ? parent.width / 2 - width / 2 : 0 y: parent ? parent.height / 2 - height / 2 : 0 - + property int maximumX: parent ? parent.width - width : 0 + property int maximumY: parent ? parent.height - height : 0 + UpdateDialog { id: updateDialog @@ -32,18 +34,32 @@ DialogContainer { readonly property int buttonWidth: 150 readonly property int buttonHeight: 50 readonly property int buttonRadius: 15 - + signal triggerBuildDownload signal closeUpdateDialog Rectangle { id: backgroundRectangle - color: "#2c86b1" - opacity: 0.85 - radius: updateDialog.closeMargin * 2 + color: "#ffffff" width: updateDialog.inputWidth + updateDialog.borderWidth * 2 height: updateDialog.inputHeight * 6 + updateDialog.closeMargin * 2 + + MouseArea { + width: parent.width + height: parent.height + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } + drag { + target: root + minimumX: 0 + minimumY: 0 + maximumX: root.parent ? root.maximumX : 0 + maximumY: root.parent ? root.maximumY : 0 + } + } } Column { @@ -59,8 +75,6 @@ DialogContainer { id: dialogTitle width: updateDialog.inputWidth height: updateDialog.inputHeight - radius: height / 2 - color: "#ebebeb" Text { id: updateAvailableText From 0994cd97dc5767c9f1a3cf8abe3abacb47cfe6ab Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 7 Jul 2015 15:14:15 -0700 Subject: [PATCH 04/49] Rework header and add logo Use HiFi logo as placeholder for now until Interface SVG is available. --- interface/resources/qml/UpdateDialog.qml | 44 ++++++++++++++---------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/interface/resources/qml/UpdateDialog.qml b/interface/resources/qml/UpdateDialog.qml index 3f5036c6cc..2c5d1e74a9 100644 --- a/interface/resources/qml/UpdateDialog.qml +++ b/interface/resources/qml/UpdateDialog.qml @@ -26,14 +26,15 @@ DialogContainer { implicitWidth: backgroundRectangle.width implicitHeight: backgroundRectangle.height - readonly property int inputWidth: 500 - readonly property int inputHeight: 60 + readonly property int contentWidth: 500 + readonly property int logoSize: 60 readonly property int borderWidth: 30 readonly property int closeMargin: 16 readonly property int inputSpacing: 16 readonly property int buttonWidth: 150 readonly property int buttonHeight: 50 readonly property int buttonRadius: 15 + readonly property int noticeHeight: 15 * inputSpacing signal triggerBuildDownload signal closeUpdateDialog @@ -42,8 +43,8 @@ DialogContainer { id: backgroundRectangle color: "#ffffff" - width: updateDialog.inputWidth + updateDialog.borderWidth * 2 - height: updateDialog.inputHeight * 6 + updateDialog.closeMargin * 2 + width: updateDialog.contentWidth + updateDialog.borderWidth * 2 + height: mainContent.height + updateDialog.borderWidth * 2 MouseArea { width: parent.width @@ -62,9 +63,20 @@ DialogContainer { } } + Image { + id: logo + source: "../images/hifi-logo.svg" + width: updateDialog.logoSize + height: updateDialog.logoSize + anchors { + top: mainContent.top + right: mainContent.right + } + } + Column { id: mainContent - width: updateDialog.inputWidth + width: updateDialog.contentWidth spacing: updateDialog.inputSpacing anchors { horizontalCenter: parent.horizontalCenter @@ -72,36 +84,30 @@ DialogContainer { } Rectangle { - id: dialogTitle - width: updateDialog.inputWidth - height: updateDialog.inputHeight + id: header + width: parent.width - updateDialog.logoSize - updateDialog.inputSpacing + height: updateAvailable.height + versionDetails.height Text { - id: updateAvailableText + id: updateAvailable text: "Update Available" - anchors { - verticalCenter: parent.verticalCenter - left: parent.left - leftMargin: updateDialog.inputSpacing - } } Text { + id: versionDetails text: updateDialog.updateAvailableDetails font.pixelSize: 14 color: hifi.colors.text anchors { - verticalCenter: parent.verticalCenter - left: updateAvailableText.right - leftMargin: 13 + top: updateAvailable.bottom } } } ScrollView { id: scrollArea - width: updateDialog.inputWidth - height: backgroundRectangle.height - (dialogTitle.height * 2.5) - updateDialog.closeMargin + width: parent.width + height: updateDialog.noticeHeight horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff verticalScrollBarPolicy: Qt.ScrollBarAsNeeded From 98cd706528aafac5372582fd8d1439fb4a16f529 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 7 Jul 2015 15:48:39 -0700 Subject: [PATCH 05/49] Add border around update details --- interface/resources/qml/UpdateDialog.qml | 31 ++++++++++++++++-------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/UpdateDialog.qml b/interface/resources/qml/UpdateDialog.qml index 2c5d1e74a9..55468ff6ba 100644 --- a/interface/resources/qml/UpdateDialog.qml +++ b/interface/resources/qml/UpdateDialog.qml @@ -104,20 +104,31 @@ DialogContainer { } } - ScrollView { - id: scrollArea + Rectangle { width: parent.width height: updateDialog.noticeHeight - horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff - verticalScrollBarPolicy: Qt.ScrollBarAsNeeded - Text { - id: releaseNotes - wrapMode: Text.Wrap + border { + width: 1 + color: "#808080" + } + + ScrollView { + id: scrollArea width: parent.width - updateDialog.closeMargin - text: updateDialog.releaseNotes - font.pixelSize: 14 - color: "#000000" + height: parent.height + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + verticalScrollBarPolicy: Qt.ScrollBarAsNeeded + anchors.right: parent.right + + Text { + id: releaseNotes + wrapMode: Text.Wrap + width: parent.width - updateDialog.closeMargin + text: updateDialog.releaseNotes + font.pixelSize: 14 + color: "#000000" + } } } From 1774ad9c534faf7e263876176a27713d0918327f Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 7 Jul 2015 15:59:34 -0700 Subject: [PATCH 06/49] Rework buttons --- interface/resources/qml/UpdateDialog.qml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/UpdateDialog.qml b/interface/resources/qml/UpdateDialog.qml index 55468ff6ba..c17cf5d5d9 100644 --- a/interface/resources/qml/UpdateDialog.qml +++ b/interface/resources/qml/UpdateDialog.qml @@ -31,9 +31,8 @@ DialogContainer { readonly property int borderWidth: 30 readonly property int closeMargin: 16 readonly property int inputSpacing: 16 - readonly property int buttonWidth: 150 - readonly property int buttonHeight: 50 - readonly property int buttonRadius: 15 + readonly property int buttonWidth: 100 + readonly property int buttonHeight: 30 readonly property int noticeHeight: 15 * inputSpacing signal triggerBuildDownload @@ -140,11 +139,10 @@ DialogContainer { id: cancelButton width: updateDialog.buttonWidth height: updateDialog.buttonHeight - radius: updateDialog.buttonRadius - color: "red" Text { text: "Cancel" + font.weight: Font.DemiBold anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter @@ -160,14 +158,13 @@ DialogContainer { } Rectangle { - id: downloadButton + id: updateButton width: updateDialog.buttonWidth height: updateDialog.buttonHeight - radius: updateDialog.buttonRadius - color: "green" Text { - text: "Upgrade" + text: "Update" + font.weight: Font.DemiBold anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter @@ -175,7 +172,7 @@ DialogContainer { } MouseArea { - id: downloadButtonAction + id: updateButtonAction anchors.fill: parent onClicked: updateDialog.triggerUpgrade() cursorShape: "PointingHandCursor" From cd258262d29a244dd0661cfbc0d07f9a9dade1f7 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 7 Jul 2015 16:21:24 -0700 Subject: [PATCH 07/49] Use proper Interface logo --- interface/resources/images/interface-logo.svg | 34 +++++++++++++++++++ interface/resources/qml/UpdateDialog.qml | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 interface/resources/images/interface-logo.svg diff --git a/interface/resources/images/interface-logo.svg b/interface/resources/images/interface-logo.svg new file mode 100644 index 0000000000..61fc9d9afb --- /dev/null +++ b/interface/resources/images/interface-logo.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/interface/resources/qml/UpdateDialog.qml b/interface/resources/qml/UpdateDialog.qml index c17cf5d5d9..9ddc974ddd 100644 --- a/interface/resources/qml/UpdateDialog.qml +++ b/interface/resources/qml/UpdateDialog.qml @@ -64,7 +64,7 @@ DialogContainer { Image { id: logo - source: "../images/hifi-logo.svg" + source: "../images/interface-logo.svg" width: updateDialog.logoSize height: updateDialog.logoSize anchors { From b123e280d6a015e077c6fe048d91342d87d9acb9 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 7 Jul 2015 16:22:01 -0700 Subject: [PATCH 08/49] Add release numbers to associated text --- interface/src/ui/UpdateDialog.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/UpdateDialog.cpp b/interface/src/ui/UpdateDialog.cpp index 12ac6dfd6c..839553fa06 100644 --- a/interface/src/ui/UpdateDialog.cpp +++ b/interface/src/ui/UpdateDialog.cpp @@ -33,11 +33,8 @@ UpdateDialog::UpdateDialog(QQuickItem* parent) : for (int i = latestVersion; i > currentVersion; i--) { QString releaseNotes = applicationUpdater.data()->getBuildData()[i]["releaseNotes"]; releaseNotes.remove("
"); - releaseNotes.remove(QRegExp("^\n")); - _releaseNotes += releaseNotes; - if (i > currentVersion + 1) { - _releaseNotes += "\n\n"; - } + releaseNotes.remove(QRegExp("^\n+")); + _releaseNotes += "\n" + QString().sprintf("%d", i) + "\n" + releaseNotes + "\n"; } } From abc54f2e3f7f74b5b94df5d05f1fad8ceaa2c9b3 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 7 Jul 2015 17:08:02 -0700 Subject: [PATCH 09/49] Polished fonts, colors, etc. --- interface/resources/qml/LoginDialog.qml | 2 -- interface/resources/qml/UpdateDialog.qml | 36 ++++++++++++++++++++---- interface/src/ui/UpdateDialog.cpp | 4 +-- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/LoginDialog.qml b/interface/resources/qml/LoginDialog.qml index 8d5267f7f8..29264fa608 100644 --- a/interface/resources/qml/LoginDialog.qml +++ b/interface/resources/qml/LoginDialog.qml @@ -41,8 +41,6 @@ DialogContainer { readonly property int closeMargin: 16 readonly property real tan30: 0.577 // tan(30°) readonly property int inputSpacing: 16 - property int maximumX: parent ? parent.width - width : 0 - property int maximumY: parent ? parent.height - height : 0 Rectangle { id: backgroundRectangle diff --git a/interface/resources/qml/UpdateDialog.qml b/interface/resources/qml/UpdateDialog.qml index 9ddc974ddd..948d2555a3 100644 --- a/interface/resources/qml/UpdateDialog.qml +++ b/interface/resources/qml/UpdateDialog.qml @@ -34,6 +34,7 @@ DialogContainer { readonly property int buttonWidth: 100 readonly property int buttonHeight: 30 readonly property int noticeHeight: 15 * inputSpacing + readonly property string fontFamily: "Futura" signal triggerBuildDownload signal closeUpdateDialog @@ -90,12 +91,22 @@ DialogContainer { Text { id: updateAvailable text: "Update Available" + font { + family: updateDialog.fontFamily + pixelSize: hifi.fonts.pixelSize * 1.5 + weight: Font.DemiBold + } + color: "#303030" } Text { id: versionDetails text: updateDialog.updateAvailableDetails - font.pixelSize: 14 + font { + family: updateDialog.fontFamily + pixelSize: hifi.fonts.pixelSize * 0.6 + letterSpacing: -0.5 + } color: hifi.colors.text anchors { top: updateAvailable.bottom @@ -109,7 +120,7 @@ DialogContainer { border { width: 1 - color: "#808080" + color: "#a0a0a0" } ScrollView { @@ -125,8 +136,11 @@ DialogContainer { wrapMode: Text.Wrap width: parent.width - updateDialog.closeMargin text: updateDialog.releaseNotes - font.pixelSize: 14 - color: "#000000" + color: hifi.colors.text + font { + family: updateDialog.fontFamily + pixelSize: hifi.fonts.pixelSize * 0.7 + } } } } @@ -142,7 +156,12 @@ DialogContainer { Text { text: "Cancel" - font.weight: Font.DemiBold + color: "#0c9ab4" // Same as logo + font { + family: updateDialog.fontFamily + pixelSize: hifi.fonts.pixelSize * 1.2 + weight: Font.DemiBold + } anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter @@ -164,7 +183,12 @@ DialogContainer { Text { text: "Update" - font.weight: Font.DemiBold + color: "#0c9ab4" // Same as logo + font { + family: updateDialog.fontFamily + pixelSize: hifi.fonts.pixelSize * 1.2 + weight: Font.DemiBold + } anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter diff --git a/interface/src/ui/UpdateDialog.cpp b/interface/src/ui/UpdateDialog.cpp index 839553fa06..6fa2d858fb 100644 --- a/interface/src/ui/UpdateDialog.cpp +++ b/interface/src/ui/UpdateDialog.cpp @@ -24,8 +24,8 @@ UpdateDialog::UpdateDialog(QQuickItem* parent) : int currentVersion = QCoreApplication::applicationVersion().toInt(); int latestVersion = applicationUpdater.data()->getBuildData().lastKey(); int versionsBehind = latestVersion - currentVersion; - _updateAvailableDetails = "v" + QString::number(latestVersion) + " released on " - + applicationUpdater.data()->getBuildData()[latestVersion]["releaseTime"]; + _updateAvailableDetails = "v" + QString::number(latestVersion) + " released on " + + QString(applicationUpdater.data()->getBuildData()[latestVersion]["releaseTime"]).replace(" ", " "); _updateAvailableDetails += "\nYou are " + QString::number(versionsBehind) + " version" + (versionsBehind > 1 ? "s" : "") + " behind"; From db7f1d6d273611c3017288694fb2a229ecafa7b9 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 9 Jul 2015 09:35:22 -0700 Subject: [PATCH 10/49] Change font to Trebuchet --- interface/resources/qml/UpdateDialog.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/UpdateDialog.qml b/interface/resources/qml/UpdateDialog.qml index 948d2555a3..b166bdfebb 100644 --- a/interface/resources/qml/UpdateDialog.qml +++ b/interface/resources/qml/UpdateDialog.qml @@ -34,7 +34,7 @@ DialogContainer { readonly property int buttonWidth: 100 readonly property int buttonHeight: 30 readonly property int noticeHeight: 15 * inputSpacing - readonly property string fontFamily: "Futura" + readonly property string fontFamily: Qt.platform.os === "windows" ? "Trebuchet MS" : "Trebuchet" signal triggerBuildDownload signal closeUpdateDialog @@ -139,7 +139,7 @@ DialogContainer { color: hifi.colors.text font { family: updateDialog.fontFamily - pixelSize: hifi.fonts.pixelSize * 0.7 + pixelSize: hifi.fonts.pixelSize * 0.65 } } } From daf34053a8ad044cac69b77f31f4e287adfa5be8 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 9 Jul 2015 10:15:28 -0700 Subject: [PATCH 11/49] Tweak button positions --- interface/resources/qml/UpdateDialog.qml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/UpdateDialog.qml b/interface/resources/qml/UpdateDialog.qml index b166bdfebb..8baf41cd75 100644 --- a/interface/resources/qml/UpdateDialog.qml +++ b/interface/resources/qml/UpdateDialog.qml @@ -44,7 +44,7 @@ DialogContainer { color: "#ffffff" width: updateDialog.contentWidth + updateDialog.borderWidth * 2 - height: mainContent.height + updateDialog.borderWidth * 2 + height: mainContent.height + updateDialog.borderWidth * 2 - updateDialog.closeMargin / 2 MouseArea { width: parent.width @@ -80,7 +80,8 @@ DialogContainer { spacing: updateDialog.inputSpacing anchors { horizontalCenter: parent.horizontalCenter - verticalCenter: parent.verticalCenter + topMargin: updateDialog.borderWidth + top: parent.top } Rectangle { @@ -148,11 +149,13 @@ DialogContainer { Row { anchors.right: parent.right spacing: updateDialog.inputSpacing + height: updateDialog.buttonHeight + updateDialog.closeMargin / 2 Rectangle { id: cancelButton width: updateDialog.buttonWidth height: updateDialog.buttonHeight + anchors.bottom: parent.bottom Text { text: "Cancel" @@ -180,6 +183,7 @@ DialogContainer { id: updateButton width: updateDialog.buttonWidth height: updateDialog.buttonHeight + anchors.bottom: parent.bottom Text { text: "Update" From 7fc9fd97ff11076fd0b4e75e4cb1282f499be759 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 10 Jul 2015 11:03:12 -0700 Subject: [PATCH 12/49] Replacing setUniformTexture by setResourceTexture in order to differenciate the 2 types of binding points for the BUffers. --- interface/src/avatar/Avatar.cpp | 2 +- interface/src/ui/ApplicationCompositor.cpp | 2 +- interface/src/ui/ApplicationOverlay.cpp | 2 +- .../src/ui/overlays/BillboardOverlay.cpp | 4 +-- .../RenderableParticleEffectEntityItem.cpp | 2 +- libraries/gpu/src/gpu/Batch.cpp | 8 +++--- libraries/gpu/src/gpu/Batch.h | 6 ++-- libraries/gpu/src/gpu/GLBackend.cpp | 2 +- libraries/gpu/src/gpu/GLBackend.h | 2 +- libraries/gpu/src/gpu/GLBackendPipeline.cpp | 2 +- libraries/model/src/model/Skybox.cpp | 2 +- .../src/DeferredLightingEffect.cpp | 28 +++++++++---------- libraries/render-utils/src/Model.cpp | 10 +++---- .../render-utils/src/RenderDeferredTask.cpp | 2 +- libraries/render-utils/src/TextRenderer3D.cpp | 2 +- 15 files changed, 38 insertions(+), 38 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 3d4c158a0b..0dde96c7ce 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -644,7 +644,7 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) { glm::vec2 texCoordBottomRight(1.0f, 1.0f); gpu::Batch& batch = *renderArgs->_batch; - batch.setUniformTexture(0, _billboardTexture->getGPUTexture()); + batch.setResourceTexture(0, _billboardTexture->getGPUTexture()); DependencyManager::get()->bindSimpleProgram(batch, true); DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index dafa332d53..a1420e3b6a 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -179,7 +179,7 @@ void ApplicationCompositor::bindCursorTexture(gpu::Batch& batch, uint8_t cursorI _cursors[iconId] = DependencyManager::get()-> getImageTexture(iconPath); } - batch.setUniformTexture(0, _cursors[iconId]); + batch.setResourceTexture(0, _cursors[iconId]); } // Draws the FBO texture for the screen diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index e7d220893f..4c3d082bdb 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -196,7 +196,7 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder(RenderArgs* renderAr geometryCache->useSimpleDrawPipeline(batch); batch.setProjectionTransform(mat4()); batch.setModelTransform(mat4()); - batch.setUniformTexture(0, DependencyManager::get()->getWhiteTexture()); + batch.setResourceTexture(0, DependencyManager::get()->getWhiteTexture()); batch._glLineWidth(CONNECTION_STATUS_BORDER_LINE_WIDTH); // TODO animate the disconnect border for some excitement while not connected? diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index 988223765a..1bf4f2a9c7 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -87,12 +87,12 @@ void BillboardOverlay::render(RenderArgs* args) { transform.postScale(glm::vec3(getDimensions(), 1.0f)); batch->setModelTransform(transform); - batch->setUniformTexture(0, _texture->getGPUTexture()); + batch->setResourceTexture(0, _texture->getGPUTexture()); DependencyManager::get()->renderQuad(*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)); - batch->setUniformTexture(0, args->_whiteTexture); // restore default white color after me + batch->setResourceTexture(0, args->_whiteTexture); // restore default white color after me } } diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index d00728a9eb..2eb95d1bef 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -50,7 +50,7 @@ void RenderableParticleEffectEntityItem::render(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; if (textured) { - batch.setUniformTexture(0, _texture->getGPUTexture()); + batch.setResourceTexture(0, _texture->getGPUTexture()); } batch.setModelTransform(getTransformToCenter()); DependencyManager::get()->bindSimpleProgram(batch, textured); diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index b3e6b6117d..b643ba66b8 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -227,15 +227,15 @@ void Batch::setUniformBuffer(uint32 slot, const BufferView& view) { } -void Batch::setUniformTexture(uint32 slot, const TexturePointer& texture) { - ADD_COMMAND(setUniformTexture); +void Batch::setResourceTexture(uint32 slot, const TexturePointer& texture) { + ADD_COMMAND(setResourceTexture); _params.push_back(_textures.cache(texture)); _params.push_back(slot); } -void Batch::setUniformTexture(uint32 slot, const TextureView& view) { - setUniformTexture(slot, view._texture); +void Batch::setResourceTexture(uint32 slot, const TextureView& view) { + setResourceTexture(slot, view._texture); } void Batch::setFramebuffer(const FramebufferPointer& framebuffer) { diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 0cc1a6bee3..6841edb3ef 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -102,8 +102,8 @@ public: void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size); void setUniformBuffer(uint32 slot, const BufferView& view); // not a command, just a shortcut from a BufferView - void setUniformTexture(uint32 slot, const TexturePointer& view); - void setUniformTexture(uint32 slot, const TextureView& view); // not a command, just a shortcut from a TextureView + void setResourceTexture(uint32 slot, const TexturePointer& view); + void setResourceTexture(uint32 slot, const TextureView& view); // not a command, just a shortcut from a TextureView // Framebuffer Stage void setFramebuffer(const FramebufferPointer& framebuffer); @@ -172,7 +172,7 @@ public: COMMAND_setStateBlendFactor, COMMAND_setUniformBuffer, - COMMAND_setUniformTexture, + COMMAND_setResourceTexture, COMMAND_setFramebuffer, diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 54a54ce2a5..a0320cea1b 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -35,7 +35,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_setStateBlendFactor), (&::gpu::GLBackend::do_setUniformBuffer), - (&::gpu::GLBackend::do_setUniformTexture), + (&::gpu::GLBackend::do_setResourceTexture), (&::gpu::GLBackend::do_setFramebuffer), diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 78b0f0838e..2f511ca8d4 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -309,7 +309,7 @@ protected: // Uniform Stage void do_setUniformBuffer(Batch& batch, uint32 paramOffset); - void do_setUniformTexture(Batch& batch, uint32 paramOffset); + void do_setResourceTexture(Batch& batch, uint32 paramOffset); struct UniformStageState { diff --git a/libraries/gpu/src/gpu/GLBackendPipeline.cpp b/libraries/gpu/src/gpu/GLBackendPipeline.cpp index 3b16c58b20..51a3a24e9b 100755 --- a/libraries/gpu/src/gpu/GLBackendPipeline.cpp +++ b/libraries/gpu/src/gpu/GLBackendPipeline.cpp @@ -188,7 +188,7 @@ void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) { (void) CHECK_GL_ERROR(); } -void GLBackend::do_setUniformTexture(Batch& batch, uint32 paramOffset) { +void GLBackend::do_setResourceTexture(Batch& batch, uint32 paramOffset) { GLuint slot = batch._params[paramOffset + 1]._uint; TexturePointer uniformTexture = batch._textures.get(batch._params[paramOffset + 0]._uint); diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index a02c646668..0fb2458f01 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -103,7 +103,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8); batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize()); batch.setInputFormat(theFormat); - batch.setUniformTexture(0, skybox.getCubemap()); + batch.setResourceTexture(0, skybox.getCubemap()); batch.draw(gpu::TRIANGLE_STRIP, 4); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index a721e0cad3..c8ae000479 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -147,7 +147,7 @@ void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured, if (!config.isTextured()) { // If it is not textured, bind white texture and keep using textured pipeline - batch.setUniformTexture(0, DependencyManager::get()->getWhiteTexture()); + batch.setResourceTexture(0, DependencyManager::get()->getWhiteTexture()); } } @@ -244,13 +244,13 @@ void DeferredLightingEffect::render(RenderArgs* args) { batch.clearColorFramebuffer(freeFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); - batch.setUniformTexture(0, textureCache->getPrimaryColorTexture()); + batch.setResourceTexture(0, textureCache->getPrimaryColorTexture()); - batch.setUniformTexture(1, textureCache->getPrimaryNormalTexture()); + batch.setResourceTexture(1, textureCache->getPrimaryNormalTexture()); - batch.setUniformTexture(2, textureCache->getPrimarySpecularTexture()); + batch.setResourceTexture(2, textureCache->getPrimarySpecularTexture()); - batch.setUniformTexture(3, textureCache->getPrimaryDepthTexture()); + batch.setResourceTexture(3, textureCache->getPrimaryDepthTexture()); // get the viewport side (left, right, both) int viewport[4]; @@ -275,7 +275,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { const LightLocations* locations = &_directionalLightLocations; bool shadowsEnabled = _viewState->getShadowsEnabled(); if (shadowsEnabled) { - batch.setUniformTexture(4, textureCache->getShadowFramebuffer()->getDepthStencilBuffer()); + batch.setResourceTexture(4, textureCache->getShadowFramebuffer()->getDepthStencilBuffer()); program = _directionalLightShadowMap; locations = &_directionalLightShadowMapLocations; @@ -329,7 +329,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { } if (useSkyboxCubemap) { - batch.setUniformTexture(5, _skybox->getCubemap()); + batch.setResourceTexture(5, _skybox->getCubemap()); } if (locations->lightBufferUnit >= 0) { @@ -377,11 +377,11 @@ void DeferredLightingEffect::render(RenderArgs* args) { } if (useSkyboxCubemap) { - batch.setUniformTexture(5, nullptr); + batch.setResourceTexture(5, nullptr); } if (shadowsEnabled) { - batch.setUniformTexture(4, nullptr); + batch.setResourceTexture(4, nullptr); } glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); @@ -530,10 +530,10 @@ void DeferredLightingEffect::render(RenderArgs* args) { } // Probably not necessary in the long run because the gpu layer would unbound this texture if used as render target - batch.setUniformTexture(0, nullptr); - batch.setUniformTexture(1, nullptr); - batch.setUniformTexture(2, nullptr); - batch.setUniformTexture(3, nullptr); + batch.setResourceTexture(0, nullptr); + batch.setResourceTexture(1, nullptr); + batch.setResourceTexture(2, nullptr); + batch.setResourceTexture(3, nullptr); args->_context->syncCache(); args->_context->render(batch); @@ -551,7 +551,7 @@ void DeferredLightingEffect::copyBack(RenderArgs* args) { batch.setFramebuffer(textureCache->getPrimaryFramebuffer()); batch.setPipeline(_blitLightBuffer); - batch.setUniformTexture(0, freeFBO->getRenderBuffer(0)); + batch.setResourceTexture(0, freeFBO->getRenderBuffer(0)); batch.setProjectionTransform(glm::mat4()); batch.setViewTransform(Transform()); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 03140c4dfb..ce325d23cb 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2031,10 +2031,10 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran } static bool showDiffuse = true; if (showDiffuse && diffuseMap) { - batch.setUniformTexture(0, diffuseMap->getGPUTexture()); + batch.setResourceTexture(0, diffuseMap->getGPUTexture()); } else { - batch.setUniformTexture(0, textureCache->getWhiteTexture()); + batch.setResourceTexture(0, textureCache->getWhiteTexture()); } if (locations->texcoordMatrices >= 0) { @@ -2050,14 +2050,14 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran if (!mesh.tangents.isEmpty()) { Texture* normalMap = networkPart.normalTexture.data(); - batch.setUniformTexture(1, !normalMap ? + batch.setResourceTexture(1, !normalMap ? textureCache->getBlueTexture() : normalMap->getGPUTexture()); } if (locations->specularTextureUnit >= 0) { Texture* specularMap = networkPart.specularTexture.data(); - batch.setUniformTexture(locations->specularTextureUnit, !specularMap ? + batch.setResourceTexture(locations->specularTextureUnit, !specularMap ? textureCache->getWhiteTexture() : specularMap->getGPUTexture()); } @@ -2074,7 +2074,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran GLBATCH(glUniform2f)(locations->emissiveParams, emissiveOffset, emissiveScale); Texture* emissiveMap = networkPart.emissiveTexture.data(); - batch.setUniformTexture(locations->emissiveTextureUnit, !emissiveMap ? + batch.setResourceTexture(locations->emissiveTextureUnit, !emissiveMap ? textureCache->getWhiteTexture() : emissiveMap->getGPUTexture()); } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 8de5c8af01..cf60c42f98 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -236,7 +236,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon batch.setViewTransform(viewMat); batch.setPipeline(getOpaquePipeline()); - batch.setUniformTexture(0, args->_whiteTexture); + batch.setResourceTexture(0, args->_whiteTexture); if (!inItems.empty()) { batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0); diff --git a/libraries/render-utils/src/TextRenderer3D.cpp b/libraries/render-utils/src/TextRenderer3D.cpp index a429719b8b..973cddc4d7 100644 --- a/libraries/render-utils/src/TextRenderer3D.cpp +++ b/libraries/render-utils/src/TextRenderer3D.cpp @@ -423,7 +423,7 @@ void Font3D::drawString(gpu::Batch& batch, float x, float y, const QString& str, setupGPU(); batch.setPipeline(_pipeline); - batch.setUniformTexture(_fontLoc, _texture); + batch.setResourceTexture(_fontLoc, _texture); batch._glUniform1i(_outlineLoc, (effectType == TextRenderer3D::OUTLINE_EFFECT)); batch._glUniform4fv(_colorLoc, 1, (const GLfloat*)color); From 71440dfbc551f9a33278bb3e4b25c0286094684c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 10 Jul 2015 11:30:11 -0700 Subject: [PATCH 13/49] add checks for NaN --- .../entities/src/EntityActionInterface.cpp | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/libraries/entities/src/EntityActionInterface.cpp b/libraries/entities/src/EntityActionInterface.cpp index 2b723d4e15..ba7f3afea4 100644 --- a/libraries/entities/src/EntityActionInterface.cpp +++ b/libraries/entities/src/EntityActionInterface.cpp @@ -127,21 +127,21 @@ glm::vec3 EntityActionInterface::extractVec3Argument(QString objectName, QVarian qDebug() << objectName << "requires argument:" << argumentName; } ok = false; - return glm::vec3(); + return glm::vec3(0.0f); } QVariant resultV = arguments[argumentName]; if (resultV.type() != (QVariant::Type) QMetaType::QVariantMap) { qDebug() << objectName << "argument" << argumentName << "must be a map"; ok = false; - return glm::vec3(); + return glm::vec3(0.0f); } QVariantMap resultVM = resultV.toMap(); if (!resultVM.contains("x") || !resultVM.contains("y") || !resultVM.contains("z")) { - qDebug() << objectName << "argument" << argumentName << "must be a map with keys of x, y, z"; + qDebug() << objectName << "argument" << argumentName << "must be a map with keys: x, y, z"; ok = false; - return glm::vec3(); + return glm::vec3(0.0f); } QVariant xV = resultVM["x"]; @@ -155,9 +155,15 @@ glm::vec3 EntityActionInterface::extractVec3Argument(QString objectName, QVarian float y = yV.toFloat(&yOk); float z = zV.toFloat(&zOk); if (!xOk || !yOk || !zOk) { - qDebug() << objectName << "argument" << argumentName << "must be a map with keys of x, y, z and values of type float."; + qDebug() << objectName << "argument" << argumentName << "must be a map with keys: x, y, and z of type float."; ok = false; - return glm::vec3(); + return glm::vec3(0.0f); + } + + if (x != x || y != y || z != z) { + // at least one of the values is NaN + ok = false; + return glm::vec3(0.0f); } return glm::vec3(x, y, z); @@ -181,8 +187,8 @@ glm::quat EntityActionInterface::extractQuatArgument(QString objectName, QVarian } QVariantMap resultVM = resultV.toMap(); - if (!resultVM.contains("x") || !resultVM.contains("y") || !resultVM.contains("z")) { - qDebug() << objectName << "argument" << argumentName << "must be a map with keys of x, y, z"; + if (!resultVM.contains("x") || !resultVM.contains("y") || !resultVM.contains("z") || !resultVM.contains("w")) { + qDebug() << objectName << "argument" << argumentName << "must be a map with keys: x, y, z, and w"; ok = false; return glm::quat(); } @@ -202,12 +208,18 @@ glm::quat EntityActionInterface::extractQuatArgument(QString objectName, QVarian float w = wV.toFloat(&wOk); if (!xOk || !yOk || !zOk || !wOk) { qDebug() << objectName << "argument" << argumentName - << "must be a map with keys of x, y, z, w and values of type float."; + << "must be a map with keys: x, y, z, and w of type float."; ok = false; return glm::quat(); } - return glm::quat(w, x, y, z); + if (x != x || y != y || z != z || w != w) { + // at least one of the components is NaN! + ok = false; + return glm::quat(); + } + + return glm::normalize(glm::quat(w, x, y, z)); } float EntityActionInterface::extractFloatArgument(QString objectName, QVariantMap arguments, @@ -224,7 +236,7 @@ float EntityActionInterface::extractFloatArgument(QString objectName, QVariantMa bool vOk = true; float v = vV.toFloat(&vOk); - if (!vOk) { + if (!vOk || v != v) { ok = false; return 0.0f; } From 90ae1fea8b2aef2bfc1a0d3d288917202e3aa657 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 10 Jul 2015 11:30:24 -0700 Subject: [PATCH 14/49] handle case where action params are missing --- libraries/physics/src/ObjectActionOffset.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp index 2391ded13d..00b7fe6734 100644 --- a/libraries/physics/src/ObjectActionOffset.cpp +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -95,26 +95,21 @@ bool ObjectActionOffset::updateArguments(QVariantMap arguments) { glm::vec3 pointToOffsetFrom = EntityActionInterface::extractVec3Argument("offset action", arguments, "pointToOffsetFrom", ok, true); if (!ok) { - return false; + pointToOffsetFrom = _pointToOffsetFrom; } ok = true; float linearTimeScale = EntityActionInterface::extractFloatArgument("offset action", arguments, "linearTimeScale", ok, false); - if (ok) { - if (linearTimeScale <= 0.0f) { - qDebug() << "offset action -- linearTimeScale must be greater than zero."; - return false; - } - } else { - linearTimeScale = 0.1f; + if (!ok) { + linearTimeScale = _linearTimeScale; } ok = true; float linearDistance = EntityActionInterface::extractFloatArgument("offset action", arguments, "linearDistance", ok, false); if (!ok) { - linearDistance = 0.0f; + linearDistance = _linearDistance; } // only change stuff if something actually changed From 56f00a526d1403a1844156794e78704222f88fda Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 10 Jul 2015 11:31:37 -0700 Subject: [PATCH 15/49] cleanup of ObjectActionSpring --- libraries/physics/src/ObjectActionSpring.cpp | 189 ++++++++----------- libraries/physics/src/ObjectActionSpring.h | 1 + 2 files changed, 78 insertions(+), 112 deletions(-) diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index cb1dd20472..21e3c19bea 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -17,14 +17,16 @@ const float SPRING_MAX_SPEED = 10.0f; const uint16_t ObjectActionSpring::springVersion = 1; + ObjectActionSpring::ObjectActionSpring(const QUuid& id, EntityItemPointer ownerEntity) : ObjectAction(ACTION_TYPE_SPRING, id, ownerEntity), _positionalTarget(glm::vec3(0.0f)), - _linearTimeScale(0.2f), - _positionalTargetSet(false), + _linearTimeScale(FLT_MAX), + _positionalTargetSet(true), _rotationalTarget(glm::quat()), - _angularTimeScale(0.2f), - _rotationalTargetSet(false) { + _angularTimeScale(FLT_MAX), + _rotationalTargetSet(true), + _needsActivation(true) { #if WANT_DEBUG qDebug() << "ObjectActionSpring::ObjectActionSpring"; #endif @@ -61,130 +63,97 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { return; } - // handle the linear part - if (_positionalTargetSet) { - // check for NaN - if (_positionalTarget.x != _positionalTarget.x || - _positionalTarget.y != _positionalTarget.y || - _positionalTarget.z != _positionalTarget.z) { - qDebug() << "ObjectActionSpring::updateActionWorker -- target position includes NaN"; - unlock(); - lockForWrite(); - _active = false; - unlock(); - return; - } - glm::vec3 offset = _positionalTarget - bulletToGLM(rigidBody->getCenterOfMassPosition()); - float offsetLength = glm::length(offset); - float speed = offsetLength / _linearTimeScale; - - // cap speed - if (speed > SPRING_MAX_SPEED) { - speed = SPRING_MAX_SPEED; - } - - if (offsetLength > IGNORE_POSITION_DELTA) { - glm::vec3 newVelocity = glm::normalize(offset) * speed; - rigidBody->setLinearVelocity(glmToBullet(newVelocity)); - rigidBody->activate(); - } else { - rigidBody->setLinearVelocity(glmToBullet(glm::vec3(0.0f))); - } + const float MAX_TIMESCALE = 600.0f; // 10 min is a long time + if (_linearTimeScale < MAX_TIMESCALE) { + btVector3 offset = rigidBody->getCenterOfMassPosition() - glmToBullet(_positionalTarget); + float offsetLength = offset.length(); + //float blend = glm::min(1.0f, deltaTimeStep / _linearTimeScale); + float blend = 1.0f; + float speed = (offsetLength > FLT_EPSILON) ? glm::min(offsetLength / _linearTimeScale, SPRING_MAX_SPEED) : 0.0f; + rigidBody->setLinearVelocity((1.0f - blend) * rigidBody->getLinearVelocity() - (blend * speed / (offsetLength * _linearTimeScale)) * offset); } - // handle rotation - if (_rotationalTargetSet) { - if (_rotationalTarget.x != _rotationalTarget.x || - _rotationalTarget.y != _rotationalTarget.y || - _rotationalTarget.z != _rotationalTarget.z || - _rotationalTarget.w != _rotationalTarget.w) { - qDebug() << "AvatarActionHold::updateActionWorker -- target rotation includes NaN"; - unlock(); - lockForWrite(); - _active = false; - unlock(); - return; - } + if (_angularTimeScale < MAX_TIMESCALE) { + btVector3 targetVelocity(0.0f, 0.0f, 0.0f); - glm::quat bodyRotation = bulletToGLM(rigidBody->getOrientation()); - // if qZero and qOne are too close to each other, we can get NaN for angle. - auto alignmentDot = glm::dot(bodyRotation, _rotationalTarget); - const float almostOne = 0.99999f; - if (glm::abs(alignmentDot) < almostOne) { - glm::quat target = _rotationalTarget; - if (alignmentDot < 0) { + btQuaternion bodyRotation = rigidBody->getOrientation(); + auto alignmentDot = bodyRotation.dot(glmToBullet(_rotationalTarget)); + const float ALMOST_ONE = 0.99999f; + if (glm::abs(alignmentDot) < ALMOST_ONE) { + btQuaternion target = glmToBullet(_rotationalTarget); + if (alignmentDot < 0.0f) { target = -target; } - glm::quat qZeroInverse = glm::inverse(bodyRotation); - glm::quat deltaQ = target * qZeroInverse; - glm::vec3 axis = glm::axis(deltaQ); - float angle = glm::angle(deltaQ); - assert(!isNaN(angle)); - glm::vec3 newAngularVelocity = (angle / _angularTimeScale) * glm::normalize(axis); - rigidBody->setAngularVelocity(glmToBullet(newAngularVelocity)); - rigidBody->activate(); - } else { - rigidBody->setAngularVelocity(glmToBullet(glm::vec3(0.0f))); + // if dQ is the incremental rotation that gets an object from Q0 to Q1 then: + // + // Q1 = dQ * Q0 + // + // solving for dQ gives: + // + // dQ = Q1 * Q0^ + btQuaternion deltaQ = target * bodyRotation.inverse(); + float angle = deltaQ.getAngle(); + const float MIN_ANGLE = 1.0e-4; + if (angle > MIN_ANGLE) { + targetVelocity = (angle / _angularTimeScale) * deltaQ.getAxis(); + } } + //float blend = glm::min(1.0f, deltaTimeStep / _angularTimeScale); + float blend = 1.0f; + rigidBody->setAngularVelocity((1.0f - blend) * rigidBody->getAngularVelocity() + blend * targetVelocity); + } + if (_needsActivation) { + rigidBody->activate(); + _needsActivation = false; } - unlock(); } +const float MIN_TIMESCALE = 0.1f; bool ObjectActionSpring::updateArguments(QVariantMap arguments) { // targets are required, spring-constants are optional - bool ptOk = true; + bool ok = true; glm::vec3 positionalTarget = - EntityActionInterface::extractVec3Argument("spring action", arguments, "targetPosition", ptOk, false); - bool pscOk = true; + EntityActionInterface::extractVec3Argument("spring action", arguments, "targetPosition", ok, false); + if (!ok) { + positionalTarget = _positionalTarget; + } + ok = true; float linearTimeScale = - EntityActionInterface::extractFloatArgument("spring action", arguments, "linearTimeScale", pscOk, false); - if (ptOk && pscOk && linearTimeScale <= 0.0f) { - qDebug() << "spring action -- linearTimeScale must be greater than zero."; - return false; + EntityActionInterface::extractFloatArgument("spring action", arguments, "linearTimeScale", ok, false); + if (!ok || linearTimeScale <= 0.0f) { + linearTimeScale = _linearTimeScale; } - bool rtOk = true; + ok = true; glm::quat rotationalTarget = - EntityActionInterface::extractQuatArgument("spring action", arguments, "targetRotation", rtOk, false); - bool rscOk = true; + EntityActionInterface::extractQuatArgument("spring action", arguments, "targetRotation", ok, false); + if (!ok) { + rotationalTarget = _rotationalTarget; + } + + ok = true; float angularTimeScale = - EntityActionInterface::extractFloatArgument("spring action", arguments, "angularTimeScale", rscOk, false); - - if (!ptOk && !rtOk) { - qDebug() << "spring action requires at least one of targetPosition or targetRotation argument"; - return false; + EntityActionInterface::extractFloatArgument("spring action", arguments, "angularTimeScale", ok, false); + if (!ok) { + angularTimeScale = _angularTimeScale; } - lockForWrite(); - - _positionalTargetSet = _rotationalTargetSet = false; - - if (ptOk) { + if (positionalTarget != _positionalTarget + || linearTimeScale != _linearTimeScale + || rotationalTarget != _rotationalTarget + || angularTimeScale != _angularTimeScale) { + // something changed + lockForWrite(); _positionalTarget = positionalTarget; - _positionalTargetSet = true; - - if (pscOk) { - _linearTimeScale = linearTimeScale; - } else { - _linearTimeScale = 0.1f; - } - } - - if (rtOk) { + _linearTimeScale = glm::max(MIN_TIMESCALE, glm::abs(linearTimeScale)); _rotationalTarget = rotationalTarget; - _rotationalTargetSet = true; - - if (rscOk) { - _angularTimeScale = angularTimeScale; - } else { - _angularTimeScale = 0.1f; - } + _angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale)); + _active = true; + _needsActivation = true; + unlock(); } - - _active = true; - unlock(); return true; } @@ -192,15 +161,11 @@ QVariantMap ObjectActionSpring::getArguments() { QVariantMap arguments; lockForRead(); - if (_positionalTargetSet) { - arguments["linearTimeScale"] = _linearTimeScale; - arguments["targetPosition"] = glmToQMap(_positionalTarget); - } + arguments["linearTimeScale"] = _linearTimeScale; + arguments["targetPosition"] = glmToQMap(_positionalTarget); - if (_rotationalTargetSet) { - arguments["targetRotation"] = glmToQMap(_rotationalTarget); - arguments["angularTimeScale"] = _angularTimeScale; - } + arguments["targetRotation"] = glmToQMap(_rotationalTarget); + arguments["angularTimeScale"] = _angularTimeScale; unlock(); return arguments; diff --git a/libraries/physics/src/ObjectActionSpring.h b/libraries/physics/src/ObjectActionSpring.h index caa64c3d3a..a0a829bdab 100644 --- a/libraries/physics/src/ObjectActionSpring.h +++ b/libraries/physics/src/ObjectActionSpring.h @@ -37,6 +37,7 @@ protected: glm::quat _rotationalTarget; float _angularTimeScale; bool _rotationalTargetSet; + bool _needsActivation; }; #endif // hifi_ObjectActionSpring_h From 294c1ba367fe5de853bd9f3b91de62a60150ae17 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 10 Jul 2015 12:17:21 -0700 Subject: [PATCH 16/49] always serialize ACTION_TYPE_SPRING --- libraries/physics/src/ObjectActionSpring.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index 21e3c19bea..c1ef94296a 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -175,7 +175,7 @@ QByteArray ObjectActionSpring::serialize() const { QByteArray serializedActionArguments; QDataStream dataStream(&serializedActionArguments, QIODevice::WriteOnly); - dataStream << getType(); + dataStream << ACTION_TYPE_SPRING; dataStream << getID(); dataStream << ObjectActionSpring::springVersion; @@ -195,7 +195,7 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) { EntityActionType type; dataStream >> type; - assert(type == getType()); + assert(type == ACTION_TYPE_SPRING); QUuid id; dataStream >> id; From 9cb7e86877f297944e845a919f4d5b3362dc28d0 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 10 Jul 2015 12:18:09 -0700 Subject: [PATCH 17/49] cleanup of AvatarActionHold deserialization --- interface/src/avatar/AvatarActionHold.cpp | 100 ++++++++-------------- 1 file changed, 38 insertions(+), 62 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index ba37112fe1..1e75250ee2 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -70,30 +70,14 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { return; } - // check for NaNs - if (position.x != position.x || - position.y != position.y || - position.z != position.z) { - qDebug() << "AvatarActionHold::updateActionWorker -- target position includes NaN"; - return; - } - if (rotation.x != rotation.x || - rotation.y != rotation.y || - rotation.z != rotation.z || - rotation.w != rotation.w) { - qDebug() << "AvatarActionHold::updateActionWorker -- target rotation includes NaN"; - return; - } - if (_positionalTarget != position || _rotationalTarget != rotation) { auto ownerEntity = _ownerEntity.lock(); if (ownerEntity) { ownerEntity->setActionDataDirty(true); } + _positionalTarget = position; + _rotationalTarget = rotation; } - - _positionalTarget = position; - _rotationalTarget = rotation; unlock(); ObjectActionSpring::updateActionWorker(deltaTimeStep); @@ -101,59 +85,51 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { bool AvatarActionHold::updateArguments(QVariantMap arguments) { - bool rPOk = true; + bool ok = true; glm::vec3 relativePosition = - EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", rPOk, false); - bool rROk = true; + EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false); + if (!ok) { + relativePosition = _relativePosition; + } + + ok = true; glm::quat relativeRotation = - EntityActionInterface::extractQuatArgument("hold", arguments, "relativeRotation", rROk, false); - bool tSOk = true; + EntityActionInterface::extractQuatArgument("hold", arguments, "relativeRotation", ok, false); + if (!ok) { + relativeRotation = _relativeRotation; + } + + ok = true; float timeScale = - EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", tSOk, false); - bool hOk = true; + EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", ok, false); + if (!ok) { + timeScale = _linearTimeScale; + } + + ok = true; QString hand = - EntityActionInterface::extractStringArgument("hold", arguments, "hand", hOk, false); + EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false); + if (!ok || !(hand == "left" || hand == "right")) { + hand = _hand; + } - lockForWrite(); - if (rPOk) { + if (relativePosition != _relativePosition + || relativeRotation != _relativeRotation + || timeScale != _linearTimeScale + || hand != _hand) { + lockForWrite(); _relativePosition = relativePosition; - } else { - _relativePosition = glm::vec3(0.0f, 0.0f, 1.0f); - } - - if (rROk) { _relativeRotation = relativeRotation; - } else { - _relativeRotation = glm::quat(0.0f, 0.0f, 0.0f, 1.0f); - } + const float MIN_TIMESCALE = 0.1f; + _linearTimeScale = glm::min(MIN_TIMESCALE, timeScale); + _angularTimeScale = _linearTimeScale; + _hand = hand; - if (tSOk) { - _linearTimeScale = timeScale; - _angularTimeScale = timeScale; - } else { - _linearTimeScale = 0.2f; - _angularTimeScale = 0.2f; + _mine = true; + _active = true; + _needsActivation = true; + unlock(); } - - if (hOk) { - hand = hand.toLower(); - if (hand == "left") { - _hand = "left"; - } else if (hand == "right") { - _hand = "right"; - } else { - qDebug() << "hold action -- invalid hand argument:" << hand; - _hand = "right"; - } - } else { - _hand = "right"; - } - - _mine = true; - _positionalTargetSet = true; - _rotationalTargetSet = true; - _active = true; - unlock(); return true; } From 2ce8dba8193222f6a48176e7623a5d0133c886a6 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 10 Jul 2015 15:06:38 -0700 Subject: [PATCH 18/49] Removing heap allocation from property flag parsing, adding some manual tests --- libraries/shared/src/BufferParser.h | 5 +- libraries/shared/src/PropertyFlags.h | 92 ++++++++------- tests/entities/CMakeLists.txt | 12 ++ tests/entities/packet.bin | Bin 0 -> 1387 bytes tests/entities/src/main.cpp | 165 +++++++++++++++++++++++++++ 5 files changed, 231 insertions(+), 43 deletions(-) create mode 100644 tests/entities/CMakeLists.txt create mode 100644 tests/entities/packet.bin create mode 100644 tests/entities/src/main.cpp diff --git a/libraries/shared/src/BufferParser.h b/libraries/shared/src/BufferParser.h index 84bde2be31..d60e7127cd 100644 --- a/libraries/shared/src/BufferParser.h +++ b/libraries/shared/src/BufferParser.h @@ -44,10 +44,7 @@ public: template inline void readFlags(PropertyFlags& result) { - // FIXME doing heap allocation - QByteArray encoded((const char*)(_data + _offset), remaining()); - result.decode(encoded); - _offset += result.getEncodedLength(); + _offset += result.decode(_data + _offset, remaining()); } template diff --git a/libraries/shared/src/PropertyFlags.h b/libraries/shared/src/PropertyFlags.h index de05edc076..0202784c77 100644 --- a/libraries/shared/src/PropertyFlags.h +++ b/libraries/shared/src/PropertyFlags.h @@ -25,6 +25,7 @@ #include #include +#include "ByteCountCoding.h" #include templateclass PropertyFlags { @@ -51,7 +52,8 @@ public: void setHasProperty(Enum flag, bool value = true); bool getHasProperty(Enum flag) const; QByteArray encode(); - void decode(const QByteArray& fromEncoded); + size_t decode(const uint8_t* data, size_t length); + size_t decode(const QByteArray& fromEncoded); operator QByteArray() { return encode(); }; @@ -193,51 +195,63 @@ template inline QByteArray PropertyFlags::encode() { return output; } -template inline void PropertyFlags::decode(const QByteArray& fromEncodedBytes) { +template +inline size_t PropertyFlags::decode(const uint8_t* data, size_t size) { + clear(); + //clear(); // we are cleared out! - clear(); // we are cleared out! + size_t bytesConsumed = 0; + int bitCount = BITS_IN_BYTE * size; - // first convert the ByteArray into a BitArray... - QBitArray encodedBits; - int bitCount = BITS_PER_BYTE * fromEncodedBytes.count(); - encodedBits.resize(bitCount); - - for(int byte = 0; byte < fromEncodedBytes.count(); byte++) { - char originalByte = fromEncodedBytes.at(byte); - for(int bit = 0; bit < BITS_PER_BYTE; bit++) { - int shiftBy = BITS_PER_BYTE - (bit + 1); - char maskBit = ( 1 << shiftBy); - bool bitValue = originalByte & maskBit; - encodedBits.setBit(byte * BITS_PER_BYTE + bit, bitValue); + int encodedByteCount = 1; // there is at least 1 byte (after the leadBits) + int leadBits = 1; // there is always at least 1 lead bit + bool inLeadBits = true; + int bitAt = 0; + int expectedBitCount; // unknown at this point + int lastValueBit; + for (int byte = 0; byte < size; byte++) { + char originalByte = data[byte]; + bytesConsumed++; + unsigned char maskBit = 0x80; // LEFT MOST BIT set + for (int bit = 0; bit < BITS_IN_BYTE; bit++) { + bool bitIsSet = originalByte & maskBit; + // Processing of the lead bits + if (inLeadBits) { + if (bitIsSet) { + encodedByteCount++; + leadBits++; + } else { + inLeadBits = false; // once we hit our first 0, we know we're out of the lead bits + expectedBitCount = (encodedByteCount * BITS_IN_BYTE) - leadBits; + lastValueBit = expectedBitCount + bitAt; + + // check to see if the remainder of our buffer is sufficient + if (expectedBitCount > (bitCount - leadBits)) { + break; + } + } + } else { + if (bitAt > lastValueBit) { + break; + } + + if (bitIsSet) { + setHasProperty(static_cast(bitAt - leadBits), true); + } + } + bitAt++; + maskBit >>= 1; } - } - - // next, read the leading bits to determine the correct number of bytes to decode (may not match the QByteArray) - int encodedByteCount = 0; - int leadBits = 1; - int bitAt; - for (bitAt = 0; bitAt < bitCount; bitAt++) { - if (encodedBits.at(bitAt)) { - encodedByteCount++; - leadBits++; - } else { + if (!inLeadBits && bitAt > lastValueBit) { break; } } - encodedByteCount++; // always at least one byte - _encodedLength = encodedByteCount; + _encodedLength = bytesConsumed; + return bytesConsumed; +} - int expectedBitCount = encodedByteCount * BITS_PER_BYTE; - - // Now, keep reading... - if (expectedBitCount <= (encodedBits.size() - leadBits)) { - int flagsStartAt = bitAt + 1; - for (bitAt = flagsStartAt; bitAt < expectedBitCount; bitAt++) { - if (encodedBits.at(bitAt)) { - setHasProperty((Enum)(bitAt - flagsStartAt)); - } - } - } +template inline size_t PropertyFlags::decode(const QByteArray& fromEncodedBytes) { + return decode(reinterpret_cast(fromEncodedBytes.data()), fromEncodedBytes.size()); } template inline void PropertyFlags::debugDumpBits() { diff --git a/tests/entities/CMakeLists.txt b/tests/entities/CMakeLists.txt new file mode 100644 index 0000000000..44b84dea43 --- /dev/null +++ b/tests/entities/CMakeLists.txt @@ -0,0 +1,12 @@ + +set(TARGET_NAME "entities-test") + +# This is not a testcase -- just set it up as a regular hifi project +setup_hifi_project() + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") + +# link in the shared libraries +link_hifi_libraries(entities avatars shared octree gpu model fbx networking animation environment) + +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tests/entities/packet.bin b/tests/entities/packet.bin new file mode 100644 index 0000000000000000000000000000000000000000..295117172ded11f54ff48a869fbb449ee8672154 GIT binary patch literal 1387 zcmcJPPiWIn9LIlgRCiF(IjM@c65L_1G;PyvX+g6!VK`@DZU=W6E=!XwlIC?us#|AW zhl*b2pD8jucu-Nni<^Rf4h}(Z!`A89iiqe$chG|}a2iRs)(tylh~MPF%kTFB@B90G z-s>O#(wr%3NT1o=b>}%byv~t)wW)Z>ZiCG5z5#Qi4WP{|n<;}GMblMlp^!L8nk)ct zW?%L(3oZIxW5IMPwGCh_2oUGy=ieFQ+W~-?9m!E_eliyZ##)8}VAcRw4s{Abnl+t$ z0USwlBslez8?Mh>c=Gx1&Sx`iHOY@-Et7T|Y#Etz*J74^GvVNhg6<|OFfP6oICRrw zm*TF8!kF(}40HDAA?DxQS!T*1T+LIoH@r<{C*k0X^opgRQ=AtNX(Dmod}P*f*Fa+noWBc}C) zP*~K|UGjce?Px+MLe{H>sL4npSrm!J3{i7R?cMoGf2z&42m|PcUR;tj-Kf*}h=>PV zmADku@c?B_tWdog7Q3_YPNanKfW#}hScxlq{uj5)QYEe+6wT+gn5xQZNB&zkc+IGd z87RUVvcM}!&s-{z-N_({mrgwhRS%qROk~*8ZyYuEZ@{SC21B{NH~xw0BNZ5@Oqguz zwWaml^*F@f7YCWEt=IE?Pp39NwDvShdk){fQN5s>IiR8R*mUB>$^M4mi7R_cV)V!( zJ`eP&TXR6K$pWnu271qX;JPMEwj^a4drkl7Q$8#>U5hCFwupHeJH=coU7a_U)6$Ns zWu_deyk5y8y4?irrYOQIcm#r$B#{t!pV!L^g5aaw3rYb04d@`RH5&*iivVqD!^-1{ qdoS74x!Y7n^Tf@JBe_0!_p;pvy}6>d&2Uf*u&m$>8Rsxa0>DqVPf;uY literal 0 HcmV?d00001 diff --git a/tests/entities/src/main.cpp b/tests/entities/src/main.cpp new file mode 100644 index 0000000000..8d16d98103 --- /dev/null +++ b/tests/entities/src/main.cpp @@ -0,0 +1,165 @@ +// +// main.cpp +// tests/render-utils/src +// +// 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +const QString& getTestResourceDir() { + static QString dir; + if (dir.isEmpty()) { + QDir path(__FILE__); + path.cdUp(); + dir = path.cleanPath(path.absoluteFilePath("../")) + "/"; + qDebug() << "Qml Test Path: " << dir; + } + return dir; +} + +class StopWatch { +public: + void start() { + Q_ASSERT(_start == 0); + _start = usecTimestampNow(); + } + + void stop() { + Q_ASSERT(_start != 0); + _last = usecTimestampNow() - _start; + _start = 0; + _total += _last; + _count++; + } + + quint64 getLast() { + return _last; + } + + quint64 getTotal() { + return _total; + } + + float getAverage() { + return (float)_total / (float)_count; + } + + void reset() { + _last = _start = _total = _count = 0; + } + +private: + size_t _count{ 0 }; + quint64 _total{ 0 }; + quint64 _start{ 0 }; + quint64 _last{ 0 }; +}; + +template +void testByteCountCodedStable(const T& value) { + ByteCountCoded coder((T)value); + auto encoded = coder.encode(); + auto originalEncodedSize = encoded.size(); + for (int i = 0; i < 10; ++i) { + encoded.append(qrand()); + } + ByteCountCoded decoder; + decoder.decode(encoded); + Q_ASSERT(decoder.data == coder.data); + auto consumed = decoder.decode(encoded.data(), encoded.size()); + Q_ASSERT(consumed == originalEncodedSize); + +} + +template +void testByteCountCoded() { + testByteCountCodedStable(0); + testByteCountCodedStable(1); + testByteCountCodedStable(1 << 16); + testByteCountCodedStable(std::numeric_limits::max() >> 16); + testByteCountCodedStable(std::numeric_limits::max() >> 8); + testByteCountCodedStable(std::numeric_limits::max() >> 1); + testByteCountCodedStable(std::numeric_limits::max()); +} + +void testPropertyFlags(uint32_t value) { + EntityPropertyFlags original; + original.clear(); + auto enumSize = sizeof(EntityPropertyList); + for (size_t i = 0; i < sizeof(EntityPropertyList) * 8; ++i) { + original.setHasProperty((EntityPropertyList)i); + } + QByteArray encoded = original.encode(); + auto originalSize = encoded.size(); + for (size_t i = 0; i < sizeof(EntityPropertyList); ++i) { + encoded.append(qrand()); + } + + EntityPropertyFlags decodeOld, decodeNew; + { + decodeOld.decode(encoded); + Q_ASSERT(decodeOld == original); + } + + { + auto decodeSize = decodeNew.decode((const uint8_t*)encoded.data(), encoded.size()); + Q_ASSERT(originalSize == decodeSize); + Q_ASSERT(decodeNew == original); + } +} + +void testPropertyFlags() { + testPropertyFlags(0); + testPropertyFlags(1); + testPropertyFlags(1 << 16); + testPropertyFlags(0xFFFF); +} + +int main(int argc, char** argv) { + QCoreApplication app(argc, argv); + { + auto start = usecTimestampNow(); + for (int i = 0; i < 1000; ++i) { + testPropertyFlags(); + testByteCountCoded(); + testByteCountCoded(); + testByteCountCoded(); + testByteCountCoded(); + } + auto duration = usecTimestampNow() - start; + qDebug() << duration; + + } + DependencyManager::set(NodeType::Unassigned); + + QFile file(getTestResourceDir() + "packet.bin"); + if (!file.open(QIODevice::ReadOnly)) return -1; + QByteArray packet = file.readAll(); + EntityItemPointer item = BoxEntityItem::factory(EntityItemID(), EntityItemProperties()); + ReadBitstreamToTreeParams params; + params.bitstreamVersion = 33; + + auto start = usecTimestampNow(); + for (int i = 0; i < 1000; ++i) { + item->readEntityDataFromBuffer(reinterpret_cast(packet.constData()), packet.size(), params); + } + float duration = (usecTimestampNow() - start); + qDebug() << (duration / 1000.0f); + return 0; +} + +#include "main.moc" From 98f10e72ec4f5662604d2b93c5357e538e002c34 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 10 Jul 2015 15:20:49 -0700 Subject: [PATCH 19/49] fix the wrong function name that happened missing a merge --- interface/src/audio/AudioScope.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/audio/AudioScope.cpp b/interface/src/audio/AudioScope.cpp index 7a93be80f1..4b4e86e7f4 100644 --- a/interface/src/audio/AudioScope.cpp +++ b/interface/src/audio/AudioScope.cpp @@ -130,7 +130,7 @@ void AudioScope::render(RenderArgs* renderArgs, int width, int height) { auto geometryCache = DependencyManager::get(); geometryCache->useSimpleDrawPipeline(batch); auto textureCache = DependencyManager::get(); - batch.setUniformTexture(0, textureCache->getWhiteTexture()); + batch.setResourceTexture(0, textureCache->getWhiteTexture()); mat4 legacyProjection = glm::ortho(0, width, height, 0, -1000, 1000); batch.setProjectionTransform(legacyProjection); batch.setModelTransform(Transform()); From 3db3676fae7d6b794ab55b58198998a4de47facd Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 10 Jul 2015 15:26:22 -0700 Subject: [PATCH 20/49] Fixing compile failure --- tests/entities/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/entities/CMakeLists.txt b/tests/entities/CMakeLists.txt index 44b84dea43..23c02a97f8 100644 --- a/tests/entities/CMakeLists.txt +++ b/tests/entities/CMakeLists.txt @@ -2,7 +2,7 @@ set(TARGET_NAME "entities-test") # This is not a testcase -- just set it up as a regular hifi project -setup_hifi_project() +setup_hifi_project(Script) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") From c340d336dcfb319dee2b84b528687a0c95658f1b Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 10 Jul 2015 15:43:56 -0700 Subject: [PATCH 21/49] Functional sword script: Mouse and hydra. Switchable hands. Scores above buttons (2d) and above head in-world. Adds avatar hit sound while sword is brandished. --- examples/example/games/sword.js | 259 +++++++++++++++++++------------- 1 file changed, 156 insertions(+), 103 deletions(-) diff --git a/examples/example/games/sword.js b/examples/example/games/sword.js index 66503b62aa..18d6911f0b 100644 --- a/examples/example/games/sword.js +++ b/examples/example/games/sword.js @@ -11,24 +11,26 @@ // "use strict"; /*jslint vars: true*/ -var Script, Entities, MyAvatar, Window, Overlays, Controller, Vec3, Quat, print, ToolBar; // Referenced globals provided by High Fidelity. -Script.include(["../../libraries/toolBars.js"]); +var Script, Entities, MyAvatar, Window, Overlays, Controller, Vec3, Quat, print, ToolBar, Settings; // Referenced globals provided by High Fidelity. +Script.include("http://s3.amazonaws.com/hifi-public/scripts/libraries/toolBars.js"); -var hand = "right"; +var hand = Settings.getValue("highfidelity.sword.hand", "right"); var nullActionID = "00000000-0000-0000-0000-000000000000"; var controllerID; var controllerActive; var stickID = null; var actionID = nullActionID; var targetIDs = []; -var dimensions = { x: 0.3, y: 0.1, z: 2.0 }; -var AWAY_ORIENTATION = Quat.fromPitchYawRollDegrees(-90, 0, 0); +var dimensions = { x: 0.3, y: 0.15, z: 2.0 }; var BUTTON_SIZE = 32; var stickModel = "https://hifi-public.s3.amazonaws.com/eric/models/stick.fbx"; var swordModel = "https://hifi-public.s3.amazonaws.com/ozan/props/sword/sword.fbx"; +var swordCollisionShape = "https://hifi-public.s3.amazonaws.com/ozan/props/sword/sword.obj"; +var swordCollisionSoundURL = "http://public.highfidelity.io/sounds/Collisions-hitsandslaps/swordStrike1.wav"; +var avatarCollisionSoundURL = "https://s3.amazonaws.com/hifi-public/sounds/Collisions-hitsandslaps/airhockey_hit1.wav"; var whichModel = "sword"; -var attachmentOffset, MOUSE_CONTROLLER_OFFSET = {x: 0.5, y: 0.4, z: 0.0}; // A fudge when using mouse rather than hand-controller, to hit yourself less often. +var originalAvatarCollisionSound; var toolBar = new ToolBar(0, 0, ToolBar.vertical, "highfidelity.sword.toolbar", function () { return {x: 100, y: 380}; @@ -37,6 +39,7 @@ var toolBar = new ToolBar(0, 0, ToolBar.vertical, "highfidelity.sword.toolbar", var SWORD_IMAGE = "http://s3.amazonaws.com/hifi-public/images/billiardsReticle.png"; // Toggle between brandishing/sheathing sword (creating if necessary) var TARGET_IMAGE = "http://s3.amazonaws.com/hifi-public/images/puck.png"; // Create a target dummy var CLEANUP_IMAGE = "http://s3.amazonaws.com/hifi-public/images/delete.png"; // Remove sword and all target dummies.f +var SWITCH_HANDS_IMAGE = "http://s3.amazonaws.com/hifi-public/images/up-arrow.svg"; // Toggle left vs right hand. Persists in settings. var swordButton = toolBar.addOverlay("image", { width: BUTTON_SIZE, height: BUTTON_SIZE, @@ -49,6 +52,12 @@ var targetButton = toolBar.addOverlay("image", { imageURL: TARGET_IMAGE, alpha: 1 }); +var switchHandsButton = toolBar.addOverlay("image", { + width: BUTTON_SIZE, + height: BUTTON_SIZE, + imageURL: SWITCH_HANDS_IMAGE, + alpha: 1 +}); var cleanupButton = toolBar.addOverlay("image", { width: BUTTON_SIZE, height: BUTTON_SIZE, @@ -77,53 +86,51 @@ function flash(color) { flasher.timer = Script.setTimeout(clearFlash, 500); } - var health = 100; -var display; -var isAway = false; +var display2d, display3d; +function trackAvatarWithText() { + Entities.editEntity(display3d, { + position: Vec3.sum(MyAvatar.position, {x: 0, y: 1.5, z: 0}), + rotation: Quat.multiply(MyAvatar.orientation, Quat.fromPitchYawRollDegrees(0, 180, 0)) + }); +} function updateDisplay() { var text = health.toString(); - if (!display) { + if (!display2d) { health = 100; - display = Overlays.addOverlay("text", { + display2d = Overlays.addOverlay("text", { text: text, font: { size: 20 }, color: {red: 0, green: 255, blue: 0}, backgroundColor: {red: 100, green: 100, blue: 100}, // Why doesn't this and the next work? backgroundAlpha: 0.9, - x: Window.innerWidth - 50, - y: 50 + x: toolBar.x - 5, // I'd like to add the score to the toolBar and have it drag with it, but toolBar doesn't support text (just buttons). + y: toolBar.y - 30 // So next best thing is to position it each time as if it were on top. }); + display3d = Entities.addEntity({ + name: MyAvatar.displayName + " score", + textColor: {red: 255, green: 255, blue: 255}, + type: "Text", + text: text, + lineHeight: 0.14, + backgroundColor: {red: 64, green: 64, blue: 64}, + dimensions: {x: 0.3, y: 0.2, z: 0.01}, + }); + Script.update.connect(trackAvatarWithText); } else { - Overlays.editOverlay(display, {text: text}); + Overlays.editOverlay(display2d, {text: text}); + Entities.editEntity(display3d, {text: text}); } } function removeDisplay() { - if (display) { - Overlays.deleteOverlay(display); - display = null; + if (display2d) { + Overlays.deleteOverlay(display2d); + display2d = null; + Script.update.disconnect(trackAvatarWithText); + Entities.deleteEntity(display3d); + display3d = null; } } - -function cleanUp(leaveButtons) { - attachmentOffset = {x: 0, y: 0, z: 0}; - if (stickID) { - Entities.deleteAction(stickID, actionID); - Entities.deleteEntity(stickID); - stickID = null; - actionID = null; - } - targetIDs.forEach(function (id) { - Entities.deleteAction(id.entity, id.action); - Entities.deleteEntity(id.entity); - }); - targetIDs = []; - removeDisplay(); - if (!leaveButtons) { - toolBar.cleanup(); - } -} - function computeEnergy(collision, entityID) { var id = entityID || collision.idA || collision.idB; var entity = id && Entities.getEntityProperties(id); @@ -133,31 +140,67 @@ function computeEnergy(collision, entityID) { return Math.min(Math.max(1.0, Math.round(energy)), 20); } function gotHit(collision) { - if (isAway) { return; } var energy = computeEnergy(collision); + print("Got hit - " + energy + " from " + collision.idA + " " + collision.idB); health -= energy; flash({red: 255, green: 0, blue: 0}); updateDisplay(); } function scoreHit(idA, idB, collision) { - if (isAway) { return; } var energy = computeEnergy(collision, idA); + print("Score + " + energy + " from " + JSON.stringify(idA) + " " + JSON.stringify(idB)); health += energy; flash({red: 0, green: 255, blue: 0}); updateDisplay(); } -function positionStick(stickOrientation) { - var baseOffset = Vec3.sum(attachmentOffset, {x: 0.0, y: 0.0, z: -dimensions.z / 2}); - var offset = Vec3.multiplyQbyV(stickOrientation, baseOffset); - Entities.updateAction(stickID, actionID, {relativePosition: offset, - relativeRotation: stickOrientation}); +function isFighting() { + return stickID && (actionID !== nullActionID); } - +function initControls() { + print("Sword hand is " + hand); + if (hand === "right") { + controllerID = 3; // right handed + } else { + controllerID = 4; // left handed + } +} +var inHand = false; +function positionStick(stickOrientation) { + var reorient = Quat.fromPitchYawRollDegrees(0, -90, 0); + var baseOffset = {x: -dimensions.z * 0.8, y: 0, z: 0}; + var offset = Vec3.multiplyQbyV(reorient, baseOffset); + stickOrientation = Quat.multiply(reorient, stickOrientation); + inHand = false; + Entities.updateAction(stickID, actionID, { + relativePosition: offset, + relativeRotation: stickOrientation + }); +} +function resetToHand() { // Maybe coordinate with positionStick? + if (inHand) { // Optimization: bail if we're already inHand. + return; + } + print('Reset to hand'); + Entities.updateAction(stickID, actionID, { + relativePosition: {x: 0.0, y: 0.0, z: -dimensions.z * 0.5}, + relativeRotation: Quat.fromVec3Degrees({x: 45.0, y: 0.0, z: 0.0}), + hand: hand, // It should not be necessary to repeat these two, but there seems to be a bug in that that + timeScale: 0.05 // they do not retain their earlier values if you don't repeat them. + }); + inHand = true; +} function mouseMoveEvent(event) { - attachmentOffset = MOUSE_CONTROLLER_OFFSET; - if (!stickID || actionID === nullActionID || isAway) { + if (event.deviceID) { // Not a MOUSE mouse event, but a (e.g., hydra) mouse event, with x/y that is not meaningful for us. + resetToHand(); // Can only happen when controller is uncradled, so let's drive with that, resetting our attachement. + return; + } + controllerActive = (Vec3.length(Controller.getSpatialControlPosition(controllerID)) > 0); + //print("Mouse move with hand controller " + (controllerActive ? "active" : "inactive") + JSON.stringify(event)); + if (controllerActive || !isFighting()) { + print('Attempting attachment reset'); + resetToHand(); return; } var windowCenterX = Window.innerWidth / 2; @@ -167,73 +210,80 @@ function mouseMoveEvent(event) { var mouseXRatio = mouseXCenterOffset / windowCenterX; var mouseYRatio = mouseYCenterOffset / windowCenterY; - var stickOrientation = Quat.fromPitchYawRollDegrees(mouseYRatio * -90, mouseXRatio * -90, 0); + var stickOrientation = Quat.fromPitchYawRollDegrees(mouseYRatio * 90, mouseXRatio * 90, 0); positionStick(stickOrientation); } - -function initControls() { - if (hand === "right") { - controllerID = 3; // right handed - } else { - controllerID = 4; // left handed +function removeSword() { + if (stickID) { + print('deleting action ' + actionID + ' and entity ' + stickID); + Entities.deleteAction(stickID, actionID); + Entities.deleteEntity(stickID); + stickID = null; + actionID = nullActionID; + Controller.mouseMoveEvent.disconnect(mouseMoveEvent); + MyAvatar.collisionWithEntity.disconnect(gotHit); + // removeEventhHandler happens automatically when the entity is deleted. + } + inHand = false; + if (originalAvatarCollisionSound !== undefined) { + MyAvatar.collisionSoundURL = originalAvatarCollisionSound; + } + removeDisplay(); +} +function cleanUp(leaveButtons) { + removeSword(); + targetIDs.forEach(function (id) { + Entities.deleteAction(id.entity, id.action); + Entities.deleteEntity(id.entity); + }); + targetIDs = []; + if (!leaveButtons) { + toolBar.cleanup(); } } - - -function update() { - var palmPosition = Controller.getSpatialControlPosition(controllerID); - controllerActive = (Vec3.length(palmPosition) > 0); - if (!controllerActive) { - return; +function makeSword() { + initControls(); + stickID = Entities.addEntity({ + type: "Model", + modelURL: swordModel, + compoundShapeURL: swordCollisionShape, + dimensions: dimensions, + position: (hand === 'right') ? MyAvatar.getRightPalmPosition() : MyAvatar.getLeftPalmPosition(), // initial position doesn't matter, as long as it's close + rotation: MyAvatar.orientation, + damping: 0.1, + collisionSoundURL: swordCollisionSoundURL, + restitution: 0.01, + collisionsWillMove: true + }); + actionID = Entities.addAction("hold", stickID, { + relativePosition: {x: 0.0, y: 0.0, z: -dimensions.z * 0.5}, + relativeRotation: Quat.fromVec3Degrees({x: 45.0, y: 0.0, z: 0.0}), + hand: hand, + timeScale: 0.05 + }); + if (actionID === nullActionID) { + print('*** FAILED TO MAKE SWORD ACTION ***'); + cleanUp(); } - - var stickOrientation = Controller.getSpatialControlRawRotation(controllerID); - var adjustment = Quat.fromPitchYawRollDegrees(180, 0, 0); - stickOrientation = Quat.multiply(stickOrientation, adjustment); - - positionStick(stickOrientation); -} - -function toggleAway() { - isAway = !isAway; - if (isAway) { - positionStick(AWAY_ORIENTATION); - removeDisplay(); - } else { - updateDisplay(); + if (originalAvatarCollisionSound === undefined) { + originalAvatarCollisionSound = MyAvatar.collisionSoundURL; // We won't get MyAvatar.collisionWithEntity unless there's a sound URL. (Bug.) + SoundCache.getSound(avatarCollisionSoundURL); // Interface does not currently "preload" this? (Bug?) } + MyAvatar.collisionSoundURL = avatarCollisionSoundURL; + Controller.mouseMoveEvent.connect(mouseMoveEvent); + MyAvatar.collisionWithEntity.connect(gotHit); + Script.addEventHandler(stickID, 'collisionWithEntity', scoreHit); + updateDisplay(); } function onClick(event) { switch (Overlays.getOverlayAtPoint(event)) { case swordButton: if (!stickID) { - initControls(); - stickID = Entities.addEntity({ - type: "Model", - modelURL: (whichModel === "sword") ? swordModel : stickModel, - //compoundShapeURL: "https://hifi-public.s3.amazonaws.com/eric/models/stick.obj", - shapeType: "box", - dimensions: dimensions, - position: MyAvatar.getRightPalmPosition(), // initial position doesn't matter, as long as it's close - rotation: MyAvatar.orientation, - damping: 0.1, - collisionSoundURL: "http://public.highfidelity.io/sounds/Collisions-hitsandslaps/swordStrike1.wav", - restitution: 0.01, - collisionsWillMove: true - }); - actionID = Entities.addAction("hold", stickID, {relativePosition: {x: 0.0, y: 0.0, z: -dimensions.z / 2}, - hand: hand, - timeScale: 0.15}); - if (actionID === nullActionID) { - print('*** FAILED TO MAKE SWORD ACTION ***'); - cleanUp(); - } - Script.addEventHandler(stickID, 'collisionWithEntity', scoreHit); - updateDisplay(); + makeSword(); } else { - toggleAway(); + removeSword(); } break; case targetButton: @@ -256,6 +306,12 @@ function onClick(event) { }); targetIDs.push({entity: boxId, action: action}); break; + case switchHandsButton: + cleanUp('leaveButtons'); + hand = hand === "right" ? "left" : "right"; + Settings.setValue("highfidelity.sword.hand", hand); + makeSword(); + break; case cleanupButton: cleanUp('leaveButtons'); break; @@ -263,7 +319,4 @@ function onClick(event) { } Script.scriptEnding.connect(cleanUp); -Controller.mouseMoveEvent.connect(mouseMoveEvent); Controller.mousePressEvent.connect(onClick); -Script.update.connect(update); -MyAvatar.collisionWithEntity.connect(gotHit); From c1b72db18dbf750f63fb6eec86c1a455cb86ff93 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 10 Jul 2015 16:00:51 -0700 Subject: [PATCH 22/49] Still trying to get jenkins builds to work --- libraries/shared/src/PropertyFlags.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/shared/src/PropertyFlags.h b/libraries/shared/src/PropertyFlags.h index 0202784c77..b0ac9e76d8 100644 --- a/libraries/shared/src/PropertyFlags.h +++ b/libraries/shared/src/PropertyFlags.h @@ -197,8 +197,7 @@ template inline QByteArray PropertyFlags::encode() { template inline size_t PropertyFlags::decode(const uint8_t* data, size_t size) { - clear(); - //clear(); // we are cleared out! + clear(); // we are cleared out! size_t bytesConsumed = 0; int bitCount = BITS_IN_BYTE * size; From eb9d52fbb32291d7cef7abf379b697253f57af77 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 10 Jul 2015 16:11:56 -0700 Subject: [PATCH 23/49] Helps to actually commit the fix --- tests/entities/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/entities/CMakeLists.txt b/tests/entities/CMakeLists.txt index 23c02a97f8..0077549100 100644 --- a/tests/entities/CMakeLists.txt +++ b/tests/entities/CMakeLists.txt @@ -2,7 +2,7 @@ set(TARGET_NAME "entities-test") # This is not a testcase -- just set it up as a regular hifi project -setup_hifi_project(Script) +setup_hifi_project(Network Script) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") From 51be24515974e60fe4625c979d3644981d5383c0 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 10 Jul 2015 16:55:45 -0700 Subject: [PATCH 24/49] Remove old octreeFade code that wasn't working anyway. --- interface/src/Application.cpp | 38 ---------------- interface/src/Application.h | 10 ----- interface/src/Menu.cpp | 1 - interface/src/Menu.h | 1 - interface/src/octree/OctreeFade.cpp | 68 ----------------------------- interface/src/octree/OctreeFade.h | 46 ------------------- tests/ui/src/main.cpp | 2 +- 7 files changed, 1 insertion(+), 165 deletions(-) delete mode 100644 interface/src/octree/OctreeFade.cpp delete mode 100644 interface/src/octree/OctreeFade.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 00a4440920..aa978f3464 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3572,23 +3572,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se if (!selfAvatarOnly) { _nodeBoundsDisplay.draw(); - // render octree fades if they exist - if (_octreeFades.size() > 0) { - PerformanceTimer perfTimer("octreeFades"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... octree fades..."); - _octreeFadesLock.lockForWrite(); - for(std::vector::iterator fade = _octreeFades.begin(); fade != _octreeFades.end();) { - fade->render(renderArgs); - if(fade->isDone()) { - fade = _octreeFades.erase(fade); - } else { - ++fade; - } - } - _octreeFadesLock.unlock(); - } - // give external parties a change to hook in { PerformanceTimer perfTimer("inWorldInterface"); @@ -3880,17 +3863,6 @@ void Application::nodeKilled(SharedNodePointer node) { qCDebug(interfaceapp, "model server going away...... v[%f, %f, %f, %f]", (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s); - // Add the jurisditionDetails object to the list of "fade outs" - if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnOctreeServerChanges)) { - OctreeFade fade(OctreeFade::FADE_OUT, NODE_KILLED_RED, NODE_KILLED_GREEN, NODE_KILLED_BLUE); - fade.voxelDetails = rootDetails; - const float slightly_smaller = 0.99f; - fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; - _octreeFadesLock.lockForWrite(); - _octreeFades.push_back(fade); - _octreeFadesLock.unlock(); - } - // If the model server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server _entityServerJurisdictions.lockForWrite(); _entityServerJurisdictions.erase(_entityServerJurisdictions.find(nodeUUID)); @@ -3967,16 +3939,6 @@ int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePoin qPrintable(serverType), (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s); - // Add the jurisditionDetails object to the list of "fade outs" - if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnOctreeServerChanges)) { - OctreeFade fade(OctreeFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE); - fade.voxelDetails = rootDetails; - const float slightly_smaller = 0.99f; - fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; - _octreeFadesLock.lockForWrite(); - _octreeFades.push_back(fade); - _octreeFadesLock.unlock(); - } } else { jurisdiction->unlock(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 8dd987fbcd..b621b3e1f2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -72,7 +72,6 @@ #include "ui/ToolWindow.h" #include "ui/UserInputMapper.h" #include "devices/KeyboardMouseDevice.h" -#include "octree/OctreeFade.h" #include "octree/OctreePacketProcessor.h" #include "UndoStackScriptingInterface.h" @@ -91,13 +90,6 @@ class Node; class ProgramObject; class ScriptEngine; -static const float NODE_ADDED_RED = 0.0f; -static const float NODE_ADDED_GREEN = 1.0f; -static const float NODE_ADDED_BLUE = 0.0f; -static const float NODE_KILLED_RED = 1.0f; -static const float NODE_KILLED_GREEN = 0.0f; -static const float NODE_KILLED_BLUE = 0.0f; - static const QString SNAPSHOT_EXTENSION = ".jpg"; static const QString SVO_EXTENSION = ".svo"; static const QString SVO_JSON_EXTENSION = ".svo.json"; @@ -627,8 +619,6 @@ private: NodeBounds _nodeBoundsDisplay; - std::vector _octreeFades; - QReadWriteLock _octreeFadesLock; ControllerScriptingInterface _controllerScriptingInterface; QPointer _logDialog; QPointer _snapshotShareDialog; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 9f49361f79..c583d40d2c 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -340,7 +340,6 @@ Menu::Menu() { 0, // QML Qt::SHIFT | Qt::Key_A, true); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::AmbientOcclusion); - addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DontFadeOnOctreeServerChanges); MenuWrapper* ambientLightMenu = renderOptionsMenu->addMenu(MenuOption::RenderAmbientLight); QActionGroup* ambientLightGroup = new QActionGroup(ambientLightMenu); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 043bb53a7f..f7c00c72ff 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -179,7 +179,6 @@ namespace MenuOption { const QString DisplayModelElementProxy = "Display Model Element Bounds"; const QString DisplayDebugTimingDetails = "Display Timing Details"; const QString DontDoPrecisionPicking = "Don't Do Precision Picking"; - const QString DontFadeOnOctreeServerChanges = "Don't Fade In/Out on Octree Server Changes"; const QString DontRenderEntitiesAsScene = "Don't Render Entities as Scene"; const QString EchoLocalAudio = "Echo Local Audio"; const QString EchoServerAudio = "Echo Server Audio"; diff --git a/interface/src/octree/OctreeFade.cpp b/interface/src/octree/OctreeFade.cpp deleted file mode 100644 index 881f3c5938..0000000000 --- a/interface/src/octree/OctreeFade.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// -// OctreeFade.cpp -// interface/src/octree -// -// Created by Brad Hefta-Gaub on 8/6/13. -// Copyright 2013 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 "InterfaceConfig.h" - -#include -#include -#include - -#include "Application.h" -#include "OctreeFade.h" - -const float OctreeFade::FADE_OUT_START = 0.5f; -const float OctreeFade::FADE_OUT_END = 0.05f; -const float OctreeFade::FADE_OUT_STEP = 0.9f; -const float OctreeFade::FADE_IN_START = 0.05f; -const float OctreeFade::FADE_IN_END = 0.5f; -const float OctreeFade::FADE_IN_STEP = 1.1f; -const float OctreeFade::DEFAULT_RED = 0.5f; -const float OctreeFade::DEFAULT_GREEN = 0.5f; -const float OctreeFade::DEFAULT_BLUE = 0.5f; - -OctreeFade::OctreeFade(FadeDirection direction, float red, float green, float blue) : - direction(direction), - red(red), - green(green), - blue(blue) -{ - opacity = (direction == FADE_OUT) ? FADE_OUT_START : FADE_IN_START; -} - -void OctreeFade::render(RenderArgs* renderArgs) { - DependencyManager::get()->begin(renderArgs); - - glDisable(GL_LIGHTING); - glPushMatrix(); - glScalef(1.0f, 1.0f, 1.0f); - glTranslatef(voxelDetails.x + voxelDetails.s * 0.5f, - voxelDetails.y + voxelDetails.s * 0.5f, - voxelDetails.z + voxelDetails.s * 0.5f); - glLineWidth(1.0f); - DependencyManager::get()->renderSolidCube(voxelDetails.s, glm::vec4(red, green, blue, opacity)); - glLineWidth(1.0f); - glPopMatrix(); - glEnable(GL_LIGHTING); - - - DependencyManager::get()->end(renderArgs); - - opacity *= (direction == FADE_OUT) ? FADE_OUT_STEP : FADE_IN_STEP; -} - -bool OctreeFade::isDone() const { - if (direction == FADE_OUT) { - return opacity <= FADE_OUT_END; - } else { - return opacity >= FADE_IN_END; - } - return true; // unexpected case, assume we're done -} diff --git a/interface/src/octree/OctreeFade.h b/interface/src/octree/OctreeFade.h deleted file mode 100644 index 137a505537..0000000000 --- a/interface/src/octree/OctreeFade.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// OctreeFade.h -// interface/src/octree -// -// Created by Brad Hefta-Gaub on 8/6/13. -// Copyright 2013 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_OctreeFade_h -#define hifi_OctreeFade_h - -#include // for VoxelPositionSize - -class OctreeFade { -public: - - enum FadeDirection { FADE_OUT, FADE_IN}; - static const float FADE_OUT_START; - static const float FADE_OUT_END; - static const float FADE_OUT_STEP; - static const float FADE_IN_START; - static const float FADE_IN_END; - static const float FADE_IN_STEP; - static const float DEFAULT_RED; - static const float DEFAULT_GREEN; - static const float DEFAULT_BLUE; - - VoxelPositionSize voxelDetails; - FadeDirection direction; - float opacity; - - float red; - float green; - float blue; - - OctreeFade(FadeDirection direction = FADE_OUT, float red = DEFAULT_RED, - float green = DEFAULT_GREEN, float blue = DEFAULT_BLUE); - - void render(RenderArgs* renderArgs); - bool isDone() const; -}; - -#endif // hifi_OctreeFade_h diff --git a/tests/ui/src/main.cpp b/tests/ui/src/main.cpp index 19070e9699..07ff40d738 100644 --- a/tests/ui/src/main.cpp +++ b/tests/ui/src/main.cpp @@ -125,7 +125,7 @@ public: DisplayModelElementProxy, DisplayDebugTimingDetails, DontDoPrecisionPicking, - DontFadeOnOctreeServerChanges, + RESERVED_DontFadeOnOctreeServerChanges, DontRenderEntitiesAsScene, EchoLocalAudio, EchoServerAudio, From dacc6f66c031c302264f939a4eaa0c128d3917f4 Mon Sep 17 00:00:00 2001 From: Niraj Venkat Date: Fri, 10 Jul 2015 17:26:56 -0700 Subject: [PATCH 25/49] Avatars rendered correctly based on Scene.shouldRenderAvatars --- interface/src/avatar/Avatar.h | 8 +++++++ interface/src/avatar/AvatarManager.cpp | 33 ++++++++++++++++++++++++-- interface/src/avatar/AvatarManager.h | 7 ++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index b23059acb0..58e76cd960 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -91,6 +91,14 @@ public: void removeFromScene(AvatarSharedPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); + //For Scene.shouldRenderAvatars + /*bool addToSceneOnStatusUpdate(AvatarSharedPointer self, std::shared_ptr scene, + render::PendingChanges& pendingChanges); + + void removeFromSceneOnStatusUpdate(AvatarSharedPointer self, std::shared_ptr scene, + render::PendingChanges& pendingChanges);*/ + + //setters void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } void setIsLookAtTarget(const bool isLookAtTarget) { _isLookAtTarget = isLookAtTarget; } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 944f16fd34..b4893389c5 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -72,9 +72,13 @@ void AvatarManager::init() { _myAvatar->init(); _avatarHash.insert(MY_AVATAR_KEY, _myAvatar); + connect(&(*DependencyManager::get()), &SceneScriptingInterface::shouldRenderAvatarsChanged, this, &AvatarManager::updateAvatarRenderStatus, Qt::QueuedConnection); + render::ScenePointer scene = Application::getInstance()->getMain3DScene(); render::PendingChanges pendingChanges; - _myAvatar->addToScene(_myAvatar, scene, pendingChanges); + if (DependencyManager::get()->shouldRenderAvatars()) { + _myAvatar->addToScene(_myAvatar, scene, pendingChanges); + } scene->enqueuePendingChanges(pendingChanges); } @@ -158,7 +162,9 @@ AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWe auto avatar = std::dynamic_pointer_cast(AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer)); render::ScenePointer scene = Application::getInstance()->getMain3DScene(); render::PendingChanges pendingChanges; - avatar->addToScene(avatar, scene, pendingChanges); + if (DependencyManager::get()->shouldRenderAvatars()) { + avatar->addToScene(avatar, scene, pendingChanges); + } scene->enqueuePendingChanges(pendingChanges); return avatar; } @@ -310,3 +316,26 @@ void AvatarManager::updateAvatarPhysicsShape(const QUuid& id) { } } } + +void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) { + if (DependencyManager::get()->shouldRenderAvatars()) { + for (auto avatarData : _avatarsLastInScene) { + auto avatar = std::dynamic_pointer_cast(avatarData); + render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::PendingChanges pendingChanges; + avatar->addToScene(avatar, scene, pendingChanges); + scene->enqueuePendingChanges(pendingChanges); + } + _avatarsLastInScene.clear(); + } + else { + _avatarsLastInScene = _avatarHash.values(); + for (auto avatarData : _avatarsLastInScene) { + auto avatar = std::dynamic_pointer_cast(avatarData); + render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::PendingChanges pendingChanges; + avatar->removeFromScene(avatar, scene, pendingChanges); + scene->enqueuePendingChanges(pendingChanges); + } + } +} diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 9d1c94a47e..0e9d1aa01c 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -60,9 +60,13 @@ public: void handleCollisionEvents(CollisionEvents& collisionEvents); void updateAvatarPhysicsShape(const QUuid& id); + + // For Scene.shouldRenderEntities + QList& getAvatarsLastInScene() { return _avatarIDsLastInScene; } public slots: void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; } + void updateAvatarRenderStatus(bool shouldRenderAvatars); private: AvatarManager(QObject* parent = 0); @@ -88,6 +92,9 @@ private: SetOfMotionStates _motionStatesToAdd; VectorOfMotionStates _motionStatesToDelete; VectorOfMotionStates _tempMotionStates; + + // For Scene.shouldRenderAvatars + QList _avatarsLastInScene; }; Q_DECLARE_METATYPE(AvatarManager::LocalLight) From bbd7b2a65e22a4f179de700bd8655cd72e9ed714 Mon Sep 17 00:00:00 2001 From: Niraj Venkat Date: Fri, 10 Jul 2015 17:31:49 -0700 Subject: [PATCH 26/49] Removed unused functions --- interface/src/avatar/Avatar.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 58e76cd960..0bb0309217 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -91,13 +91,6 @@ public: void removeFromScene(AvatarSharedPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); - //For Scene.shouldRenderAvatars - /*bool addToSceneOnStatusUpdate(AvatarSharedPointer self, std::shared_ptr scene, - render::PendingChanges& pendingChanges); - - void removeFromSceneOnStatusUpdate(AvatarSharedPointer self, std::shared_ptr scene, - render::PendingChanges& pendingChanges);*/ - //setters void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } From f95bd3f7bd635469636533d165576c7c5834cb1e Mon Sep 17 00:00:00 2001 From: Niraj Venkat Date: Fri, 10 Jul 2015 17:46:20 -0700 Subject: [PATCH 27/49] Fixing build error --- interface/src/avatar/AvatarManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 0e9d1aa01c..4b0df66439 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -62,7 +62,7 @@ public: void updateAvatarPhysicsShape(const QUuid& id); // For Scene.shouldRenderEntities - QList& getAvatarsLastInScene() { return _avatarIDsLastInScene; } + QList& getAvatarsLastInScene() { return _avatarsLastInScene; } public slots: void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; } From 9ce9c541defef086bf9c24c0e3252a0ced649e71 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 10 Jul 2015 18:45:40 -0700 Subject: [PATCH 28/49] fix activation of object when action changes --- interface/src/avatar/AvatarActionHold.cpp | 2 +- libraries/entities/src/EntityItem.cpp | 6 +++++- .../entities/src/EntityScriptingInterface.cpp | 3 +++ libraries/physics/src/ObjectAction.cpp | 7 +++++++ libraries/physics/src/ObjectAction.h | 1 + libraries/physics/src/ObjectActionOffset.cpp | 6 +----- libraries/physics/src/ObjectActionOffset.h | 1 - libraries/physics/src/ObjectActionSpring.cpp | 20 +++++++------------ libraries/physics/src/ObjectActionSpring.h | 1 - 9 files changed, 25 insertions(+), 22 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 1e75250ee2..0c5145b596 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -127,7 +127,7 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { _mine = true; _active = true; - _needsActivation = true; + activateBody(); unlock(); } return true; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 794d0752a1..024e54dbaa 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1496,7 +1496,7 @@ bool EntityItem::addAction(EntitySimulation* simulation, EntityActionPointer act bool result = addActionInternal(simulation, action); if (!result) { - removeAction(simulation, action->getID()); + removeActionInternal(action->getID()); } unlock(); @@ -1520,6 +1520,7 @@ bool EntityItem::addActionInternal(EntitySimulation* simulation, EntityActionPoi QByteArray newDataCache = serializeActions(success); if (success) { _allActionsDataCache = newDataCache; + _dirtyFlags |= EntityItem::DIRTY_PHYSICS_ACTIVATION; } return success; } @@ -1537,6 +1538,7 @@ bool EntityItem::updateAction(EntitySimulation* simulation, const QUuid& actionI bool success = action->updateArguments(arguments); if (success) { _allActionsDataCache = serializeActions(success); + _dirtyFlags |= EntityItem::DIRTY_PHYSICS_ACTIVATION; } else { qDebug() << "EntityItem::updateAction failed"; } @@ -1572,6 +1574,7 @@ bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulation* s bool success = true; _allActionsDataCache = serializeActions(success); + _dirtyFlags |= EntityItem::DIRTY_PHYSICS_ACTIVATION; return success; } return false; @@ -1590,6 +1593,7 @@ bool EntityItem::clearActions(EntitySimulation* simulation) { // empty _serializedActions means no actions for the EntityItem _actionsToRemove.clear(); _allActionsDataCache.clear(); + _dirtyFlags |= EntityItem::DIRTY_PHYSICS_ACTIVATION; unlock(); return true; } diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index f1c6157694..18175da1f6 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -543,6 +543,9 @@ bool EntityScriptingInterface::actionWorker(const QUuid& entityID, } bool success = actor(simulation, entity); + if (success) { + _entityTree->entityChanged(entity); + } _entityTree->unlock(); // transmit the change diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 101b69f03a..5205e08c62 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -129,3 +129,10 @@ void ObjectAction::setAngularVelocity(glm::vec3 angularVelocity) { rigidBody->activate(); } +void ObjectAction::activateBody() { + auto rigidBody = getRigidBody(); + if (rigidBody) { + rigidBody->activate(); + } +} + diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index f619657e92..f27ed9ab07 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -55,6 +55,7 @@ protected: virtual void setLinearVelocity(glm::vec3 linearVelocity); virtual glm::vec3 getAngularVelocity(); virtual void setAngularVelocity(glm::vec3 angularVelocity); + virtual void activateBody(); void lockForRead() { _lock.lockForRead(); } bool tryLockForRead() { return _lock.tryLockForRead(); } diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp index 00b7fe6734..a00bbbd418 100644 --- a/libraries/physics/src/ObjectActionOffset.cpp +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -59,10 +59,6 @@ void ObjectActionOffset::updateActionWorker(btScalar deltaTimeStep) { const float MAX_LINEAR_TIMESCALE = 600.0f; // 10 minutes is a long time if (_positionalTargetSet && _linearTimeScale < MAX_LINEAR_TIMESCALE) { - if (_needsActivation) { - rigidBody->activate(); - _needsActivation = false; - } glm::vec3 objectPosition = bulletToGLM(rigidBody->getCenterOfMassPosition()); glm::vec3 springAxis = objectPosition - _pointToOffsetFrom; // from anchor to object float distance = glm::length(springAxis); @@ -122,7 +118,7 @@ bool ObjectActionOffset::updateArguments(QVariantMap arguments) { _linearDistance = linearDistance; _positionalTargetSet = true; _active = true; - _needsActivation = true; + activateBody(); unlock(); } return true; diff --git a/libraries/physics/src/ObjectActionOffset.h b/libraries/physics/src/ObjectActionOffset.h index a0190f3832..1918da6996 100644 --- a/libraries/physics/src/ObjectActionOffset.h +++ b/libraries/physics/src/ObjectActionOffset.h @@ -36,7 +36,6 @@ public: float _linearDistance; float _linearTimeScale; bool _positionalTargetSet; - bool _needsActivation = true; }; #endif // hifi_ObjectActionOffset_h diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index c1ef94296a..dde47f7c4e 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -25,8 +25,7 @@ ObjectActionSpring::ObjectActionSpring(const QUuid& id, EntityItemPointer ownerE _positionalTargetSet(true), _rotationalTarget(glm::quat()), _angularTimeScale(FLT_MAX), - _rotationalTargetSet(true), - _needsActivation(true) { + _rotationalTargetSet(true) { #if WANT_DEBUG qDebug() << "ObjectActionSpring::ObjectActionSpring"; #endif @@ -67,10 +66,10 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { if (_linearTimeScale < MAX_TIMESCALE) { btVector3 offset = rigidBody->getCenterOfMassPosition() - glmToBullet(_positionalTarget); float offsetLength = offset.length(); - //float blend = glm::min(1.0f, deltaTimeStep / _linearTimeScale); - float blend = 1.0f; float speed = (offsetLength > FLT_EPSILON) ? glm::min(offsetLength / _linearTimeScale, SPRING_MAX_SPEED) : 0.0f; - rigidBody->setLinearVelocity((1.0f - blend) * rigidBody->getLinearVelocity() - (blend * speed / (offsetLength * _linearTimeScale)) * offset); + + // this action is aggresively critically damped and defeats the current velocity + rigidBody->setLinearVelocity((- speed / offsetLength) * offset); } if (_angularTimeScale < MAX_TIMESCALE) { @@ -98,13 +97,8 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { targetVelocity = (angle / _angularTimeScale) * deltaQ.getAxis(); } } - //float blend = glm::min(1.0f, deltaTimeStep / _angularTimeScale); - float blend = 1.0f; - rigidBody->setAngularVelocity((1.0f - blend) * rigidBody->getAngularVelocity() + blend * targetVelocity); - } - if (_needsActivation) { - rigidBody->activate(); - _needsActivation = false; + // this action is aggresively critically damped and defeats the current velocity + rigidBody->setAngularVelocity(targetVelocity); } unlock(); } @@ -151,7 +145,7 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { _rotationalTarget = rotationalTarget; _angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale)); _active = true; - _needsActivation = true; + activateBody(); unlock(); } return true; diff --git a/libraries/physics/src/ObjectActionSpring.h b/libraries/physics/src/ObjectActionSpring.h index a0a829bdab..caa64c3d3a 100644 --- a/libraries/physics/src/ObjectActionSpring.h +++ b/libraries/physics/src/ObjectActionSpring.h @@ -37,7 +37,6 @@ protected: glm::quat _rotationalTarget; float _angularTimeScale; bool _rotationalTargetSet; - bool _needsActivation; }; #endif // hifi_ObjectActionSpring_h From c17c9f181880b33553201ae1ad9c3c287c11321b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 12 Jul 2015 10:29:43 -0700 Subject: [PATCH 29/49] quiet compiler --- interface/src/ui/overlays/Rectangle3DOverlay.cpp | 5 ++--- libraries/gpu/src/gpu/GLBackend.cpp | 2 +- .../render-utils/src/DeferredLightingEffect.cpp | 9 +++++---- libraries/render/src/render/Scene.cpp | 2 +- libraries/shared/src/PropertyFlags.h | 2 +- tests/entities/src/main.cpp | 14 ++++++++++---- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index ddab8040b1..dfe5a3ad74 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -35,14 +35,13 @@ void Rectangle3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } - + float alpha = getAlpha(); xColor color = getColor(); const float MAX_COLOR = 255.0f; glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); glm::vec3 position = getPosition(); - glm::vec3 center = getCenter(); glm::vec2 dimensions = getDimensions(); glm::vec2 halfDimensions = dimensions * 0.5f; glm::quat rotation = getRotation(); @@ -67,7 +66,7 @@ void Rectangle3DOverlay::render(RenderArgs* args) { glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f); glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f); - + geometryCache->renderDashedLine(*batch, point1, point2, rectangleColor); geometryCache->renderDashedLine(*batch, point2, point3, rectangleColor); geometryCache->renderDashedLine(*batch, point3, point4, rectangleColor); diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index d493978b88..a412c15514 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -238,7 +238,7 @@ void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) { std::vector drawBuffers; if (masks & Framebuffer::BUFFER_COLORS) { - for (int i = 0; i < Framebuffer::MAX_NUM_RENDER_BUFFERS; i++) { + for (unsigned int i = 0; i < Framebuffer::MAX_NUM_RENDER_BUFFERS; i++) { if (masks & (1 << i)) { drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + i); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 9bda5b8048..d46aa4d8d4 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -474,17 +474,18 @@ void DeferredLightingEffect::render(RenderArgs* args) { // IN DEBUG: light->setShowContour(true); batch.setUniformBuffer(_spotLightLocations.lightBufferUnit, light->getSchemaBuffer()); - + auto eyeLightPos = eyePoint - light->getPosition(); auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection()); - + const float TANGENT_LENGTH_SCALE = 0.666f; - glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tan(0.5 * light->getSpotAngle()), 1.0f); + glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f); float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume, // we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working... - if ((eyeHalfPlaneDistance > -nearRadius) && (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) { + if ((eyeHalfPlaneDistance > -nearRadius) && + (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) { coneParam.w = 0.0f; batch._glUniform4fv(_spotLightLocations.coneParam, 1, reinterpret_cast< const GLfloat* >(&coneParam)); diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 268f2b6841..1b52145a1c 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -76,7 +76,7 @@ void Item::Status::Value::setColor(float hue) { } void Item::Status::getPackedValues(glm::ivec4& values) const { - for (unsigned int i = 0; i < values.length(); i++) { + for (unsigned int i = 0; i < (unsigned int)values.length(); i++) { if (i < _values.size()) { values[i] = _values[i]().getPackedData(); } else { diff --git a/libraries/shared/src/PropertyFlags.h b/libraries/shared/src/PropertyFlags.h index b0ac9e76d8..0be7b3af93 100644 --- a/libraries/shared/src/PropertyFlags.h +++ b/libraries/shared/src/PropertyFlags.h @@ -208,7 +208,7 @@ inline size_t PropertyFlags::decode(const uint8_t* data, size_t size) { int bitAt = 0; int expectedBitCount; // unknown at this point int lastValueBit; - for (int byte = 0; byte < size; byte++) { + for (unsigned int byte = 0; byte < size; byte++) { char originalByte = data[byte]; bytesConsumed++; unsigned char maskBit = 0x80; // LEFT MOST BIT set diff --git a/tests/entities/src/main.cpp b/tests/entities/src/main.cpp index 8d16d98103..66daeb2607 100644 --- a/tests/entities/src/main.cpp +++ b/tests/entities/src/main.cpp @@ -73,14 +73,18 @@ template void testByteCountCodedStable(const T& value) { ByteCountCoded coder((T)value); auto encoded = coder.encode(); + #ifndef QT_NO_DEBUG auto originalEncodedSize = encoded.size(); + #endif for (int i = 0; i < 10; ++i) { encoded.append(qrand()); } ByteCountCoded decoder; decoder.decode(encoded); Q_ASSERT(decoder.data == coder.data); + #ifndef QT_NO_DEBUG auto consumed = decoder.decode(encoded.data(), encoded.size()); + #endif Q_ASSERT(consumed == originalEncodedSize); } @@ -100,12 +104,12 @@ void testPropertyFlags(uint32_t value) { EntityPropertyFlags original; original.clear(); auto enumSize = sizeof(EntityPropertyList); - for (size_t i = 0; i < sizeof(EntityPropertyList) * 8; ++i) { + for (size_t i = 0; i < enumSize * 8; ++i) { original.setHasProperty((EntityPropertyList)i); } QByteArray encoded = original.encode(); - auto originalSize = encoded.size(); - for (size_t i = 0; i < sizeof(EntityPropertyList); ++i) { + // auto originalSize = encoded.size(); + for (size_t i = 0; i < enumSize; ++i) { encoded.append(qrand()); } @@ -116,7 +120,9 @@ void testPropertyFlags(uint32_t value) { } { + #ifndef QT_NO_DEBUG auto decodeSize = decodeNew.decode((const uint8_t*)encoded.data(), encoded.size()); + #endif Q_ASSERT(originalSize == decodeSize); Q_ASSERT(decodeNew == original); } @@ -129,7 +135,7 @@ void testPropertyFlags() { testPropertyFlags(0xFFFF); } -int main(int argc, char** argv) { +int main(int argc, char** argv) { QCoreApplication app(argc, argv); { auto start = usecTimestampNow(); From c56b2918a405cb066924134a44a8ae47f3a501b5 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 12 Jul 2015 10:35:44 -0700 Subject: [PATCH 30/49] allow voxels.js to work on an empty voxel-space --- examples/voxels.js | 49 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/examples/voxels.js b/examples/voxels.js index 799af04bef..e110f15260 100644 --- a/examples/voxels.js +++ b/examples/voxels.js @@ -2,6 +2,32 @@ var controlHeld = false; var shiftHeld = false; +function attemptVoxelChange(intersection) { + var ids = Entities.findEntities(intersection.intersection, 10); + var success = false; + for (var i = 0; i < ids.length; i++) { + var id = ids[i]; + if (controlHeld) { + // hold control to erase a sphere + if (Entities.setVoxelSphere(id, intersection.intersection, 1.0, 0)) { + success = true; + } + } else if (shiftHeld) { + // hold shift to set all voxels to 255 + if (Entities.setAllVoxels(id, 255)) { + success = true; + } + } else { + // no modifier key means to add a sphere + if (Entities.setVoxelSphere(id, intersection.intersection, 1.0, 255)) { + success = true; + } + } + } + return success; +} + + function mousePressEvent(event) { if (!event.isLeftButton) { return; @@ -9,20 +35,21 @@ function mousePressEvent(event) { var pickRay = Camera.computePickRay(event.x, event.y); var intersection = Entities.findRayIntersection(pickRay, true); // accurate picking - // var props = Entities.getEntityProperties(intersection.entityID); + + // we've used a picking ray to decide where to add the new sphere of voxels. If we pick nothing + // or if we pick a non-PolyVox entity, we fall through to the next picking attempt. if (intersection.intersects) { - var ids = Entities.findEntities(intersection.intersection, 10); - for (var i = 0; i < ids.length; i++) { - var id = ids[i]; - if (controlHeld) { - Entities.setVoxelSphere(id, intersection.intersection, 1.0, 0); - } else if (shiftHeld) { - Entities.setAllVoxels(id, 255); - } else { - Entities.setVoxelSphere(id, intersection.intersection, 1.0, 255); - } + if (attemptVoxelChange(intersection)) { + return; } } + + // if the PolyVox entity is empty, we can't pick against its voxel. try picking against its + // bounding box, instead. + intersection = Entities.findRayIntersection(pickRay, false); // bounding box picking + if (intersection.intersects) { + attemptVoxelChange(intersection); + } } From 848e5bcebf2a1a925c1a53b3e4a49fc43baed69c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 12 Jul 2015 13:43:21 -0700 Subject: [PATCH 31/49] this code can be called for hold actions if they end up in an svo save. revert a line from a previous commit --- libraries/physics/src/ObjectActionSpring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index dde47f7c4e..196cc8d3ea 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -189,7 +189,7 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) { EntityActionType type; dataStream >> type; - assert(type == ACTION_TYPE_SPRING); + assert(type == getType()); QUuid id; dataStream >> id; From 29333d0cad6a864423cd66e0664759769957deca Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 12 Jul 2015 18:52:15 -0700 Subject: [PATCH 32/49] Qt5.5 fixes --- libraries/avatars/src/AvatarHashMap.cpp | 2 ++ libraries/networking/src/DataServerAccountInfo.cpp | 1 + libraries/networking/src/DomainHandler.cpp | 1 + libraries/networking/src/JSONBreakableMarshal.h | 1 + libraries/networking/src/NetworkPeer.cpp | 1 + libraries/ui/src/VrMenu.cpp | 8 ++++---- 6 files changed, 10 insertions(+), 4 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 6d0d9d8d76..bf7a1a4464 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include #include #include diff --git a/libraries/networking/src/DataServerAccountInfo.cpp b/libraries/networking/src/DataServerAccountInfo.cpp index fd2c6da13d..a85aa588a8 100644 --- a/libraries/networking/src/DataServerAccountInfo.cpp +++ b/libraries/networking/src/DataServerAccountInfo.cpp @@ -13,6 +13,7 @@ #include #include +#include #include "NetworkLogging.h" #include "DataServerAccountInfo.h" diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 38d1ade2ad..5f21708d28 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -12,6 +12,7 @@ #include #include +#include #include "Assignment.h" #include "HifiSockAddr.h" diff --git a/libraries/networking/src/JSONBreakableMarshal.h b/libraries/networking/src/JSONBreakableMarshal.h index cbcc454f5a..287fed675a 100644 --- a/libraries/networking/src/JSONBreakableMarshal.h +++ b/libraries/networking/src/JSONBreakableMarshal.h @@ -17,6 +17,7 @@ #include #include #include +#include class JSONBreakableMarshal { public: diff --git a/libraries/networking/src/NetworkPeer.cpp b/libraries/networking/src/NetworkPeer.cpp index dfa4066dd2..2e98c096ab 100644 --- a/libraries/networking/src/NetworkPeer.cpp +++ b/libraries/networking/src/NetworkPeer.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp index 1b402ff2a3..4c83e6e3cd 100644 --- a/libraries/ui/src/VrMenu.cpp +++ b/libraries/ui/src/VrMenu.cpp @@ -102,13 +102,15 @@ class QQuickMenuItem; QObject* addItem(QObject* parent, const QString& text) { // FIXME add more checking here to ensure no name conflicts QQuickMenuItem* returnedValue{ nullptr }; - #ifndef QT_NO_DEBUG bool invokeResult = - #endif QMetaObject::invokeMethod(parent, "addItem", Qt::DirectConnection, Q_RETURN_ARG(QQuickMenuItem*, returnedValue), Q_ARG(QString, text)); +#ifndef QT_NO_DEBUG Q_ASSERT(invokeResult); +#else + Q_UNUSED(invokeResult); +#endif QObject* result = reinterpret_cast(returnedValue); return result; } @@ -206,9 +208,7 @@ void VrMenu::insertAction(QAction* before, QAction* action) { result = ::addItem(menu, action->text()); } else { QQuickMenuItem* returnedValue{ nullptr }; - #ifndef QT_NO_DEBUG bool invokeResult = - #endif QMetaObject::invokeMethod(menu, "insertItem", Qt::DirectConnection, Q_RETURN_ARG(QQuickMenuItem*, returnedValue), Q_ARG(int, index), Q_ARG(QString, action->text())); Q_ASSERT(invokeResult); From f011d5c7f766616b731c73e080f1d960e34d1e58 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 12 Jul 2015 20:42:17 -0700 Subject: [PATCH 33/49] remove commented code --- tests/entities/src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/entities/src/main.cpp b/tests/entities/src/main.cpp index 66daeb2607..6aa021d1b2 100644 --- a/tests/entities/src/main.cpp +++ b/tests/entities/src/main.cpp @@ -108,7 +108,6 @@ void testPropertyFlags(uint32_t value) { original.setHasProperty((EntityPropertyList)i); } QByteArray encoded = original.encode(); - // auto originalSize = encoded.size(); for (size_t i = 0; i < enumSize; ++i) { encoded.append(qrand()); } From 5aca0c28ef15e7b6c7faf294cafa73659204e56a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 13 Jul 2015 07:37:59 -0700 Subject: [PATCH 34/49] quiet compiler --- libraries/entities/src/EntityItem.cpp | 24 ++++++++++++------------ libraries/gpu/src/gpu/GLBackend.cpp | 1 - tests/entities/src/main.cpp | 7 +++++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 794d0752a1..592382286a 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -385,7 +385,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef dataAt += encodedID.size(); bytesRead += encodedID.size(); Q_ASSERT(id == _id); - Q_ASSERT(parser.offset() == bytesRead); + Q_ASSERT(parser.offset() == (unsigned int) bytesRead); } #endif @@ -400,8 +400,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef quint32 type = typeCoder; EntityTypes::EntityType oldType = (EntityTypes::EntityType)type; Q_ASSERT(oldType == _type); - Q_ASSERT(parser.offset() == bytesRead); -#endif + Q_ASSERT(parser.offset() == (unsigned int) bytesRead); +#endif bool overwriteLocalData = true; // assume the new content overwrites our local data quint64 now = usecTimestampNow(); @@ -417,9 +417,9 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef dataAt += sizeof(createdFromBuffer2); bytesRead += sizeof(createdFromBuffer2); Q_ASSERT(createdFromBuffer2 == createdFromBuffer); - Q_ASSERT(parser.offset() == bytesRead); + Q_ASSERT(parser.offset() == (unsigned int) bytesRead); } -#endif +#endif if (_created == UNKNOWN_CREATED_TIME) { // we don't yet have a _created timestamp, so we accept this one createdFromBuffer -= clockSkew; @@ -458,9 +458,9 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef dataAt += sizeof(lastEditedFromBuffer2); bytesRead += sizeof(lastEditedFromBuffer2); Q_ASSERT(lastEditedFromBuffer2 == lastEditedFromBuffer); - Q_ASSERT(parser.offset() == bytesRead); + Q_ASSERT(parser.offset() == (unsigned int) bytesRead); } -#endif +#endif quint64 lastEditedFromBufferAdjusted = lastEditedFromBuffer - clockSkew; if (lastEditedFromBufferAdjusted > now) { lastEditedFromBufferAdjusted = now; @@ -534,10 +534,10 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef encodedUpdateDelta = updateDeltaCoder; // determine true length dataAt += encodedUpdateDelta.size(); bytesRead += encodedUpdateDelta.size(); - Q_ASSERT(parser.offset() == bytesRead); + Q_ASSERT(parser.offset() == (unsigned int) bytesRead); } -#endif - +#endif + if (overwriteLocalData) { _lastUpdated = lastEditedFromBufferAdjusted + updateDelta; // don't adjust for clock skew since we already did that #ifdef WANT_DEBUG @@ -562,7 +562,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef encodedSimulatedDelta = simulatedDeltaCoder; // determine true length dataAt += encodedSimulatedDelta.size(); bytesRead += encodedSimulatedDelta.size(); - Q_ASSERT(parser.offset() == bytesRead); + Q_ASSERT(parser.offset() == (unsigned int) bytesRead); } #endif @@ -599,7 +599,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef dataAt += propertyFlags.getEncodedLength(); bytesRead += propertyFlags.getEncodedLength(); Q_ASSERT(propertyFlags2 == propertyFlags); - Q_ASSERT(parser.offset() == bytesRead); + Q_ASSERT(parser.offset() == (unsigned int)bytesRead); } #endif diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index a412c15514..55aaa12e4e 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -204,7 +204,6 @@ void GLBackend::do_drawInstanced(Batch& batch, uint32 paramOffset) { GLenum mode = _primitiveToGLmode[primitiveType]; uint32 numVertices = batch._params[paramOffset + 2]._uint; uint32 startVertex = batch._params[paramOffset + 1]._uint; - uint32 startInstance = batch._params[paramOffset + 0]._uint; glDrawArraysInstancedARB(mode, startVertex, numVertices, numInstances); (void) CHECK_GL_ERROR(); diff --git a/tests/entities/src/main.cpp b/tests/entities/src/main.cpp index 6aa021d1b2..72dbf77dfa 100644 --- a/tests/entities/src/main.cpp +++ b/tests/entities/src/main.cpp @@ -85,7 +85,7 @@ void testByteCountCodedStable(const T& value) { #ifndef QT_NO_DEBUG auto consumed = decoder.decode(encoded.data(), encoded.size()); #endif - Q_ASSERT(consumed == originalEncodedSize); + Q_ASSERT(consumed == (unsigned int)originalEncodedSize); } @@ -108,6 +108,9 @@ void testPropertyFlags(uint32_t value) { original.setHasProperty((EntityPropertyList)i); } QByteArray encoded = original.encode(); + #ifndef QT_NO_DEBUG + auto originalSize = encoded.size(); + #endif for (size_t i = 0; i < enumSize; ++i) { encoded.append(qrand()); } @@ -123,7 +126,7 @@ void testPropertyFlags(uint32_t value) { auto decodeSize = decodeNew.decode((const uint8_t*)encoded.data(), encoded.size()); #endif Q_ASSERT(originalSize == decodeSize); - Q_ASSERT(decodeNew == original); + Q_ASSERT(decodeNew == (unsigned int) original); } } From 7a6cf40b546753ddaa1b54ae65b0f1464549fe24 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 13 Jul 2015 07:39:11 -0700 Subject: [PATCH 35/49] quiet compiler --- tests/entities/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/entities/src/main.cpp b/tests/entities/src/main.cpp index 72dbf77dfa..a255ffa995 100644 --- a/tests/entities/src/main.cpp +++ b/tests/entities/src/main.cpp @@ -126,7 +126,7 @@ void testPropertyFlags(uint32_t value) { auto decodeSize = decodeNew.decode((const uint8_t*)encoded.data(), encoded.size()); #endif Q_ASSERT(originalSize == decodeSize); - Q_ASSERT(decodeNew == (unsigned int) original); + Q_ASSERT(decodeNew == original); } } From d44bb1a0d8a580a960a95e4fe174748f52f47192 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 13 Jul 2015 11:42:29 -0700 Subject: [PATCH 36/49] update javascript to use relative-to-entity line-point ends --- examples/pointer.js | 97 +++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 56 deletions(-) diff --git a/examples/pointer.js b/examples/pointer.js index 83e2cbf776..2791e06466 100644 --- a/examples/pointer.js +++ b/examples/pointer.js @@ -65,70 +65,55 @@ function removeLine() { function createOrUpdateLine(event) { - var pickRay = Camera.computePickRay(event.x, event.y); - var intersection = Entities.findRayIntersection(pickRay, true); // accurate picking - var props = Entities.getEntityProperties(intersection.entityID); + var pickRay = Camera.computePickRay(event.x, event.y); + var intersection = Entities.findRayIntersection(pickRay, true); // accurate picking + var props = Entities.getEntityProperties(intersection.entityID); - if (intersection.intersects && userCanPoint) { - var points = [nearLinePoint(intersection.intersection), intersection.intersection] - if (lineIsRezzed) { - Entities.editEntity(lineEntityID, { - position: nearLinePoint(intersection.intersection), - linePoints: points, - dimensions: { - x: 1, - y: 1, - z: 1 - }, - lifetime: 15 + props.lifespan // renew lifetime - }); + if (intersection.intersects && userCanPoint) { + var points = [Vec3.subtract(nearLinePoint(intersection.intersection), MyAvatar.position), + Vec3.subtract(intersection.intersection, MyAvatar.position)]; + if (lineIsRezzed) { + Entities.editEntity(lineEntityID, { + linePoints: points, + position: MyAvatar.position, + lifetime: 15 + props.lifespan // renew lifetime + }); + // Entities.setAllPoints(lineEntityID, points); + } else { + lineIsRezzed = true; + lineEntityID = Entities.addEntity({ + type: "Line", + position: MyAvatar.position, + linePoints: points, + dimensions: { x: 100, y: 100, z: 100 }, + color: { red: 255, green: 255, blue: 255 }, + lifetime: 15 // if someone crashes while pointing, don't leave the line there forever. + }); + } } else { - lineIsRezzed = true; - lineEntityID = Entities.addEntity({ - type: "Line", - position: nearLinePoint(intersection.intersection), - linePoints: points, - dimensions: { - x: 1, - y: 1, - z: 1 - }, - color: { - red: 255, - green: 255, - blue: 255 - }, - lifetime: 15 // if someone crashes while pointing, don't leave the line there forever. - }); + removeLine(); } - } else { - removeLine(); - } } function mousePressEvent(event) { - if (!event.isLeftButton) { - return; - } - - createOrUpdateLine(event); - var clickedOverlay = Overlays.getOverlayAtPoint({ - x: event.x, - y: event.y - }); - if (clickedOverlay == pointerButton) { - userCanPoint = !userCanPoint; - if (userCanPoint === true) { - Overlays.editOverlay(pointerButton, { - color: buttonOnColor - }); - } else { - Overlays.editOverlay(pointerButton, { - color: buttonOffColor - }); + if (!event.isLeftButton) { + return; + } + + var clickedOverlay = Overlays.getOverlayAtPoint({ + x: event.x, + y: event.y + }); + + if (clickedOverlay == pointerButton) { + userCanPoint = !userCanPoint; + if (userCanPoint === true) { + Overlays.editOverlay(pointerButton, { color: buttonOnColor }); + } else { + Overlays.editOverlay(pointerButton, { color: buttonOffColor }); + } } - } } From 59f456a2f2fcd4da47f4641052c9847b1a9cf9d6 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 13 Jul 2015 14:16:39 -0700 Subject: [PATCH 37/49] Add an "is looking at me" indicator above avatars' heads Menu item: Developer > Avatar > Show Who's Looking at Me --- interface/src/Menu.cpp | 1 + interface/src/Menu.h | 1 + interface/src/avatar/Avatar.cpp | 34 +++++++++++++++++++++++---------- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 9f49361f79..d22b80975d 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -458,6 +458,7 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderBoundingCollisionShapes); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderLookAtVectors, 0, false); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderFocusIndicator, 0, false); + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowWhosLookingAtMe, 0, false); MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 043bb53a7f..3745f1e766 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -270,6 +270,7 @@ namespace MenuOption { const QString ShowBordersEntityNodes = "Show Entity Nodes"; const QString ShowIKConstraints = "Show IK Constraints"; const QString ShowRealtimeEntityStats = "Show Realtime Entity Stats"; + const QString ShowWhosLookingAtMe = "Show Who's Looking at Me"; const QString SimpleShadows = "Simple"; const QString SixenseEnabled = "Enable Hydra Support"; const QString SixenseMouseInput = "Enable Sixense Mouse Input"; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 0dde96c7ce..d026457457 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -453,22 +453,36 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo } } + // Stack indicator spheres + float indicatorOffset = 0.0f; + if (!_displayName.isEmpty() && _displayNameAlpha != 0.0f) { + const float DISPLAY_NAME_INDICATOR_OFFSET = 0.22f; + indicatorOffset = DISPLAY_NAME_INDICATOR_OFFSET; + } + const float INDICATOR_RADIUS = 0.03f; + const float INDICATOR_INDICATOR_OFFSET = 3.0f * INDICATOR_RADIUS; + // If this is the avatar being looked at, render a little ball above their head if (_isLookAtTarget && Menu::getInstance()->isOptionChecked(MenuOption::RenderFocusIndicator)) { - const float LOOK_AT_INDICATOR_RADIUS = 0.03f; - const float LOOK_AT_INDICATOR_OFFSET = 0.22f; const glm::vec4 LOOK_AT_INDICATOR_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f }; - glm::vec3 position; - if (_displayName.isEmpty() || _displayNameAlpha == 0.0f) { - position = glm::vec3(_position.x, getDisplayNamePosition().y, _position.z); - } else { - position = glm::vec3(_position.x, getDisplayNamePosition().y + LOOK_AT_INDICATOR_OFFSET, _position.z); - } + glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + indicatorOffset, _position.z); Transform transform; transform.setTranslation(position); batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphere(batch, LOOK_AT_INDICATOR_RADIUS - , 15, 15, LOOK_AT_INDICATOR_COLOR); + DependencyManager::get()->renderSolidSphere(batch, INDICATOR_RADIUS, + 15, 15, LOOK_AT_INDICATOR_COLOR); + indicatorOffset += INDICATOR_INDICATOR_OFFSET; + } + + // If the avatar is looking at me, render an indication that they area + if (getHead()->getIsLookingAtMe() && Menu::getInstance()->isOptionChecked(MenuOption::ShowWhosLookingAtMe)) { + const glm::vec4 LOOKING_AT_ME_COLOR = { 0.8f, 0.65f, 0.0f, 0.1f }; + glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + indicatorOffset, _position.z); + Transform transform; + transform.setTranslation(position); + batch.setModelTransform(transform); + DependencyManager::get()->renderSolidSphere(batch, INDICATOR_RADIUS, + 15, 15, LOOKING_AT_ME_COLOR); } // quick check before falling into the code below: From 10e0a93ac096e460078cd56790f65afe4de691d4 Mon Sep 17 00:00:00 2001 From: Niraj Venkat Date: Mon, 13 Jul 2015 15:22:00 -0700 Subject: [PATCH 38/49] Fix for avatar rendering not working on domain exit/entry --- interface/src/avatar/AvatarManager.cpp | 6 ++---- interface/src/avatar/AvatarManager.h | 5 ----- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index b4893389c5..f5a352bcca 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -319,18 +319,16 @@ void AvatarManager::updateAvatarPhysicsShape(const QUuid& id) { void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) { if (DependencyManager::get()->shouldRenderAvatars()) { - for (auto avatarData : _avatarsLastInScene) { + for (auto avatarData : _avatarHash) { auto avatar = std::dynamic_pointer_cast(avatarData); render::ScenePointer scene = Application::getInstance()->getMain3DScene(); render::PendingChanges pendingChanges; avatar->addToScene(avatar, scene, pendingChanges); scene->enqueuePendingChanges(pendingChanges); } - _avatarsLastInScene.clear(); } else { - _avatarsLastInScene = _avatarHash.values(); - for (auto avatarData : _avatarsLastInScene) { + for (auto avatarData : _avatarHash) { auto avatar = std::dynamic_pointer_cast(avatarData); render::ScenePointer scene = Application::getInstance()->getMain3DScene(); render::PendingChanges pendingChanges; diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 4b0df66439..06509d8f75 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -60,9 +60,6 @@ public: void handleCollisionEvents(CollisionEvents& collisionEvents); void updateAvatarPhysicsShape(const QUuid& id); - - // For Scene.shouldRenderEntities - QList& getAvatarsLastInScene() { return _avatarsLastInScene; } public slots: void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; } @@ -93,8 +90,6 @@ private: VectorOfMotionStates _motionStatesToDelete; VectorOfMotionStates _tempMotionStates; - // For Scene.shouldRenderAvatars - QList _avatarsLastInScene; }; Q_DECLARE_METATYPE(AvatarManager::LocalLight) From 5676246d751f2b1f5fe64e1ef91037b2e1acc86c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 13 Jul 2015 15:26:52 -0700 Subject: [PATCH 39/49] fix the lingering model parts sometimes left behind when switching domains --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 7 +++++-- .../entities-renderer/src/RenderableModelEntityItem.cpp | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 11d24c6d9d..6be891e147 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -93,16 +93,18 @@ void EntityTreeRenderer::clear() { foreach (const EntityItemID& entityID, _entityScripts.keys()) { checkAndCallUnload(entityID); } - OctreeRenderer::clear(); _entityScripts.clear(); auto scene = _viewState->getMain3DScene(); render::PendingChanges pendingChanges; + foreach(auto entity, _entitiesInScene) { entity->removeFromScene(entity, scene, pendingChanges); } scene->enqueuePendingChanges(pendingChanges); _entitiesInScene.clear(); + + OctreeRenderer::clear(); } void EntityTreeRenderer::init() { @@ -1003,7 +1005,7 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { checkAndCallUnload(entityID); } _entityScripts.remove(entityID); - + // here's where we remove the entity payload from the scene if (_entitiesInScene.contains(entityID)) { auto entity = _entitiesInScene.take(entityID); @@ -1164,6 +1166,7 @@ void EntityTreeRenderer::updateEntityRenderStatus(bool shouldRenderEntities) { } else { _entityIDsLastInScene = _entitiesInScene.keys(); for (auto entityID : _entityIDsLastInScene) { + // FIXME - is this really right? do we want to do the deletingEntity() code or just remove from the scene. deletingEntity(entityID); } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 85b7bafc78..2deb34d1f8 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -189,6 +189,7 @@ void makeEntityItemStatusGetters(RenderableModelEntityItem* entity, render::Item bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) { + _myMetaItem = scene->allocateID(); auto renderData = RenderableModelEntityItemMeta::Pointer(new RenderableModelEntityItemMeta(self)); @@ -199,7 +200,10 @@ bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_p if (_model) { render::Item::Status::Getters statusGetters; makeEntityItemStatusGetters(this, statusGetters); - return _model->addToScene(scene, pendingChanges, statusGetters); + + // note: we don't care if the model fails to add items, we always added our meta item and therefore we return + // true so that the system knows our meta item is in the scene! + _model->addToScene(scene, pendingChanges, statusGetters); } return true; From 4743bbad8051c4cf4f716035323c8b1a4cbb2f7f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 13 Jul 2015 16:18:39 -0700 Subject: [PATCH 40/49] Adding shaders to the lib for rendering simple textured quad and solve the ImageOverlay issue for edit.js --- interface/src/ui/ApplicationOverlay.cpp | 1 + interface/src/ui/overlays/ImageOverlay.cpp | 49 ++++++++++++++++++- interface/src/ui/overlays/Overlays.cpp | 5 +- libraries/gpu/src/gpu/DrawColoredTexture.slf | 22 +++++++++ .../gpu/DrawTexcoordRectTransformUnitQuad.slv | 39 +++++++++++++++ libraries/gpu/src/gpu/StandardShaderLib.cpp | 46 +++++++++++++++++ libraries/gpu/src/gpu/StandardShaderLib.h | 15 ++++++ .../src/DeferredLightingEffect.cpp | 6 +-- 8 files changed, 178 insertions(+), 5 deletions(-) create mode 100755 libraries/gpu/src/gpu/DrawColoredTexture.slf create mode 100755 libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 9f742093ee..44904a8655 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -127,6 +127,7 @@ void ApplicationOverlay::renderOverlays(RenderArgs* renderArgs) { glDisable(GL_LIGHTING); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glUseProgram(0); // give external parties a change to hook in emit qApp->renderingOverlay(); diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index 7a0c3c00c3..360eb3261d 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -14,6 +14,11 @@ #include #include +#include "qapplication.h" + +#include "gpu/Context.h" +#include "gpu/StandardShaderLib.h" + ImageOverlay::ImageOverlay() : _imageURL(), _renderImage(false), @@ -57,15 +62,42 @@ void ImageOverlay::render(RenderArgs* args) { return; } + // TODO: I commented all the code needed to migrate this ImageOverlay rendering from naked gl to gpu::Batch + /*gpu::Batch localBatch; + gpu::Batch& batch = (args->_batch ? (*args->_batch) : localBatch); + static gpu::PipelinePointer drawPipeline; + static int texcoordRectLoc = -1; + static int colorLoc = -1; + if (!drawPipeline) { + auto blitProgram = gpu::StandardShaderLib::getProgram(gpu::StandardShaderLib::getDrawTexcoordRectTransformUnitQuadVS, gpu::StandardShaderLib::getDrawColoredTexturePS); + gpu::Shader::makeProgram(*blitProgram); + texcoordRectLoc = blitProgram->getUniforms().findLocation("texcoordRect"); + colorLoc = blitProgram->getUniforms().findLocation("color"); + + gpu::StatePointer blitState = gpu::StatePointer(new gpu::State()); + blitState->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + blitState->setColorWriteMask(true, true, true, true); + drawPipeline = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState)); + } + */ + // TODO: batch.setPipeline(drawPipeline); + glUseProgram(0); + if (_renderImage) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, _texture->getID()); - } + // TODO: batch.setResourceTexture(0, _texture->getGPUTexture()); + } // TODO: else { + // TODO: batch.setResourceTexture(0, args->_whiteTexture); + // TODO: } + + // TODO: batch.setViewTransform(Transform()); const float MAX_COLOR = 255.0f; xColor color = getColor(); float alpha = getAlpha(); glm::vec4 quadColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + // TODO: batch._glUniform4fv(colorLoc, 1, (const float*) &quadColor); int left = _bounds.left(); int right = _bounds.right() + 1; @@ -75,6 +107,12 @@ void ImageOverlay::render(RenderArgs* args) { glm::vec2 topLeft(left, top); glm::vec2 bottomRight(right, bottom); + // TODO: Transform model; + // TODO: model.setTranslation(glm::vec3(0.5f * (right + left), 0.5f * (top + bottom), 0.0f)); + // TODO: model.setScale(glm::vec3(0.5f * (right - left), 0.5f * (bottom - top), 1.0f)); + // TODO: batch.setModelTransform(model); + + // if for some reason our image is not over 0 width or height, don't attempt to render the image if (_renderImage) { float imageWidth = _texture->getWidth(); @@ -104,15 +142,24 @@ void ImageOverlay::render(RenderArgs* args) { glm::vec2 texCoordTopLeft(x, y); glm::vec2 texCoordBottomRight(x + w, y + h); + glm::vec4 texcoordRect(texCoordTopLeft, w, h); + // TODO: batch._glUniform4fv(texcoordRectLoc, 1, (const float*) &texcoordRect); + // TODO: batch.draw(gpu::TRIANGLE_STRIP, 4); DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor); } else { + // TODO: batch.draw(gpu::TRIANGLE_STRIP, 4); DependencyManager::get()->renderQuad(topLeft, bottomRight, quadColor); } glDisable(GL_TEXTURE_2D); } else { + // TODO: batch.draw(gpu::TRIANGLE_STRIP, 4); DependencyManager::get()->renderQuad(topLeft, bottomRight, quadColor); } + + // TODO: if (!args->_batch) { + // TODO: args->_context->render(batch); + // TODO: } } void ImageOverlay::setProperties(const QScriptValue& properties) { diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index db1bc2185a..94d8bd17ca 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -115,7 +115,10 @@ void Overlays::renderHUD(RenderArgs* renderArgs) { thisOverlay->render(renderArgs); } } - gpu::GLBackend::renderBatch(batch, true); + + renderArgs->_context->syncCache(); + renderArgs->_context->render(batch); +// gpu::GLBackend::renderBatch(batch, true); } unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& properties) { diff --git a/libraries/gpu/src/gpu/DrawColoredTexture.slf b/libraries/gpu/src/gpu/DrawColoredTexture.slf new file mode 100755 index 0000000000..b60c7d9575 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawColoredTexture.slf @@ -0,0 +1,22 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw texture 0 fetched at texcoord.xy, Blend with color uniform +// +// Created by Sam Gateau on 7/12/2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +uniform sampler2D colorMap; +uniform vec4 color; + +varying vec2 varTexcoord; + +void main(void) { + gl_FragColor = texture2D(colorMap, varTexcoord) * color; +} diff --git a/libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv b/libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv new file mode 100755 index 0000000000..284f68dd93 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv @@ -0,0 +1,39 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw and transform the unit quad [-1,-1 -> 1,1] +// Transform the normalized texcoords [0, 1] to be in the range [texcoordRect.xy, texcoordRect.xy + texcoordRect.zw] +// Simply draw a Triangle_strip of 2 triangles, no input buffers or index buffer needed +// +// Created by Sam Gateau on 6/22/2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include gpu/Transform.slh@> + +<$declareStandardTransform()$> + +uniform vec4 texcoordRect; + +varying vec2 varTexcoord; + +void main(void) { + const vec4 UNIT_QUAD[4] = vec4[4]( + vec4(-1.0, -1.0, 0.0, 1.0), + vec4(1.0, -1.0, 0.0, 1.0), + vec4(-1.0, 1.0, 0.0, 1.0), + vec4(1.0, 1.0, 0.0, 1.0) + ); + vec4 pos = UNIT_QUAD[gl_VertexID]; + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToClipPos(cam, obj, pos, gl_Position)$> + + varTexcoord = ((pos.xy + 1) * 0.5) * texcoordRect.zw + texcoordRect.xy; +} diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index 581ce47cde..dabeeaf770 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -13,14 +13,46 @@ #include "StandardShaderLib.h" #include "DrawTransformUnitQuad_vert.h" +#include "DrawTexcoordRectTransformUnitQuad_vert.h" #include "DrawViewportQuadTransformTexcoord_vert.h" #include "DrawTexture_frag.h" +#include "DrawColoredTexture_frag.h" using namespace gpu; ShaderPointer StandardShaderLib::_drawTransformUnitQuadVS; +ShaderPointer StandardShaderLib::_drawTexcoordRectTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawViewportQuadTransformTexcoordVS; ShaderPointer StandardShaderLib::_drawTexturePS; +ShaderPointer StandardShaderLib::_drawColoredTexturePS; +StandardShaderLib::ProgramMap StandardShaderLib::_programs; + +ShaderPointer StandardShaderLib::getProgram(GetShader getVS, GetShader getPS) { + + auto& programIt = _programs.find(std::pair(getVS, getPS)); + if (programIt != _programs.end()) { + return (*programIt).second; + } else { + auto vs = getVS(); + auto ps = getPS(); + auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); + if (program) { + // Program created, let's try to make it + if (gpu::Shader::makeProgram((*program))) { + // All good, backup and return that program + _programs.insert(ProgramMap::value_type(std::pair(getVS, getPS), program)); + return program; + } else { + // Failed to make the program probably because vs and ps cannot work together? + } + } else { + // Failed to create the program maybe because ps and vs are not true vertex and pixel shaders? + } + } + return ShaderPointer(); +} + + ShaderPointer StandardShaderLib::getDrawTransformUnitQuadVS() { if (!_drawTransformUnitQuadVS) { @@ -29,6 +61,13 @@ ShaderPointer StandardShaderLib::getDrawTransformUnitQuadVS() { return _drawTransformUnitQuadVS; } +ShaderPointer StandardShaderLib::getDrawTexcoordRectTransformUnitQuadVS() { + if (!_drawTexcoordRectTransformUnitQuadVS) { + _drawTexcoordRectTransformUnitQuadVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(DrawTexcoordRectTransformUnitQuad_vert))); + } + return _drawTexcoordRectTransformUnitQuadVS; +} + ShaderPointer StandardShaderLib::getDrawViewportQuadTransformTexcoordVS() { if (!_drawViewportQuadTransformTexcoordVS) { _drawViewportQuadTransformTexcoordVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(DrawViewportQuadTransformTexcoord_vert))); @@ -42,3 +81,10 @@ ShaderPointer StandardShaderLib::getDrawTexturePS() { } return _drawTexturePS; } + +ShaderPointer StandardShaderLib::getDrawColoredTexturePS() { + if (!_drawColoredTexturePS) { + _drawColoredTexturePS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(DrawColoredTexture_frag))); + } + return _drawColoredTexturePS; +} diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index a8fc5126f8..653c4ab120 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -14,6 +14,7 @@ #define hifi_gpu_StandardShaderLib_h #include +#include #include "Shader.h" @@ -26,16 +27,30 @@ public: // A texcoord attribute is also generated texcoord = [(0,0),(1,1)] static ShaderPointer getDrawTransformUnitQuadVS(); + // Shader draw the unit quad objectPos = ([(-1,-1),(1,1)]) and transform it by the full model transform stack (Model, View, Proj). + // A texcoord attribute is also generated covering a rect defined from the uniform vec4 texcoordRect: texcoord = [texcoordRect.xy,texcoordRect.xy + texcoordRect.zw] + static ShaderPointer getDrawTexcoordRectTransformUnitQuadVS(); + // Shader draws the unit quad in the full viewport clipPos = ([(-1,-1),(1,1)]) and transform the texcoord = [(0,0),(1,1)] by the model transform. static ShaderPointer getDrawViewportQuadTransformTexcoordVS(); static ShaderPointer getDrawTexturePS(); + static ShaderPointer getDrawColoredTexturePS(); + + // The shader program combining the shaders available above, so they are unique + typedef ShaderPointer (*StandardShaderLib::GetShader) (); + static ShaderPointer getProgram(GetShader vs, GetShader ps); protected: static ShaderPointer _drawTransformUnitQuadVS; + static ShaderPointer _drawTexcoordRectTransformUnitQuadVS; static ShaderPointer _drawViewportQuadTransformTexcoordVS; static ShaderPointer _drawTexturePS; + static ShaderPointer _drawColoredTexturePS; + + typedef std::map, ShaderPointer> ProgramMap; + static ProgramMap _programs; }; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 5d4a7adea8..4c321f8fd9 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -114,9 +114,9 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { loadLightProgram(deferred_light_spot_vert, spot_light_frag, true, _spotLight, _spotLightLocations); { - auto VSFS = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); - auto PSBlit = gpu::StandardShaderLib::getDrawTexturePS(); - auto blitProgram = gpu::ShaderPointer(gpu::Shader::createProgram(VSFS, PSBlit)); + //auto VSFS = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); + //auto PSBlit = gpu::StandardShaderLib::getDrawTexturePS(); + auto blitProgram = gpu::StandardShaderLib::getProgram(gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS, gpu::StandardShaderLib::getDrawTexturePS); gpu::Shader::makeProgram(*blitProgram); gpu::StatePointer blitState = gpu::StatePointer(new gpu::State()); blitState->setBlendFunction(true, From f08c608195de1a459e1039fa4de0bb69ef09c518 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 13 Jul 2015 16:33:04 -0700 Subject: [PATCH 41/49] Remove dead code --- interface/src/ui/overlays/Overlays.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 94d8bd17ca..57de4915ee 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -118,7 +118,6 @@ void Overlays::renderHUD(RenderArgs* renderArgs) { renderArgs->_context->syncCache(); renderArgs->_context->render(batch); -// gpu::GLBackend::renderBatch(batch, true); } unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& properties) { From 99ae0326ad754f1d0f9258f57198c418c0676272 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 13 Jul 2015 19:17:09 -0700 Subject: [PATCH 42/49] FIxing th ecompilation issue on mac, ready to ship --- libraries/gpu/src/gpu/StandardShaderLib.cpp | 6 +++--- libraries/gpu/src/gpu/StandardShaderLib.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index dabeeaf770..1c1cca458a 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -29,12 +29,12 @@ StandardShaderLib::ProgramMap StandardShaderLib::_programs; ShaderPointer StandardShaderLib::getProgram(GetShader getVS, GetShader getPS) { - auto& programIt = _programs.find(std::pair(getVS, getPS)); + auto programIt = _programs.find(std::pair(getVS, getPS)); if (programIt != _programs.end()) { return (*programIt).second; } else { - auto vs = getVS(); - auto ps = getPS(); + auto vs = (getVS)(); + auto ps = (getPS)(); auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); if (program) { // Program created, let's try to make it diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index 653c4ab120..d5a3685feb 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -38,7 +38,7 @@ public: static ShaderPointer getDrawColoredTexturePS(); // The shader program combining the shaders available above, so they are unique - typedef ShaderPointer (*StandardShaderLib::GetShader) (); + typedef ShaderPointer (*GetShader) (); static ShaderPointer getProgram(GetShader vs, GetShader ps); protected: From 1f1a5f8e751b3acb810be81e833984762bfbd23c Mon Sep 17 00:00:00 2001 From: Niraj Venkat Date: Mon, 13 Jul 2015 22:57:11 -0700 Subject: [PATCH 43/49] Coding standard and fixing pointers --- interface/src/avatar/AvatarManager.cpp | 5 ++--- interface/src/avatar/AvatarManager.h | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index f5a352bcca..8e7a03685b 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -72,7 +72,7 @@ void AvatarManager::init() { _myAvatar->init(); _avatarHash.insert(MY_AVATAR_KEY, _myAvatar); - connect(&(*DependencyManager::get()), &SceneScriptingInterface::shouldRenderAvatarsChanged, this, &AvatarManager::updateAvatarRenderStatus, Qt::QueuedConnection); + connect(DependencyManager::get().data(), &SceneScriptingInterface::shouldRenderAvatarsChanged, this, &AvatarManager::updateAvatarRenderStatus, Qt::QueuedConnection); render::ScenePointer scene = Application::getInstance()->getMain3DScene(); render::PendingChanges pendingChanges; @@ -326,8 +326,7 @@ void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) { avatar->addToScene(avatar, scene, pendingChanges); scene->enqueuePendingChanges(pendingChanges); } - } - else { + } else { for (auto avatarData : _avatarHash) { auto avatar = std::dynamic_pointer_cast(avatarData); render::ScenePointer scene = Application::getInstance()->getMain3DScene(); diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 06509d8f75..d066158a0c 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -89,7 +89,6 @@ private: SetOfMotionStates _motionStatesToAdd; VectorOfMotionStates _motionStatesToDelete; VectorOfMotionStates _tempMotionStates; - }; Q_DECLARE_METATYPE(AvatarManager::LocalLight) From ef3c6b25e0d8547d2dae1f81ede4ef505c246a3b Mon Sep 17 00:00:00 2001 From: Niraj Venkat Date: Tue, 14 Jul 2015 00:45:38 -0700 Subject: [PATCH 44/49] More coding standard changes --- interface/src/avatar/Avatar.h | 1 - libraries/entities-renderer/src/EntityTreeRenderer.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 0bb0309217..b23059acb0 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -91,7 +91,6 @@ public: void removeFromScene(AvatarSharedPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); - //setters void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } void setIsLookAtTarget(const bool isLookAtTarget) { _isLookAtTarget = isLookAtTarget; } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 11d24c6d9d..9b5925e5ab 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -803,7 +803,7 @@ void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityS connect(this, &EntityTreeRenderer::leaveEntity, entityScriptingInterface, &EntityScriptingInterface::leaveEntity); connect(this, &EntityTreeRenderer::collisionWithEntity, entityScriptingInterface, &EntityScriptingInterface::collisionWithEntity); - connect(&(*DependencyManager::get()), &SceneScriptingInterface::shouldRenderEntitiesChanged, this, &EntityTreeRenderer::updateEntityRenderStatus, Qt::QueuedConnection); + connect(DependencyManager::get().data(), &SceneScriptingInterface::shouldRenderEntitiesChanged, this, &EntityTreeRenderer::updateEntityRenderStatus, Qt::QueuedConnection); } QScriptValueList EntityTreeRenderer::createMouseEventArgs(const EntityItemID& entityID, QMouseEvent* event, unsigned int deviceID) { From 7610fe48c228d092b1a14e5ae1ea6e9057244b80 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Jul 2015 09:21:42 -0700 Subject: [PATCH 45/49] filter action updates during simulation ownership This fixes a bug where actions can be thrashed (created/deleted) by late entity update echos from the entity-server. --- libraries/entities/src/EntityItem.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 7354628390..50b36ec6e2 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -610,6 +610,9 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef int bytesRead = parser.offset(); #endif + auto nodeList = DependencyManager::get(); + const QUuid& myNodeID = nodeList->getSessionUUID(); + bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID); if (args.bitstreamVersion >= VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE) { // pack SimulationOwner and terse update properties near each other @@ -632,10 +635,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef } { // When we own the simulation we don't accept updates to the entity's transform/velocities // but since we're using macros below we have to temporarily modify overwriteLocalData. - auto nodeList = DependencyManager::get(); - bool weOwnIt = _simulationOwner.matchesValidID(nodeList->getSessionUUID()); bool oldOverwrite = overwriteLocalData; - overwriteLocalData = overwriteLocalData && !weOwnIt; + overwriteLocalData = overwriteLocalData && !weOwnSimulation; READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition); READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation); READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocity); @@ -657,6 +658,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint); } else { // legacy order of packing here + // TODO: purge this logic in a few months from now (2015.07) READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition); READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensions); READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation); @@ -702,7 +704,16 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_HREF, QString, setHref); READ_ENTITY_PROPERTY(PROP_DESCRIPTION, QString, setDescription); - READ_ENTITY_PROPERTY(PROP_ACTION_DATA, QByteArray, setActionData); + { // When we own the simulation we don't accept updates to the entity's actions + // but since we're using macros below we have to temporarily modify overwriteLocalData. + // NOTE: this prevents userB from adding an action to an object1 when UserA + // has simulation ownership of it. + // TODO: figure out how to allow multiple users to update actions simultaneously + bool oldOverwrite = overwriteLocalData; + overwriteLocalData = overwriteLocalData && !weOwnSimulation; + READ_ENTITY_PROPERTY(PROP_ACTION_DATA, QByteArray, setActionData); + overwriteLocalData = oldOverwrite; + } bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData); @@ -713,7 +724,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef // NOTE: we had a bad version of the stream that we added stream data after the subclass. We can attempt to recover // by doing this parsing here... but it's not likely going to fully recover the content. // - // TODO: Remove this conde once we've sufficiently migrated content past this damaged version + // TODO: Remove this code once we've sufficiently migrated content past this damaged version if (args.bitstreamVersion == VERSION_ENTITIES_HAS_MARKETPLACE_ID_DAMAGED) { READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID); } @@ -738,8 +749,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef } } - auto nodeList = DependencyManager::get(); - const QUuid& myNodeID = nodeList->getSessionUUID(); if (overwriteLocalData) { if (!_simulationOwner.matchesValidID(myNodeID)) { From 69db9aa01ac18f1330396f9b4fd8d7f8d847fc78 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Jul 2015 09:23:05 -0700 Subject: [PATCH 46/49] fix grab transitions between vert and horiz planes --- examples/grab.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/examples/grab.js b/examples/grab.js index f64aaa30ee..13c91bebb8 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -43,9 +43,10 @@ var gMaxGrabDistance; // elevationAzimuth var gGrabMode = "xzplane"; -// gGrabOffset allows the user to grab an object off-center. It points from ray's intersection -// with the move-plane to object center (at the moment the grab is initiated). Future target positions -// are relative to the ray's intersection by the same offset. +// gGrabOffset allows the user to grab an object off-center. It points from the object's center +// to the point where the ray intersects the grab plane (at the moment the grab is initiated). +// Future target positions of the ray intersection are on the same plane, and the offset is subtracted +// to compute the target position of the object's center. var gGrabOffset = { x: 0, y: 0, z: 0 }; var gTargetPosition; @@ -152,7 +153,6 @@ function computeNewGrabPlane() { maybeResetMousePosition = true; } gGrabMode = "xzPlane"; - gPointOnPlane = gCurrentPosition; gPlaneNormal = { x: 0, y: 1, z: 0 }; if (gLiftKey) { if (!gRotateKey) { @@ -163,7 +163,7 @@ function computeNewGrabPlane() { gGrabMode = "rotate"; } - gPointOnPlane = Vec3.subtract(gCurrentPosition, gGrabOffset); + gPointOnPlane = Vec3.sum(gCurrentPosition, gGrabOffset); var xzOffset = Vec3.subtract(gPointOnPlane, Camera.getPosition()); xzOffset.y = 0; gXzDistanceToGrab = Vec3.length(xzOffset); @@ -220,8 +220,8 @@ function mousePressEvent(event) { nearestPoint = Vec3.multiply(distanceToGrab, pickRay.direction); gPointOnPlane = Vec3.sum(cameraPosition, nearestPoint); - // compute the grab offset - gGrabOffset = Vec3.subtract(gStartPosition, gPointOnPlane); + // compute the grab offset (points from object center to point of grab) + gGrabOffset = Vec3.subtract(gPointOnPlane, gStartPosition); computeNewGrabPlane(); @@ -258,6 +258,7 @@ function mouseMoveEvent(event) { if (Vec3.length(entityProperties.gravity) != 0) { gOriginalGravity = entityProperties.gravity; } + gCurrentPosition = entityProperties.position; var actionArgs = {}; @@ -287,6 +288,7 @@ function mouseMoveEvent(event) { var pointOnCylinder = Vec3.multiply(planeNormal, gXzDistanceToGrab); pointOnCylinder = Vec3.sum(Camera.getPosition(), pointOnCylinder); newTargetPosition = mouseIntersectionWithPlane(pointOnCylinder, planeNormal, event); + gPointOnPlane = Vec3.sum(newTargetPosition, gGrabOffset); } else { var cameraPosition = Camera.getPosition(); newTargetPosition = mouseIntersectionWithPlane(gPointOnPlane, gPlaneNormal, event); @@ -298,7 +300,7 @@ function mouseMoveEvent(event) { newTargetPosition = Vec3.sum(relativePosition, cameraPosition); } } - gTargetPosition = Vec3.sum(newTargetPosition, gGrabOffset); + gTargetPosition = Vec3.subtract(newTargetPosition, gGrabOffset); actionArgs = {targetPosition: gTargetPosition, linearTimeScale: 0.1}; } gPreviousMouse = { x: event.x, y: event.y }; From c49851cf032d0add4a17fa368bb891f7135a41db Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 14 Jul 2015 09:33:08 -0700 Subject: [PATCH 47/49] Update sword script for current controller/physics behavior. --- examples/example/games/sword.js | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/examples/example/games/sword.js b/examples/example/games/sword.js index 18d6911f0b..178a48f35a 100644 --- a/examples/example/games/sword.js +++ b/examples/example/games/sword.js @@ -175,10 +175,12 @@ function positionStick(stickOrientation) { inHand = false; Entities.updateAction(stickID, actionID, { relativePosition: offset, - relativeRotation: stickOrientation + relativeRotation: stickOrientation, + hand: "right" }); } -function resetToHand() { // Maybe coordinate with positionStick? +function resetToHand() { // For use with controllers, puts the sword in contact with the hand. + // Maybe coordinate with positionStick? if (inHand) { // Optimization: bail if we're already inHand. return; } @@ -191,14 +193,14 @@ function resetToHand() { // Maybe coordinate with positionStick? }); inHand = true; } +function isControllerActive() { + // I don't think the hydra API provides any reliable way to know whether a particular controller is active. Ask for both. + controllerActive = (Vec3.length(Controller.getSpatialControlPosition(3)) > 0) || Vec3.length(Controller.getSpatialControlPosition(4)) > 0; + return controllerActive; +} function mouseMoveEvent(event) { - if (event.deviceID) { // Not a MOUSE mouse event, but a (e.g., hydra) mouse event, with x/y that is not meaningful for us. - resetToHand(); // Can only happen when controller is uncradled, so let's drive with that, resetting our attachement. - return; - } - controllerActive = (Vec3.length(Controller.getSpatialControlPosition(controllerID)) > 0); - //print("Mouse move with hand controller " + (controllerActive ? "active" : "inactive") + JSON.stringify(event)); - if (controllerActive || !isFighting()) { + // When a controller like the hydra gives a mouse event, the x/y is not meaningful to us, but we can detect with a truty deviceID + if (event.deviceID || !isFighting() || isControllerActive()) { print('Attempting attachment reset'); resetToHand(); return; @@ -244,12 +246,20 @@ function cleanUp(leaveButtons) { } function makeSword() { initControls(); + var swordPosition; + if (!isControllerActive()) { // Dont' knock yourself with sword + swordPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(MyAvatar.orientation))); + } else if (hand === 'right') { + swordPosition = MyAvatar.getRightPalmPosition(); + } else { + swordPosition = MyAvatar.getLeftPalmPosition(); + } stickID = Entities.addEntity({ type: "Model", modelURL: swordModel, compoundShapeURL: swordCollisionShape, dimensions: dimensions, - position: (hand === 'right') ? MyAvatar.getRightPalmPosition() : MyAvatar.getLeftPalmPosition(), // initial position doesn't matter, as long as it's close + position: swordPosition, rotation: MyAvatar.orientation, damping: 0.1, collisionSoundURL: swordCollisionSoundURL, From 5196648b229e6216e5043f3dbf5eaa50c02b4458 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 14 Jul 2015 09:57:19 -0700 Subject: [PATCH 48/49] Remove obsolete enum member. --- tests/ui/src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/ui/src/main.cpp b/tests/ui/src/main.cpp index 07ff40d738..1b0c7e0ab1 100644 --- a/tests/ui/src/main.cpp +++ b/tests/ui/src/main.cpp @@ -125,7 +125,6 @@ public: DisplayModelElementProxy, DisplayDebugTimingDetails, DontDoPrecisionPicking, - RESERVED_DontFadeOnOctreeServerChanges, DontRenderEntitiesAsScene, EchoLocalAudio, EchoServerAudio, From 1c8ec3b1c9c80bd35dfab0aaf0ebe3f6e0bb2d27 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 14 Jul 2015 10:16:06 -0700 Subject: [PATCH 49/49] preventing unused warnings --- libraries/ui/src/VrMenu.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp index 4c83e6e3cd..ce4aba83d3 100644 --- a/libraries/ui/src/VrMenu.cpp +++ b/libraries/ui/src/VrMenu.cpp @@ -211,7 +211,11 @@ void VrMenu::insertAction(QAction* before, QAction* action) { bool invokeResult = QMetaObject::invokeMethod(menu, "insertItem", Qt::DirectConnection, Q_RETURN_ARG(QQuickMenuItem*, returnedValue), Q_ARG(int, index), Q_ARG(QString, action->text())); +#ifndef QT_NO_DEBUG Q_ASSERT(invokeResult); +#else + Q_UNUSED(invokeResult); +#endif result = reinterpret_cast(returnedValue); } Q_ASSERT(result);