Merge branch 'master' of github.com:highfidelity/hifi into addRecursionToAutotester

This commit is contained in:
NissimHadar 2018-03-09 18:15:03 -08:00
commit cb24fe6166
82 changed files with 424 additions and 340 deletions

View file

@ -33,8 +33,6 @@ Item {
width: parent.width width: parent.width
height: parent.height height: parent.height
} }
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
Timer { Timer {
id: updateList id: updateList

View file

@ -109,9 +109,9 @@ CheckBox {
contentItem: Text { contentItem: Text {
id: root id: root
FontLoader { id: ralewaySemiBold; source: "qrc:/fonts/Raleway-SemiBold.ttf"; }
font.pixelSize: hifi.fontSizes.inputLabel font.pixelSize: hifi.fontSizes.inputLabel
font.family: ralewaySemiBold.name font.family: "Raleway"
font.weight: Font.DemiBold
text: checkBox.text text: checkBox.text
color: checkBox.color color: checkBox.color
x: 2 x: 2

View file

@ -125,8 +125,7 @@ Rectangle {
TextInput { TextInput {
id: mirrorText id: mirrorText
visible: showMirrorText visible: showMirrorText
FontLoader { id: font; source: "qrc:/fonts/FiraSans-Regular.ttf"; } font.family: "Fira Sans"
font.family: font.name
font.pixelSize: 20 font.pixelSize: 20
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
@ -165,8 +164,6 @@ Rectangle {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: 0 anchors.bottomMargin: 0
FontLoader { id: hiFiGlyphs; source: "qrc:/fonts/hifi-glyphs.ttf"; }
Column { Column {
id: columnAlpha id: columnAlpha
width: keyboardWidth width: keyboardWidth
@ -250,7 +247,7 @@ Rectangle {
Key { width: 43; glyph: ","; } Key { width: 43; glyph: ","; }
Key { width: 43; glyph: "."; } Key { width: 43; glyph: "."; }
Key { Key {
fontFamily: hiFiGlyphs.name; fontFamily: "hifi-glyphs";
fontPixelSize: 48; fontPixelSize: 48;
letterAnchors.topMargin: -4; letterAnchors.topMargin: -4;
verticalAlignment: Text.AlignVCenter; verticalAlignment: Text.AlignVCenter;
@ -343,7 +340,7 @@ Rectangle {
Key { width: 43; glyph: ","; } Key { width: 43; glyph: ","; }
Key { width: 43; glyph: "."; } Key { width: 43; glyph: "."; }
Key { Key {
fontFamily: hiFiGlyphs.name; fontFamily: "hifi-glyphs";
fontPixelSize: 48; fontPixelSize: 48;
letterAnchors.topMargin: -4; letterAnchors.topMargin: -4;
verticalAlignment: Text.AlignVCenter; verticalAlignment: Text.AlignVCenter;

View file

@ -25,8 +25,7 @@ SpinBox {
property color colorLabelInside: hifi.colors.white property color colorLabelInside: hifi.colors.white
property real controlHeight: height + (spinBoxLabel.visible ? spinBoxLabel.height + spinBoxLabel.anchors.bottomMargin : 0) property real controlHeight: height + (spinBoxLabel.visible ? spinBoxLabel.height + spinBoxLabel.anchors.bottomMargin : 0)
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; } font.family: "Fira Sans SemiBold"
font.family: firaSansSemiBold.name
font.pixelSize: hifi.fontSizes.textFieldInput font.pixelSize: hifi.fontSizes.textFieldInput
height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control. height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control.

View file

@ -16,9 +16,9 @@ import "../styles-uit"
TextEdit { TextEdit {
property real size: 32 property real size: 32
FontLoader { id: ralewaySemiBold; source: "qrc:/fonts/Raleway-SemiBold.ttf"; } font.family: "Raleway"
font.family: ralewaySemiBold.name font.weight: Font.DemiBold
font.pointSize: size font.pointSize: size
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft

View file

@ -34,9 +34,7 @@ TextField {
placeholderText: textField.placeholderText placeholderText: textField.placeholderText
FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; } font.family: "Fira Sans"
FontLoader { id: hifiGlyphs; source: "qrc:/fonts/hifi-glyphs.ttf"; }
font.family: firaSansRegular.name
font.pixelSize: hifi.fontSizes.textFieldInput font.pixelSize: hifi.fontSizes.textFieldInput
height: implicitHeight + 3 // Make surrounding box higher so that highlight is vertically centered. height: implicitHeight + 3 // Make surrounding box higher so that highlight is vertically centered.
property alias textFieldLabel: textFieldLabel property alias textFieldLabel: textFieldLabel

View file

@ -4,13 +4,12 @@ import QtQuick.Controls.Styles 1.3
Text { Text {
id: root id: root
FontLoader { id: iconFont; source: "qrc:/fonts/fontawesome-webfont.ttf"; }
property int size: 32 property int size: 32
width: size width: size
height: size height: size
font.pixelSize: size font.pixelSize: size
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
font.family: iconFont.name font.family: "FontAwesome"
} }

View file

@ -532,9 +532,6 @@ ModalWindow {
itemDelegate: Item { itemDelegate: Item {
clip: true clip: true
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
FiraSansSemiBold { FiraSansSemiBold {
text: getText(); text: getText();
elide: styleData.elideMode elide: styleData.elideMode
@ -548,7 +545,7 @@ ModalWindow {
size: hifi.fontSizes.tableText size: hifi.fontSizes.tableText
color: hifi.colors.baseGrayHighlight color: hifi.colors.baseGrayHighlight
font.family: (styleData.row !== -1 && fileTableView.model.get(styleData.row).fileIsDir) font.family: (styleData.row !== -1 && fileTableView.model.get(styleData.row).fileIsDir)
? firaSansSemiBold.name : firaSansRegular.name ? "Fira Sans SemiBold" : "Fira Sans"
function getText() { function getText() {
if (styleData.row === -1) { if (styleData.row === -1) {

View file

@ -496,9 +496,6 @@ TabletModalWindow {
itemDelegate: Item { itemDelegate: Item {
clip: true clip: true
//FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
//FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
FiraSansSemiBold { FiraSansSemiBold {
text: getText(); text: getText();
elide: styleData.elideMode elide: styleData.elideMode
@ -512,7 +509,7 @@ TabletModalWindow {
size: hifi.fontSizes.tableText size: hifi.fontSizes.tableText
color: hifi.colors.baseGrayHighlight color: hifi.colors.baseGrayHighlight
//font.family: (styleData.row !== -1 && fileTableView.model.get(styleData.row).fileIsDir) //font.family: (styleData.row !== -1 && fileTableView.model.get(styleData.row).fileIsDir)
//? firaSansSemiBold.name : firaSansRegular.name //? "Fira Sans SemiBold" : "Fira Sans"
function getText() { function getText() {
if (styleData.row === -1) { if (styleData.row === -1) {

View file

@ -345,9 +345,6 @@ Item {
itemDelegate: Item { itemDelegate: Item {
clip: true clip: true
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
FiraSansSemiBold { FiraSansSemiBold {
text: styleData.value text: styleData.value
elide: styleData.elideMode elide: styleData.elideMode
@ -361,7 +358,7 @@ Item {
size: hifi.fontSizes.tableText size: hifi.fontSizes.tableText
color: hifi.colors.baseGrayHighlight color: hifi.colors.baseGrayHighlight
font.family: (styleData.row !== -1 && assetTableView.model.get(styleData.row).fileIsDir) font.family: (styleData.row !== -1 && assetTableView.model.get(styleData.row).fileIsDir)
? firaSansSemiBold.name : firaSansRegular.name ? "Fira Sans SemiBold" : "Fira Sans"
} }
} }

View file

@ -660,8 +660,7 @@ Windows.ScrollingWindow {
text: styleData.value text: styleData.value
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; } font.family: "Fira Sans SemiBold"
font.family: firaSansSemiBold.name
font.pixelSize: hifi.fontSizes.textFieldInput font.pixelSize: hifi.fontSizes.textFieldInput
height: hifi.dimensions.tableRowHeight height: hifi.dimensions.tableRowHeight

View file

@ -25,8 +25,6 @@ Item {
property int dialogHeight; property int dialogHeight;
property int comboOptionTextSize: 16; property int comboOptionTextSize: 16;
property int comboBodyTextSize: 16; property int comboBodyTextSize: 16;
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
FontLoader { id: ralewaySemiBold; source: "qrc:/fonts/Raleway-SemiBold.ttf"; }
visible: false; visible: false;
id: combo; id: combo;
anchors.fill: parent; anchors.fill: parent;

View file

@ -24,8 +24,6 @@ Item {
property real headerTextMargin: -5 property real headerTextMargin: -5
property real headerGlyphMargin: -15 property real headerGlyphMargin: -15
property bool isDesktop: false property bool isDesktop: false
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
FontLoader { id: ralewaySemiBold; source: "qrc:/fonts/Raleway-SemiBold.ttf"; }
visible: false visible: false
id: letterbox id: letterbox
anchors.fill: parent anchors.fill: parent
@ -78,7 +76,8 @@ Item {
// Text Size // Text Size
font.pixelSize: headerTextPixelSize font.pixelSize: headerTextPixelSize
// Style // Style
font.family: ralewaySemiBold.name font.family: "Raleway"
font.weight: Font.DemiBold
color: hifi.colors.darkGray color: hifi.colors.darkGray
horizontalAlignment: Text.AlignHLeft horizontalAlignment: Text.AlignHLeft
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
@ -101,7 +100,7 @@ Item {
horizontalAlignment: Text.AlignHLeft horizontalAlignment: Text.AlignHLeft
// Style // Style
font.pixelSize: popupTextPixelSize font.pixelSize: popupTextPixelSize
font.family: ralewayRegular.name font.family: "Raleway"
color: hifi.colors.darkGray color: hifi.colors.darkGray
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
textFormat: Text.StyledText textFormat: Text.StyledText

View file

@ -23,8 +23,6 @@ Item {
property real popupTextPixelSize: 16 property real popupTextPixelSize: 16
property real headerTextMargin: -5 property real headerTextMargin: -5
property real headerGlyphMargin: -15 property real headerGlyphMargin: -15
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
FontLoader { id: ralewaySemiBold; source: "qrc:/fonts/Raleway-SemiBold.ttf"; }
visible: false visible: false
id: letterbox id: letterbox
anchors.fill: parent anchors.fill: parent
@ -82,7 +80,8 @@ Item {
// Text Size // Text Size
font.pixelSize: headerTextPixelSize font.pixelSize: headerTextPixelSize
// Style // Style
font.family: ralewaySemiBold.name font.family: "Raleway"
font.weight: Font.DemiBold
color: hifi.colors.darkGray color: hifi.colors.darkGray
horizontalAlignment: Text.AlignHLeft horizontalAlignment: Text.AlignHLeft
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
@ -127,7 +126,7 @@ Item {
horizontalAlignment: Text.AlignHLeft horizontalAlignment: Text.AlignHLeft
// Style // Style
font.pixelSize: popupTextPixelSize font.pixelSize: popupTextPixelSize
font.family: ralewayRegular.name font.family: "Raleway"
color: hifi.colors.darkGray color: hifi.colors.darkGray
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
textFormat: Text.StyledText textFormat: Text.StyledText

View file

@ -177,8 +177,7 @@ Item {
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: editGlyph.width + editGlyph.anchors.rightMargin anchors.rightMargin: editGlyph.width + editGlyph.anchors.rightMargin
// Style // Style
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; } font.family: "Fira Sans SemiBold"
font.family: firaSansSemiBold.name
font.pixelSize: displayNameTextPixelSize font.pixelSize: displayNameTextPixelSize
selectionColor: hifi.colors.blueAccent selectionColor: hifi.colors.blueAccent
selectedTextColor: "black" selectedTextColor: "black"

View file

@ -908,7 +908,6 @@ Rectangle {
anchors.horizontalCenter: parent.horizontalCenter; anchors.horizontalCenter: parent.horizontalCenter;
} }
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
Text { Text {
id: connectionHelpText; id: connectionHelpText;
// Anchors // Anchors
@ -923,7 +922,7 @@ Rectangle {
horizontalAlignment: Text.AlignHLeft horizontalAlignment: Text.AlignHLeft
// Style // Style
font.pixelSize: 18; font.pixelSize: 18;
font.family: ralewayRegular.name font.family: "Raleway"
color: hifi.colors.darkGray color: hifi.colors.darkGray
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
textFormat: Text.StyledText; textFormat: Text.StyledText;

View file

@ -128,10 +128,10 @@ Rectangle {
AudioControls.CheckBox { AudioControls.CheckBox {
id: stereoMic id: stereoMic
spacing: muteMic.spacing; spacing: muteMic.spacing;
text: qsTr("use stereo for stereo devices"); text: qsTr("Enable stereo input");
checked: false; checked: AudioScriptingInterface.isStereoInput();
onClicked: { onClicked: {
var success = Audio.setIsStereoInput(checked); var success = AudioScriptingInterface.setStereoInput(checked);
if (!success) { if (!success) {
checked = !checked; checked = !checked;
} }
@ -219,7 +219,7 @@ Rectangle {
onPressed: { onPressed: {
if (!checked) { if (!checked) {
stereoMic.checked = false; stereoMic.checked = false;
Audio.setIsStereoInput(false); // the next selected audio device might not support stereo AudioScriptingInterface.setStereoInput(false); // the next selected audio device might not support stereo
AudioScriptingInterface.setInputDevice(info, bar.currentIndex === 1); AudioScriptingInterface.setInputDevice(info, bar.currentIndex === 1);
} }
} }

View file

@ -147,8 +147,7 @@ Rectangle {
} else if (root.itemHref.indexOf('.json') > -1) { } else if (root.itemHref.indexOf('.json') > -1) {
root.itemType = "entity"; // "wearable" type handled later root.itemType = "entity"; // "wearable" type handled later
} else { } else {
console.log("WARNING - Item type is UNKNOWN!"); root.itemType = "unknown";
root.itemType = "entity";
} }
} }

View file

@ -141,10 +141,9 @@ Item {
} }
} }
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
TextMetrics { TextMetrics {
id: textMetrics; id: textMetrics;
font.family: ralewayRegular.name font.family: "Raleway"
text: usernameText.text; text: usernameText.text;
} }

View file

@ -174,11 +174,12 @@ Rectangle {
WalletChoice { WalletChoice {
id: walletChoice; id: walletChoice;
proceedFunction: function (isReset) { proceedFunction: function (isReset) {
console.log(isReset ? "Reset wallet." : "Trying again with new wallet."); console.log("WalletChoice", isReset ? "Reset wallet." : "Trying again with new wallet.");
Commerce.setSoftReset(); Commerce.setSoftReset();
if (isReset) { if (isReset) {
walletResetSetup(); walletResetSetup();
} else { } else {
Commerce.clearWallet();
var msg = { referrer: walletChoice.referrer } var msg = { referrer: walletChoice.referrer }
followReferrer(msg); followReferrer(msg);
} }

View file

@ -997,14 +997,13 @@ Item {
anchors.right: parent.right; anchors.right: parent.right;
anchors.rightMargin: 20; anchors.rightMargin: 20;
height: 95; height: 95;
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
TextArea { TextArea {
id: optionalMessage; id: optionalMessage;
property int maximumLength: 72; property int maximumLength: 72;
property string previousText: text; property string previousText: text;
placeholderText: "<i>Optional Public Message (" + maximumLength + " character limit)</i>"; placeholderText: "<i>Optional Public Message (" + maximumLength + " character limit)</i>";
font.family: firaSansSemiBold.name; font.family: "Fira Sans SemiBold";
font.pixelSize: 20; font.pixelSize: 20;
// Anchors // Anchors
anchors.fill: parent; anchors.fill: parent;

View file

@ -659,8 +659,7 @@ Rectangle {
text: styleData.value text: styleData.value
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; } font.family: "Fira Sans SemiBold"
font.family: firaSansSemiBold.name
font.pixelSize: hifi.fontSizes.textFieldInput font.pixelSize: hifi.fontSizes.textFieldInput
height: hifi.dimensions.tableRowHeight height: hifi.dimensions.tableRowHeight

View file

@ -478,9 +478,6 @@ Rectangle {
itemDelegate: Item { itemDelegate: Item {
clip: true clip: true
//FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
//FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
FiraSansSemiBold { FiraSansSemiBold {
text: getText(); text: getText();
elide: styleData.elideMode elide: styleData.elideMode
@ -494,7 +491,7 @@ Rectangle {
size: hifi.fontSizes.tableText size: hifi.fontSizes.tableText
color: hifi.colors.baseGrayHighlight color: hifi.colors.baseGrayHighlight
//font.family: (styleData.row !== -1 && fileTableView.model.get(styleData.row).fileIsDir) //font.family: (styleData.row !== -1 && fileTableView.model.get(styleData.row).fileIsDir)
//? firaSansSemiBold.name : firaSansRegular.name //? "Fira Sans SemiBold" : "Fira Sans"
function getText() { function getText() {
if (styleData.row === -1) { if (styleData.row === -1) {

View file

@ -14,10 +14,9 @@ import QtQuick.Controls.Styles 1.4
Text { Text {
id: root id: root
FontLoader { id: anonymousProRegular; source: "qrc:/fonts/AnonymousPro-Regular.ttf"; }
property real size: 32 property real size: 32
font.pixelSize: size font.pixelSize: size
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
font.family: anonymousProRegular.name font.family: "Anonymous Pro"
} }

View file

@ -14,10 +14,9 @@ import QtQuick.Controls.Styles 1.4
Text { Text {
id: root id: root
FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
property real size: 32 property real size: 32
font.pixelSize: size font.pixelSize: size
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
font.family: firaSansRegular.name font.family: "Fira Sans"
} }

View file

@ -14,10 +14,9 @@ import QtQuick.Controls.Styles 1.4
Text { Text {
id: root id: root
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
property real size: 32 property real size: 32
font.pixelSize: size font.pixelSize: size
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
font.family: firaSansSemiBold.name font.family: "Fira Sans SemiBold"
} }

View file

@ -12,12 +12,11 @@ import QtQuick 2.5
Text { Text {
id: root id: root
FontLoader { id: hiFiGlyphs; source: "qrc:/fonts/hifi-glyphs.ttf"; }
property int size: 32 property int size: 32
font.pixelSize: size font.pixelSize: size
width: size width: size
height: size height: size
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
font.family: hiFiGlyphs.name font.family: "hifi-glyphs"
} }

View file

@ -14,11 +14,10 @@ import QtQuick.Controls.Styles 1.4
Text { Text {
id: root id: root
FontLoader { id: ralewayBold; source: "qrc:/fonts/Raleway-Bold.ttf"; }
property real size: 32 property real size: 32
font.pixelSize: size font.pixelSize: size
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
font.family: ralewayBold.name font.family: "Raleway"
font.bold: true // Font seems to need this in order to display bold. font.bold: true
} }

View file

@ -14,10 +14,9 @@ import QtQuick.Controls.Styles 1.4
Text { Text {
id: root id: root
FontLoader { id: ralewayLight; source: "qrc:/fonts/Raleway-Light.ttf"; }
property real size: 32 property real size: 32
font.pixelSize: size font.pixelSize: size
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
font.family: ralewayLight.name font.family: "Raleway Light"
} }

View file

@ -14,10 +14,9 @@ import QtQuick.Controls.Styles 1.4
Text { Text {
id: root id: root
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
property real size: 32 property real size: 32
font.pixelSize: size font.pixelSize: size
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
font.family: ralewayRegular.name font.family: "Raleway"
} }

View file

@ -14,10 +14,10 @@ import QtQuick.Controls.Styles 1.4
Text { Text {
id: root id: root
FontLoader { id: ralewaySemiBold; source: "qrc:/fonts/Raleway-SemiBold.ttf"; }
property real size: 32 property real size: 32
font.pixelSize: size font.pixelSize: size
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
font.family: ralewaySemiBold.name font.family: "Raleway"
font.weight: Font.DemiBold
} }

View file

@ -981,6 +981,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
qInstallMessageHandler(messageHandler); qInstallMessageHandler(messageHandler);
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "styles/Inconsolata.otf"); QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "styles/Inconsolata.otf");
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/fontawesome-webfont.ttf");
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/hifi-glyphs.ttf");
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/AnonymousPro-Regular.ttf");
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/FiraSans-Regular.ttf");
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/FiraSans-SemiBold.ttf");
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Raleway-Light.ttf");
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Raleway-Regular.ttf");
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Raleway-Bold.ttf");
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Raleway-SemiBold.ttf");
_window->setWindowTitle("High Fidelity Interface"); _window->setWindowTitle("High Fidelity Interface");
Model::setAbstractViewStateInterface(this); // The model class will sometimes need to know view state details from us Model::setAbstractViewStateInterface(this); // The model class will sometimes need to know view state details from us
@ -6636,17 +6645,17 @@ void Application::addAssetToWorld(QString path, QString zipFile, bool isZip, boo
addAssetToWorldInfo(filename, "Adding " + mapping.mid(1) + " to the Asset Server."); addAssetToWorldInfo(filename, "Adding " + mapping.mid(1) + " to the Asset Server.");
addAssetToWorldWithNewMapping(path, mapping, 0); addAssetToWorldWithNewMapping(path, mapping, 0, isZip, isBlocks);
} }
void Application::addAssetToWorldWithNewMapping(QString filePath, QString mapping, int copy) { void Application::addAssetToWorldWithNewMapping(QString filePath, QString mapping, int copy, bool isZip, bool isBlocks) {
auto request = DependencyManager::get<AssetClient>()->createGetMappingRequest(mapping); auto request = DependencyManager::get<AssetClient>()->createGetMappingRequest(mapping);
QObject::connect(request, &GetMappingRequest::finished, this, [=](GetMappingRequest* request) mutable { QObject::connect(request, &GetMappingRequest::finished, this, [=](GetMappingRequest* request) mutable {
const int MAX_COPY_COUNT = 100; // Limit number of duplicate assets; recursion guard. const int MAX_COPY_COUNT = 100; // Limit number of duplicate assets; recursion guard.
auto result = request->getError(); auto result = request->getError();
if (result == GetMappingRequest::NotFound) { if (result == GetMappingRequest::NotFound) {
addAssetToWorldUpload(filePath, mapping); addAssetToWorldUpload(filePath, mapping, isZip, isBlocks);
} else if (result != GetMappingRequest::NoError) { } else if (result != GetMappingRequest::NoError) {
QString errorInfo = "Could not map asset name: " QString errorInfo = "Could not map asset name: "
+ mapping.left(mapping.length() - QString::number(copy).length() - 1); + mapping.left(mapping.length() - QString::number(copy).length() - 1);
@ -6658,7 +6667,7 @@ void Application::addAssetToWorldWithNewMapping(QString filePath, QString mappin
} }
copy++; copy++;
mapping = mapping.insert(mapping.lastIndexOf("."), "-" + QString::number(copy)); mapping = mapping.insert(mapping.lastIndexOf("."), "-" + QString::number(copy));
addAssetToWorldWithNewMapping(filePath, mapping, copy); addAssetToWorldWithNewMapping(filePath, mapping, copy, isZip, isBlocks);
} else { } else {
QString errorInfo = "Too many copies of asset name: " QString errorInfo = "Too many copies of asset name: "
+ mapping.left(mapping.length() - QString::number(copy).length() - 1); + mapping.left(mapping.length() - QString::number(copy).length() - 1);
@ -6671,7 +6680,7 @@ void Application::addAssetToWorldWithNewMapping(QString filePath, QString mappin
request->start(); request->start();
} }
void Application::addAssetToWorldUpload(QString filePath, QString mapping) { void Application::addAssetToWorldUpload(QString filePath, QString mapping, bool isZip, bool isBlocks) {
qInfo(interfaceapp) << "Uploading" << filePath << "to Asset Server as" << mapping; qInfo(interfaceapp) << "Uploading" << filePath << "to Asset Server as" << mapping;
auto upload = DependencyManager::get<AssetClient>()->createUpload(filePath); auto upload = DependencyManager::get<AssetClient>()->createUpload(filePath);
QObject::connect(upload, &AssetUpload::finished, this, [=](AssetUpload* upload, const QString& hash) mutable { QObject::connect(upload, &AssetUpload::finished, this, [=](AssetUpload* upload, const QString& hash) mutable {
@ -6680,7 +6689,7 @@ void Application::addAssetToWorldUpload(QString filePath, QString mapping) {
qWarning(interfaceapp) << "Error downloading model: " + errorInfo; qWarning(interfaceapp) << "Error downloading model: " + errorInfo;
addAssetToWorldError(filenameFromPath(filePath), errorInfo); addAssetToWorldError(filenameFromPath(filePath), errorInfo);
} else { } else {
addAssetToWorldSetMapping(filePath, mapping, hash); addAssetToWorldSetMapping(filePath, mapping, hash, isZip, isBlocks);
} }
// Remove temporary directory created by Clara.io market place download. // Remove temporary directory created by Clara.io market place download.
@ -6697,7 +6706,7 @@ void Application::addAssetToWorldUpload(QString filePath, QString mapping) {
upload->start(); upload->start();
} }
void Application::addAssetToWorldSetMapping(QString filePath, QString mapping, QString hash) { void Application::addAssetToWorldSetMapping(QString filePath, QString mapping, QString hash, bool isZip, bool isBlocks) {
auto request = DependencyManager::get<AssetClient>()->createSetMappingRequest(mapping, hash); auto request = DependencyManager::get<AssetClient>()->createSetMappingRequest(mapping, hash);
connect(request, &SetMappingRequest::finished, this, [=](SetMappingRequest* request) mutable { connect(request, &SetMappingRequest::finished, this, [=](SetMappingRequest* request) mutable {
if (request->getError() != SetMappingRequest::NoError) { if (request->getError() != SetMappingRequest::NoError) {
@ -6705,9 +6714,10 @@ void Application::addAssetToWorldSetMapping(QString filePath, QString mapping, Q
qWarning(interfaceapp) << "Error downloading model: " + errorInfo; qWarning(interfaceapp) << "Error downloading model: " + errorInfo;
addAssetToWorldError(filenameFromPath(filePath), errorInfo); addAssetToWorldError(filenameFromPath(filePath), errorInfo);
} else { } else {
// to prevent files that aren't models from being loaded into world automatically // to prevent files that aren't models or texture files from being loaded into world automatically
if (filePath.toLower().endsWith(OBJ_EXTENSION) || filePath.toLower().endsWith(FBX_EXTENSION) || if ((filePath.toLower().endsWith(OBJ_EXTENSION) || filePath.toLower().endsWith(FBX_EXTENSION)) ||
filePath.toLower().endsWith(JPG_EXTENSION) || filePath.toLower().endsWith(PNG_EXTENSION)) { ((filePath.toLower().endsWith(JPG_EXTENSION) || filePath.toLower().endsWith(PNG_EXTENSION)) &&
((!isBlocks) && (!isZip)))) {
addAssetToWorldAddEntity(filePath, mapping); addAssetToWorldAddEntity(filePath, mapping);
} else { } else {
qCDebug(interfaceapp) << "Zipped contents are not supported entity files"; qCDebug(interfaceapp) << "Zipped contents are not supported entity files";

View file

@ -321,11 +321,11 @@ public slots:
// FIXME: Move addAssetToWorld* methods to own class? // FIXME: Move addAssetToWorld* methods to own class?
void addAssetToWorldFromURL(QString url); void addAssetToWorldFromURL(QString url);
void addAssetToWorldFromURLRequestFinished(); void addAssetToWorldFromURLRequestFinished();
void addAssetToWorld(QString filePath, QString zipFile, bool isZip, bool isBlocks); void addAssetToWorld(QString filePath, QString zipFile, bool isZip = false, bool isBlocks = false);
void addAssetToWorldUnzipFailure(QString filePath); void addAssetToWorldUnzipFailure(QString filePath);
void addAssetToWorldWithNewMapping(QString filePath, QString mapping, int copy); void addAssetToWorldWithNewMapping(QString filePath, QString mapping, int copy, bool isZip = false, bool isBlocks = false);
void addAssetToWorldUpload(QString filePath, QString mapping); void addAssetToWorldUpload(QString filePath, QString mapping, bool isZip = false, bool isBlocks = false);
void addAssetToWorldSetMapping(QString filePath, QString mapping, QString hash); void addAssetToWorldSetMapping(QString filePath, QString mapping, QString hash, bool isZip = false, bool isBlocks = false);
void addAssetToWorldAddEntity(QString filePath, QString mapping); void addAssetToWorldAddEntity(QString filePath, QString mapping);
void handleUnzip(QString sourceFile, QStringList destinationFile, bool autoAdd, bool isZip, bool isBlocks); void handleUnzip(QString sourceFile, QStringList destinationFile, bool autoAdd, bool isZip, bool isBlocks);

View file

@ -80,9 +80,13 @@ void Ledger::signedSend(const QString& propertyName, const QByteArray& text, con
void Ledger::keysQuery(const QString& endpoint, const QString& success, const QString& fail, QJsonObject& requestParams) { void Ledger::keysQuery(const QString& endpoint, const QString& success, const QString& fail, QJsonObject& requestParams) {
auto wallet = DependencyManager::get<Wallet>(); auto wallet = DependencyManager::get<Wallet>();
requestParams["public_keys"] = QJsonArray::fromStringList(wallet->listPublicKeys()); QStringList cachedPublicKeys = wallet->listPublicKeys();
if (!cachedPublicKeys.isEmpty()) {
send(endpoint, success, fail, QNetworkAccessManager::PostOperation, AccountManagerAuth::Required, requestParams); requestParams["public_keys"] = QJsonArray::fromStringList(cachedPublicKeys);
send(endpoint, success, fail, QNetworkAccessManager::PostOperation, AccountManagerAuth::Required, requestParams);
} else {
qDebug(commerce) << "User attempted to call keysQuery, but cachedPublicKeys was empty!";
}
} }
void Ledger::keysQuery(const QString& endpoint, const QString& success, const QString& fail) { void Ledger::keysQuery(const QString& endpoint, const QString& success, const QString& fail) {
@ -296,14 +300,18 @@ void Ledger::updateLocation(const QString& asset_id, const QString location, con
emit walletScriptingInterface->walletNotSetup(); emit walletScriptingInterface->walletNotSetup();
qDebug(commerce) << "User attempted to update the location of a certificate, but their wallet wasn't ready. Status:" << walletStatus; qDebug(commerce) << "User attempted to update the location of a certificate, but their wallet wasn't ready. Status:" << walletStatus;
} else { } else {
QStringList keys = wallet->listPublicKeys(); QStringList cachedPublicKeys = wallet->listPublicKeys();
QString key = keys[0]; if (!cachedPublicKeys.isEmpty()) {
QJsonObject transaction; QString key = cachedPublicKeys[0];
transaction["certificate_id"] = asset_id; QJsonObject transaction;
transaction["place_name"] = location; transaction["certificate_id"] = asset_id;
QJsonDocument transactionDoc{ transaction }; transaction["place_name"] = location;
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); QJsonDocument transactionDoc{ transaction };
signedSend("transaction", transactionString, key, "location", "updateLocationSuccess", "updateLocationFailure", controlledFailure); auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
signedSend("transaction", transactionString, key, "location", "updateLocationSuccess", "updateLocationFailure", controlledFailure);
} else {
qDebug(commerce) << "User attempted to update the location of a certificate, but cachedPublicKeys was empty!";
}
} }
} }
@ -359,7 +367,12 @@ void Ledger::alreadyOwned(const QString& marketplaceId) {
auto wallet = DependencyManager::get<Wallet>(); auto wallet = DependencyManager::get<Wallet>();
QString endpoint = "already_owned"; QString endpoint = "already_owned";
QJsonObject request; QJsonObject request;
request["public_keys"] = QJsonArray::fromStringList(wallet->listPublicKeys()); QStringList cachedPublicKeys = wallet->listPublicKeys();
request["marketplace_item_id"] = marketplaceId; if (!cachedPublicKeys.isEmpty()) {
send(endpoint, "alreadyOwnedSuccess", "alreadyOwnedFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, request); request["public_keys"] = QJsonArray::fromStringList(wallet->listPublicKeys());
request["marketplace_item_id"] = marketplaceId;
send(endpoint, "alreadyOwnedSuccess", "alreadyOwnedFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, request);
} else {
qDebug(commerce) << "User attempted to use the alreadyOwned endpoint, but cachedPublicKeys was empty!";
}
} }

View file

@ -138,6 +138,11 @@ void QmlCommerce::setSoftReset() {
wallet->setSoftReset(); wallet->setSoftReset();
} }
void QmlCommerce::clearWallet() {
auto wallet = DependencyManager::get<Wallet>();
wallet->clear();
}
void QmlCommerce::setPassphrase(const QString& passphrase) { void QmlCommerce::setPassphrase(const QString& passphrase) {
auto wallet = DependencyManager::get<Wallet>(); auto wallet = DependencyManager::get<Wallet>();
wallet->setPassphrase(passphrase); wallet->setPassphrase(passphrase);

View file

@ -67,6 +67,7 @@ protected:
Q_INVOKABLE void setPassphrase(const QString& passphrase); Q_INVOKABLE void setPassphrase(const QString& passphrase);
Q_INVOKABLE void changePassphrase(const QString& oldPassphrase, const QString& newPassphrase); Q_INVOKABLE void changePassphrase(const QString& oldPassphrase, const QString& newPassphrase);
Q_INVOKABLE void setSoftReset(); Q_INVOKABLE void setSoftReset();
Q_INVOKABLE void clearWallet();
Q_INVOKABLE void buy(const QString& assetId, int cost, const bool controlledFailure = false); Q_INVOKABLE void buy(const QString& assetId, int cost, const bool controlledFailure = false);
Q_INVOKABLE void balance(); Q_INVOKABLE void balance();

View file

@ -343,19 +343,23 @@ Wallet::Wallet() {
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() {
getWalletStatus(); getWalletStatus();
_publicKeys.clear(); clear();
if (_securityImage) {
delete _securityImage;
}
_securityImage = nullptr;
// tell the provider we got nothing
updateImageProvider();
_passphrase->clear();
}); });
} }
void Wallet::clear() {
_publicKeys.clear();
if (_securityImage) {
delete _securityImage;
}
_securityImage = nullptr;
// tell the provider we got nothing
updateImageProvider();
_passphrase->clear();
}
Wallet::~Wallet() { Wallet::~Wallet() {
if (_securityImage) { if (_securityImage) {
delete _securityImage; delete _securityImage;

View file

@ -49,8 +49,9 @@ public:
bool getPassphraseIsCached() { return !(_passphrase->isEmpty()); } bool getPassphraseIsCached() { return !(_passphrase->isEmpty()); }
bool walletIsAuthenticatedWithPassphrase(); bool walletIsAuthenticatedWithPassphrase();
bool changePassphrase(const QString& newPassphrase); bool changePassphrase(const QString& newPassphrase);
void setSoftReset() { _isOverridingServer = true; } void setSoftReset() { _isOverridingServer = true; }
bool wasSoftReset() { bool was = _isOverridingServer; _isOverridingServer = false; return was; } bool wasSoftReset() { bool was = _isOverridingServer; _isOverridingServer = false; return was; }
void clear();
void getWalletStatus(); void getWalletStatus();
enum WalletStatus { enum WalletStatus {

View file

@ -174,4 +174,12 @@ void PickScriptingInterface::registerMetaTypes(QScriptEngine* engine) {
engine->globalObject().setProperty("PickType", pickTypes); engine->globalObject().setProperty("PickType", pickTypes);
qScriptRegisterMetaType(engine, pickTypesToScriptValue, pickTypesFromScriptValue); qScriptRegisterMetaType(engine, pickTypesToScriptValue, pickTypesFromScriptValue);
} }
unsigned int PickScriptingInterface::getPerFrameTimeBudget() const {
return DependencyManager::get<PickManager>()->getPerFrameTimeBudget();
}
void PickScriptingInterface::setPerFrameTimeBudget(unsigned int numUsecs) {
DependencyManager::get<PickManager>()->setPerFrameTimeBudget(numUsecs);
}

View file

@ -185,6 +185,14 @@ public:
*/ */
Q_INVOKABLE bool isMouse(unsigned int uid); Q_INVOKABLE bool isMouse(unsigned int uid);
Q_PROPERTY(unsigned int perFrameTimeBudget READ getPerFrameTimeBudget WRITE setPerFrameTimeBudget)
/**jsdoc
* The max number of usec to spend per frame updating Pick results.
* @typedef {number} Picks.perFrameTimeBudget
*/
unsigned int getPerFrameTimeBudget() const;
void setPerFrameTimeBudget(unsigned int numUsecs);
public slots: public slots:
static constexpr unsigned int PICK_NOTHING() { return 0; } static constexpr unsigned int PICK_NOTHING() { return 0; }
static constexpr unsigned int PICK_ENTITIES() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ENTITIES); } static constexpr unsigned int PICK_ENTITIES() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ENTITIES); }
@ -202,4 +210,4 @@ public slots:
static constexpr unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; } static constexpr unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; }
}; };
#endif // hifi_PickScriptingInterface_h #endif // hifi_PickScriptingInterface_h

View file

@ -259,7 +259,6 @@ void WindowScriptingInterface::browseAsync(const QString& title, const QString&
setPreviousBrowseLocation(QFileInfo(result).absolutePath()); setPreviousBrowseLocation(QFileInfo(result).absolutePath());
} }
emit browseChanged(result); emit browseChanged(result);
emit openFileChanged(result); // Deprecated signal; to be removed in due course.
}); });
} }

View file

@ -179,7 +179,6 @@ public slots:
* Prompt the user to choose a file. Displays a non-modal dialog that navigates the directory tree. A * Prompt the user to choose a file. Displays a non-modal dialog that navigates the directory tree. A
* {@link Window.browseChanged|browseChanged} signal is emitted when a file is chosen; no signal is emitted if the user * {@link Window.browseChanged|browseChanged} signal is emitted when a file is chosen; no signal is emitted if the user
* cancels the dialog. * cancels the dialog.
* @deprecated A deprecated {@link Window.openFileChanged|openFileChanged} signal is also emitted when a file is chosen.
* @function Window.browseAsync * @function Window.browseAsync
* @param {string} title="" - The title to display at the top of the dialog. * @param {string} title="" - The title to display at the top of the dialog.
* @param {string} directory="" - The initial directory to start browsing at. * @param {string} directory="" - The initial directory to start browsing at.
@ -660,15 +659,6 @@ signals:
*/ */
void browseChanged(QString filename); void browseChanged(QString filename);
/**jsdoc
* Triggered when the user chooses a file in a {@link Window.browseAsync|browseAsync} dialog.
* @function Window.openFileChanged
* @deprecated This signal is being replaced with {@link Window.browseChanged|browseChanged} and will be removed.
* @param {string} filename - The path and name of the file the user chose in the dialog.
* @returns {Signal}
*/
void openFileChanged(QString filename);
/**jsdoc /**jsdoc
* Triggered when the user OKs a {@link Window.promptAsync|promptAsync} dialog. * Triggered when the user OKs a {@link Window.promptAsync|promptAsync} dialog.
* @function Window.promptTextChanged * @function Window.promptTextChanged

View file

@ -193,6 +193,7 @@ public slots:
bool isMuted() { return _muted; } bool isMuted() { return _muted; }
virtual bool setIsStereoInput(bool stereo) override; virtual bool setIsStereoInput(bool stereo) override;
virtual bool isStereoInput() override { return _isStereoInput; }
void setNoiseReduction(bool isNoiseGateEnabled); void setNoiseReduction(bool isNoiseGateEnabled);
bool isNoiseReductionEnabled() const { return _isNoiseGateEnabled; } bool isNoiseReductionEnabled() const { return _isNoiseGateEnabled; }

View file

@ -28,7 +28,7 @@ class AbstractAudioInterface : public QObject {
Q_OBJECT Q_OBJECT
public: public:
AbstractAudioInterface(QObject* parent = 0) : QObject(parent) {}; AbstractAudioInterface(QObject* parent = 0) : QObject(parent) {};
static void emitAudioPacket(const void* audioData, size_t bytes, quint16& sequenceNumber, bool isStereo, static void emitAudioPacket(const void* audioData, size_t bytes, quint16& sequenceNumber, bool isStereo,
const Transform& transform, glm::vec3 avatarBoundingBoxCorner, glm::vec3 avatarBoundingBoxScale, const Transform& transform, glm::vec3 avatarBoundingBoxCorner, glm::vec3 avatarBoundingBoxScale,
PacketType packetType, QString codecName = QString("")); PacketType packetType, QString codecName = QString(""));
@ -40,8 +40,10 @@ public:
public slots: public slots:
virtual bool shouldLoopbackInjectors() { return false; } virtual bool shouldLoopbackInjectors() { return false; }
virtual bool setIsStereoInput(bool stereo) = 0; virtual bool setIsStereoInput(bool stereo) = 0;
virtual bool isStereoInput() = 0;
}; };
Q_DECLARE_METATYPE(AbstractAudioInterface*) Q_DECLARE_METATYPE(AbstractAudioInterface*)

View file

@ -286,7 +286,7 @@ bool RenderableModelEntityItem::supportsDetailedRayIntersection() const {
} }
bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, OctreeElementPointer& element, float& distance, BoxFace& face,
glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const {
auto model = getModel(); auto model = getModel();
if (!model) { if (!model) {

View file

@ -68,7 +68,7 @@ public:
virtual bool supportsDetailedRayIntersection() const override; virtual bool supportsDetailedRayIntersection() const override;
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const override; QVariantMap& extraInfo, bool precisionPicking) const override;

View file

@ -565,7 +565,7 @@ public:
#endif #endif
bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, OctreeElementPointer& element,
float& distance, BoxFace& face, glm::vec3& surfaceNormal, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const QVariantMap& extraInfo, bool precisionPicking) const
{ {

View file

@ -53,7 +53,7 @@ public:
virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool supportsDetailedRayIntersection() const override { return true; }
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const override; QVariantMap& extraInfo, bool precisionPicking) const override;

View file

@ -2984,4 +2984,4 @@ std::unordered_map<std::string, graphics::MultiMaterial> EntityItem::getMaterial
toReturn = _materials; toReturn = _materials;
} }
return toReturn; return toReturn;
} }

View file

@ -159,7 +159,7 @@ public:
virtual bool supportsDetailedRayIntersection() const { return false; } virtual bool supportsDetailedRayIntersection() const { return false; }
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const { return true; } QVariantMap& extraInfo, bool precisionPicking) const { return true; }

View file

@ -594,17 +594,15 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly, const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
QVariantMap& extraInfo, bool precisionPicking) { QVariantMap& extraInfo, bool precisionPicking) {
keepSearching = true; // assume that we will continue searching after this.
EntityItemID result; EntityItemID result;
float distanceToElementCube = std::numeric_limits<float>::max(); float distanceToElementCube = std::numeric_limits<float>::max();
float distanceToElementDetails = distance;
BoxFace localFace; BoxFace localFace;
glm::vec3 localSurfaceNormal; glm::vec3 localSurfaceNormal;
QVariantMap localExtraInfo;
// if the ray doesn't intersect with our cube, we can stop searching! // if the ray doesn't intersect with our cube OR the distance to element is less than current best distance
if (!_cube.findRayIntersection(origin, direction, distanceToElementCube, localFace, localSurfaceNormal)) { // we can stop searching!
bool hit = _cube.findRayIntersection(origin, direction, distanceToElementCube, localFace, localSurfaceNormal);
if (!hit || (!_cube.contains(origin) && distanceToElementCube > distance)) {
keepSearching = false; // no point in continuing to search keepSearching = false; // no point in continuing to search
return result; // we did not intersect return result; // we did not intersect
} }
@ -616,52 +614,46 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con
// if the distance to the element cube is not less than the current best distance, then it's not possible // if the distance to the element cube is not less than the current best distance, then it's not possible
// for any details inside the cube to be closer so we don't need to consider them. // for any details inside the cube to be closer so we don't need to consider them.
if (_cube.contains(origin) || distanceToElementCube < distance) { QVariantMap localExtraInfo;
float distanceToElementDetails = distance;
EntityItemID entityID = findDetailedRayIntersection(origin, direction, keepSearching, element, distanceToElementDetails, EntityItemID entityID = findDetailedRayIntersection(origin, direction, element, distanceToElementDetails,
face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly, face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly,
localExtraInfo, precisionPicking, distanceToElementCube); localExtraInfo, precisionPicking);
if (!entityID.isNull()) { if (!entityID.isNull() && distanceToElementDetails < distance) {
if (distanceToElementDetails < distance) { distance = distanceToElementDetails;
distance = distanceToElementDetails; face = localFace;
face = localFace; surfaceNormal = localSurfaceNormal;
surfaceNormal = localSurfaceNormal; extraInfo = localExtraInfo;
extraInfo = localExtraInfo; result = entityID;
result = entityID;
}
}
} }
return result; return result;
} }
EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIDsToDiscard, const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIDsToDiscard,
bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking, float distanceToElementCube) { bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking) {
// only called if we do intersect our bounding cube, but find if we actually intersect with entities... // only called if we do intersect our bounding cube, but find if we actually intersect with entities...
int entityNumber = 0; int entityNumber = 0;
EntityItemID entityID; EntityItemID entityID;
forEachEntity([&](EntityItemPointer entity) { forEachEntity([&](EntityItemPointer entity) {
if ( (visibleOnly && !entity->isVisible()) || (collidableOnly && (entity->getCollisionless() || entity->getShapeType() == SHAPE_TYPE_NONE)) // use simple line-sphere for broadphase check
|| (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID())) // (this is faster and more likely to cull results than the filter check below so we do it first)
|| (entityIDsToDiscard.size() > 0 && entityIDsToDiscard.contains(entity->getID())) ) {
return;
}
bool success; bool success;
AABox entityBox = entity->getAABox(success); AABox entityBox = entity->getAABox(success);
if (!success) { if (!success) {
return; return;
} }
if (!entityBox.rayHitsBoundingSphere(origin, direction)) {
return;
}
float localDistance; // check RayPick filter settings
BoxFace localFace; if ((visibleOnly && !entity->isVisible())
glm::vec3 localSurfaceNormal; || (collidableOnly && (entity->getCollisionless() || entity->getShapeType() == SHAPE_TYPE_NONE))
QVariantMap localExtraInfo; || (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID()))
|| (entityIDsToDiscard.size() > 0 && entityIDsToDiscard.contains(entity->getID())) ) {
// if the ray doesn't intersect with our cube, we can stop searching!
if (!entityBox.findRayIntersection(origin, direction, localDistance, localFace, localSurfaceNormal)) {
return; return;
} }
@ -682,14 +674,17 @@ EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& ori
// we can use the AABox's ray intersection by mapping our origin and direction into the entity frame // we can use the AABox's ray intersection by mapping our origin and direction into the entity frame
// and testing intersection there. // and testing intersection there.
float localDistance;
BoxFace localFace;
glm::vec3 localSurfaceNormal;
if (entityFrameBox.findRayIntersection(entityFrameOrigin, entityFrameDirection, localDistance, if (entityFrameBox.findRayIntersection(entityFrameOrigin, entityFrameDirection, localDistance,
localFace, localSurfaceNormal)) { localFace, localSurfaceNormal)) {
if (entityFrameBox.contains(entityFrameOrigin) || localDistance < distance) { if (entityFrameBox.contains(entityFrameOrigin) || localDistance < distance) {
// now ask the entity if we actually intersect // now ask the entity if we actually intersect
if (entity->supportsDetailedRayIntersection()) { if (entity->supportsDetailedRayIntersection()) {
if (entity->findDetailedRayIntersection(origin, direction, keepSearching, element, localDistance, QVariantMap localExtraInfo;
localFace, localSurfaceNormal, localExtraInfo, precisionPicking)) { if (entity->findDetailedRayIntersection(origin, direction, element, localDistance,
localFace, localSurfaceNormal, localExtraInfo, precisionPicking)) {
if (localDistance < distance) { if (localDistance < distance) {
distance = localDistance; distance = localDistance;
face = localFace; face = localFace;

View file

@ -152,10 +152,10 @@ public:
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly, const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
QVariantMap& extraInfo, bool precisionPicking = false); QVariantMap& extraInfo, bool precisionPicking = false);
virtual EntityItemID findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual EntityItemID findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude, BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly, const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
QVariantMap& extraInfo, bool precisionPicking, float distanceToElementCube); QVariantMap& extraInfo, bool precisionPicking);
virtual bool findSpherePenetration(const glm::vec3& center, float radius, virtual bool findSpherePenetration(const glm::vec3& center, float radius,
glm::vec3& penetration, void** penetratedObject) const override; glm::vec3& penetration, void** penetratedObject) const override;

View file

@ -298,7 +298,7 @@ void LightEntityItem::resetLightPropertiesChanged() {
} }
bool LightEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool LightEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const { QVariantMap& extraInfo, bool precisionPicking) const {

View file

@ -86,7 +86,7 @@ public:
virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool supportsDetailedRayIntersection() const override { return true; }
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const override; QVariantMap& extraInfo, bool precisionPicking) const override;

View file

@ -61,7 +61,7 @@ class LineEntityItem : public EntityItem {
// never have a ray intersection pick a LineEntityItem. // never have a ray intersection pick a LineEntityItem.
virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool supportsDetailedRayIntersection() const override { return true; }
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, QVariantMap& extraInfo,
bool precisionPicking) const override { return false; } bool precisionPicking) const override { return false; }

View file

@ -94,7 +94,7 @@ class PolyLineEntityItem : public EntityItem {
// never have a ray intersection pick a PolyLineEntityItem. // never have a ray intersection pick a PolyLineEntityItem.
virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool supportsDetailedRayIntersection() const override { return true; }
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const override { return false; } QVariantMap& extraInfo, bool precisionPicking) const override { return false; }

View file

@ -45,7 +45,7 @@ class PolyVoxEntityItem : public EntityItem {
// never have a ray intersection pick a PolyVoxEntityItem. // never have a ray intersection pick a PolyVoxEntityItem.
virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool supportsDetailedRayIntersection() const override { return true; }
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const override { return false; } QVariantMap& extraInfo, bool precisionPicking) const override { return false; }

View file

@ -228,7 +228,7 @@ bool ShapeEntityItem::supportsDetailedRayIntersection() const {
} }
bool ShapeEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool ShapeEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, OctreeElementPointer& element,
float& distance, BoxFace& face, glm::vec3& surfaceNormal, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const { QVariantMap& extraInfo, bool precisionPicking) const {
// determine the ray in the frame of the entity transformed from a unit sphere // determine the ray in the frame of the entity transformed from a unit sphere

View file

@ -92,7 +92,7 @@ public:
bool supportsDetailedRayIntersection() const override; bool supportsDetailedRayIntersection() const override;
bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const override; QVariantMap& extraInfo, bool precisionPicking) const override;

View file

@ -129,7 +129,7 @@ void TextEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
} }
bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const { QVariantMap& extraInfo, bool precisionPicking) const {
glm::vec3 dimensions = getScaledDimensions(); glm::vec3 dimensions = getScaledDimensions();

View file

@ -48,7 +48,7 @@ public:
virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool supportsDetailedRayIntersection() const override { return true; }
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const override; QVariantMap& extraInfo, bool precisionPicking) const override;

View file

@ -106,7 +106,7 @@ void WebEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitst
} }
bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const { QVariantMap& extraInfo, bool precisionPicking) const {
glm::vec3 dimensions = getScaledDimensions(); glm::vec3 dimensions = getScaledDimensions();

View file

@ -47,7 +47,7 @@ public:
virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool supportsDetailedRayIntersection() const override { return true; }
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const override; QVariantMap& extraInfo, bool precisionPicking) const override;

View file

@ -296,7 +296,7 @@ void ZoneEntityItem::setCompoundShapeURL(const QString& url) {
} }
bool ZoneEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool ZoneEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const { QVariantMap& extraInfo, bool precisionPicking) const {

View file

@ -105,7 +105,7 @@ public:
virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool supportsDetailedRayIntersection() const override { return true; }
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElementPointer& element, float& distance, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
QVariantMap& extraInfo, bool precisionPicking) const override; QVariantMap& extraInfo, bool precisionPicking) const override;

View file

@ -46,10 +46,6 @@ AddressManager::AddressManager() :
} }
QString AddressManager::protocolVersion() {
return protocolVersionsSignatureBase64();
}
bool AddressManager::isConnected() { bool AddressManager::isConnected() {
return DependencyManager::get<NodeList>()->getDomainHandler().isConnected(); return DependencyManager::get<NodeList>()->getDomainHandler().isConnected();
} }

View file

@ -71,15 +71,6 @@ class AddressManager : public QObject, public Dependency {
Q_PROPERTY(QString domainID READ getDomainID) Q_PROPERTY(QString domainID READ getDomainID)
Q_PROPERTY(QString domainId READ getDomainID) Q_PROPERTY(QString domainId READ getDomainID)
public: public:
/**jsdoc
* Get Interface's protocol version.
* @function location.protocolVersion
* @returns {string} A string uniquely identifying the version of the metaverse protocol that Interface is using.
* @deprecated This function is deprecated and will be removed. Use {@link Window.protocolSignature} instead.
*/
Q_INVOKABLE QString protocolVersion();
using PositionGetter = std::function<glm::vec3()>; using PositionGetter = std::function<glm::vec3()>;
using OrientationGetter = std::function<glm::quat()>; using OrientationGetter = std::function<glm::quat()>;

View file

@ -37,7 +37,7 @@ template<typename T>
class PickCacheOptimizer { class PickCacheOptimizer {
public: public:
void update(std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>& picks, bool shouldPickHUD); void update(std::unordered_map<uint32_t, std::shared_ptr<PickQuery>>& picks, uint32_t& nextToUpdate, uint64_t expiry, bool shouldPickHUD);
protected: protected:
typedef std::unordered_map<T, std::unordered_map<PickCacheKey, PickResultPointer>> PickCache; typedef std::unordered_map<T, std::unordered_map<PickCacheKey, PickResultPointer>> PickCache;
@ -67,66 +67,84 @@ void PickCacheOptimizer<T>::cacheResult(const bool intersects, const PickResultP
} }
template<typename T> template<typename T>
void PickCacheOptimizer<T>::update(std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>& picks, bool shouldPickHUD) { void PickCacheOptimizer<T>::update(std::unordered_map<uint32_t, std::shared_ptr<PickQuery>>& picks,
uint32_t& nextToUpdate, uint64_t expiry, bool shouldPickHUD) {
PickCache results; PickCache results;
for (const auto& pickPair : picks) { const uint32_t INVALID_PICK_ID = 0;
std::shared_ptr<Pick<T>> pick = std::static_pointer_cast<Pick<T>>(pickPair.second); auto itr = picks.begin();
if (nextToUpdate != INVALID_PICK_ID) {
itr = picks.find(nextToUpdate);
if (itr == picks.end()) {
itr = picks.begin();
}
}
uint32_t numUpdates = 0;
while(numUpdates < picks.size()) {
std::shared_ptr<Pick<T>> pick = std::static_pointer_cast<Pick<T>>(itr->second);
T mathematicalPick = pick->getMathematicalPick(); T mathematicalPick = pick->getMathematicalPick();
PickResultPointer res = pick->getDefaultResult(mathematicalPick.toVariantMap()); PickResultPointer res = pick->getDefaultResult(mathematicalPick.toVariantMap());
if (!pick->isEnabled() || pick->getFilter().doesPickNothing() || pick->getMaxDistance() < 0.0f || !mathematicalPick) { if (!pick->isEnabled() || pick->getFilter().doesPickNothing() || pick->getMaxDistance() < 0.0f || !mathematicalPick) {
pick->setPickResult(res); pick->setPickResult(res);
continue;
}
if (pick->getFilter().doesPickEntities()) {
PickCacheKey entityKey = { pick->getFilter().getEntityFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
if (!checkAndCompareCachedResults(mathematicalPick, results, res, entityKey)) {
PickResultPointer entityRes = pick->getEntityIntersection(mathematicalPick);
if (entityRes) {
cacheResult(entityRes->doesIntersect(), entityRes, entityKey, res, mathematicalPick, results, pick);
}
}
}
if (pick->getFilter().doesPickOverlays()) {
PickCacheKey overlayKey = { pick->getFilter().getOverlayFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
if (!checkAndCompareCachedResults(mathematicalPick, results, res, overlayKey)) {
PickResultPointer overlayRes = pick->getOverlayIntersection(mathematicalPick);
if (overlayRes) {
cacheResult(overlayRes->doesIntersect(), overlayRes, overlayKey, res, mathematicalPick, results, pick);
}
}
}
if (pick->getFilter().doesPickAvatars()) {
PickCacheKey avatarKey = { pick->getFilter().getAvatarFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
if (!checkAndCompareCachedResults(mathematicalPick, results, res, avatarKey)) {
PickResultPointer avatarRes = pick->getAvatarIntersection(mathematicalPick);
if (avatarRes) {
cacheResult(avatarRes->doesIntersect(), avatarRes, avatarKey, res, mathematicalPick, results, pick);
}
}
}
// Can't intersect with HUD in desktop mode
if (pick->getFilter().doesPickHUD() && shouldPickHUD) {
PickCacheKey hudKey = { pick->getFilter().getHUDFlags(), QVector<QUuid>(), QVector<QUuid>() };
if (!checkAndCompareCachedResults(mathematicalPick, results, res, hudKey)) {
PickResultPointer hudRes = pick->getHUDIntersection(mathematicalPick);
if (hudRes) {
cacheResult(true, hudRes, hudKey, res, mathematicalPick, results, pick);
}
}
}
if (pick->getMaxDistance() == 0.0f || (pick->getMaxDistance() > 0.0f && res->checkOrFilterAgainstMaxDistance(pick->getMaxDistance()))) {
pick->setPickResult(res);
} else { } else {
pick->setPickResult(pick->getDefaultResult(mathematicalPick.toVariantMap())); if (pick->getFilter().doesPickEntities()) {
PickCacheKey entityKey = { pick->getFilter().getEntityFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
if (!checkAndCompareCachedResults(mathematicalPick, results, res, entityKey)) {
PickResultPointer entityRes = pick->getEntityIntersection(mathematicalPick);
if (entityRes) {
cacheResult(entityRes->doesIntersect(), entityRes, entityKey, res, mathematicalPick, results, pick);
}
}
}
if (pick->getFilter().doesPickOverlays()) {
PickCacheKey overlayKey = { pick->getFilter().getOverlayFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
if (!checkAndCompareCachedResults(mathematicalPick, results, res, overlayKey)) {
PickResultPointer overlayRes = pick->getOverlayIntersection(mathematicalPick);
if (overlayRes) {
cacheResult(overlayRes->doesIntersect(), overlayRes, overlayKey, res, mathematicalPick, results, pick);
}
}
}
if (pick->getFilter().doesPickAvatars()) {
PickCacheKey avatarKey = { pick->getFilter().getAvatarFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
if (!checkAndCompareCachedResults(mathematicalPick, results, res, avatarKey)) {
PickResultPointer avatarRes = pick->getAvatarIntersection(mathematicalPick);
if (avatarRes) {
cacheResult(avatarRes->doesIntersect(), avatarRes, avatarKey, res, mathematicalPick, results, pick);
}
}
}
// Can't intersect with HUD in desktop mode
if (pick->getFilter().doesPickHUD() && shouldPickHUD) {
PickCacheKey hudKey = { pick->getFilter().getHUDFlags(), QVector<QUuid>(), QVector<QUuid>() };
if (!checkAndCompareCachedResults(mathematicalPick, results, res, hudKey)) {
PickResultPointer hudRes = pick->getHUDIntersection(mathematicalPick);
if (hudRes) {
cacheResult(true, hudRes, hudKey, res, mathematicalPick, results, pick);
}
}
}
if (pick->getMaxDistance() == 0.0f || (pick->getMaxDistance() > 0.0f && res->checkOrFilterAgainstMaxDistance(pick->getMaxDistance()))) {
pick->setPickResult(res);
} else {
pick->setPickResult(pick->getDefaultResult(mathematicalPick.toVariantMap()));
}
}
++itr;
if (itr == picks.end()) {
itr = picks.begin();
}
nextToUpdate = itr->first;
++numUpdates;
if (usecTimestampNow() > expiry) {
break;
} }
} }
} }
#endif // hifi_PickCacheOptimizer_h #endif // hifi_PickCacheOptimizer_h

View file

@ -89,14 +89,17 @@ void PickManager::setIncludeItems(unsigned int uid, const QVector<QUuid>& includ
} }
void PickManager::update() { void PickManager::update() {
uint64_t expiry = usecTimestampNow() + _perFrameTimeBudget;
std::unordered_map<PickQuery::PickType, std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>> cachedPicks; std::unordered_map<PickQuery::PickType, std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>> cachedPicks;
withReadLock([&] { withReadLock([&] {
cachedPicks = _picks; cachedPicks = _picks;
}); });
bool shouldPickHUD = _shouldPickHUDOperator(); bool shouldPickHUD = _shouldPickHUDOperator();
_rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], shouldPickHUD); // we pass the same expiry to both updates, but the stylus updates are relatively cheap
_stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], false); // and the rayPicks updae will ALWAYS update at least one ray even when there is no budget
_stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], _nextPickToUpdate[PickQuery::Stylus], expiry, false);
_rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], _nextPickToUpdate[PickQuery::Ray], expiry, shouldPickHUD);
} }
bool PickManager::isLeftHand(unsigned int uid) { bool PickManager::isLeftHand(unsigned int uid) {
@ -121,4 +124,4 @@ bool PickManager::isMouse(unsigned int uid) {
return pick->isMouse(); return pick->isMouse();
} }
return false; return false;
} }

View file

@ -14,6 +14,8 @@
#include "Pick.h" #include "Pick.h"
#include "PickCacheOptimizer.h" #include "PickCacheOptimizer.h"
#include <NumericalConstants.h>
class PickManager : public Dependency, protected ReadWriteLockable { class PickManager : public Dependency, protected ReadWriteLockable {
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
@ -48,17 +50,24 @@ public:
static const unsigned int INVALID_PICK_ID { 0 }; static const unsigned int INVALID_PICK_ID { 0 };
unsigned int getPerFrameTimeBudget() const { return _perFrameTimeBudget; }
void setPerFrameTimeBudget(unsigned int numUsecs) { _perFrameTimeBudget = numUsecs; }
protected: protected:
std::function<bool()> _shouldPickHUDOperator; std::function<bool()> _shouldPickHUDOperator;
std::function<glm::vec2(const glm::vec3&)> _calculatePos2DFromHUDOperator; std::function<glm::vec2(const glm::vec3&)> _calculatePos2DFromHUDOperator;
std::shared_ptr<PickQuery> findPick(unsigned int uid) const; std::shared_ptr<PickQuery> findPick(unsigned int uid) const;
std::unordered_map<PickQuery::PickType, std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>> _picks; std::unordered_map<PickQuery::PickType, std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>> _picks;
unsigned int _nextPickToUpdate[PickQuery::NUM_PICK_TYPES] { 0, 0 };
std::unordered_map<unsigned int, PickQuery::PickType> _typeMap; std::unordered_map<unsigned int, PickQuery::PickType> _typeMap;
unsigned int _nextPickID { INVALID_PICK_ID + 1 }; unsigned int _nextPickID { INVALID_PICK_ID + 1 };
PickCacheOptimizer<PickRay> _rayPickCacheOptimizer; PickCacheOptimizer<PickRay> _rayPickCacheOptimizer;
PickCacheOptimizer<StylusTip> _stylusPickCacheOptimizer; PickCacheOptimizer<StylusTip> _stylusPickCacheOptimizer;
static const unsigned int DEFAULT_PER_FRAME_TIME_BUDGET = 2 * USECS_PER_MSEC;
unsigned int _perFrameTimeBudget { DEFAULT_PER_FRAME_TIME_BUDGET };
}; };
#endif // hifi_PickManager_h #endif // hifi_PickManager_h

View file

@ -67,3 +67,11 @@ bool AudioScriptingInterface::setStereoInput(bool stereo) {
} }
return stereoInputChanged; return stereoInputChanged;
} }
bool AudioScriptingInterface::isStereoInput() {
bool stereoEnabled = false;
if (_localAudioInterface) {
stereoEnabled = _localAudioInterface->isStereoInput();
}
return stereoEnabled;
}

View file

@ -36,6 +36,7 @@ protected:
Q_INVOKABLE ScriptAudioInjector* playSystemSound(SharedSoundPointer sound, const QVector3D& position); Q_INVOKABLE ScriptAudioInjector* playSystemSound(SharedSoundPointer sound, const QVector3D& position);
Q_INVOKABLE bool setStereoInput(bool stereo); Q_INVOKABLE bool setStereoInput(bool stereo);
Q_INVOKABLE bool isStereoInput();
signals: signals:
void mutedByMixer(); /// the client has been muted by the mixer void mutedByMixer(); /// the client has been muted by the mixer

View file

@ -68,6 +68,10 @@ void FileScriptingInterface::runUnzip(QString path, QUrl url, bool autoAdd, bool
if (path.contains("vr.google.com/downloads")) { if (path.contains("vr.google.com/downloads")) {
isZip = true; isZip = true;
} }
if (!hasModel(fileList)) {
isZip = false;
}
emit unzipResult(path, fileList, autoAdd, isZip, isBlocks); emit unzipResult(path, fileList, autoAdd, isZip, isBlocks);
} }
@ -107,6 +111,15 @@ bool FileScriptingInterface::isTempDir(QString tempDir) {
return (testContainer == tempContainer); return (testContainer == tempContainer);
} }
bool FileScriptingInterface::hasModel(QStringList fileList) {
for (int i = 0; i < fileList.size(); i++) {
if (fileList.at(i).toLower().contains(".fbx") || fileList.at(i).toLower().contains(".obj")) {
return true;
}
}
return false;
}
QString FileScriptingInterface::getTempDir() { QString FileScriptingInterface::getTempDir() {
QTemporaryDir dir; QTemporaryDir dir;
dir.setAutoRemove(false); dir.setAutoRemove(false);

View file

@ -32,6 +32,7 @@ signals:
private: private:
bool isTempDir(QString tempDir); bool isTempDir(QString tempDir);
bool hasModel(QStringList fileList);
QStringList unzipFile(QString path, QString tempDir); QStringList unzipFile(QString path, QString tempDir);
void recursiveFileScan(QFileInfo file, QString* dirName); void recursiveFileScan(QFileInfo file, QString* dirName);
void downloadZip(QString path, const QString link); void downloadZip(QString path, const QString link);

View file

@ -287,6 +287,15 @@ bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direct
return false; return false;
} }
bool AABox::rayHitsBoundingSphere(const glm::vec3& origin, const glm::vec3& direction) const {
glm::vec3 localCenter = calcCenter() - origin;
float distance = glm::dot(localCenter, direction);
const float ONE_OVER_TWO_SQUARED = 0.25f;
float radiusSquared = ONE_OVER_TWO_SQUARED * glm::length2(_scale);
return (glm::length2(localCenter) < radiusSquared
|| (glm::abs(distance) > 0.0f && glm::distance2(distance * direction, localCenter) < radiusSquared));
}
bool AABox::touchesSphere(const glm::vec3& center, float radius) const { bool AABox::touchesSphere(const glm::vec3& center, float radius) const {
// Avro's algorithm from this paper: http://www.mrtc.mdh.se/projects/3Dgraphics/paperF.pdf // Avro's algorithm from this paper: http://www.mrtc.mdh.se/projects/3Dgraphics/paperF.pdf
glm::vec3 e = glm::max(_corner - center, Vectors::ZERO) + glm::max(center - _corner - _scale, Vectors::ZERO); glm::vec3 e = glm::max(_corner - center, Vectors::ZERO) + glm::max(center - _corner - _scale, Vectors::ZERO);

View file

@ -71,6 +71,7 @@ public:
bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const; bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const;
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
BoxFace& face, glm::vec3& surfaceNormal) const; BoxFace& face, glm::vec3& surfaceNormal) const;
bool rayHitsBoundingSphere(const glm::vec3& origin, const glm::vec3& direction) const;
bool touchesSphere(const glm::vec3& center, float radius) const; // fast but may generate false positives bool touchesSphere(const glm::vec3& center, float radius) const; // fast but may generate false positives
bool touchesAAEllipsoid(const glm::vec3& center, const glm::vec3& radials) const; bool touchesAAEllipsoid(const glm::vec3& center, const glm::vec3& radials) const;
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const; bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const;

View file

@ -22,7 +22,6 @@
#include <QtCore/QDateTime> #include <QtCore/QDateTime>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QMutexLocker> #include <QtCore/QMutexLocker>
#include <QtCore/QRegExp>
#include <QtCore/QThread> #include <QtCore/QThread>
#include <QtCore/QTimer> #include <QtCore/QTimer>
@ -92,12 +91,13 @@ void LogHandler::setShouldDisplayMilliseconds(bool shouldDisplayMilliseconds) {
void LogHandler::flushRepeatedMessages() { void LogHandler::flushRepeatedMessages() {
QMutexLocker lock(&_mutex); QMutexLocker lock(&_mutex);
QHash<QString, int>::iterator message = _repeatMessageCountHash.begin(); for(auto& message: _repeatedMessages) {
while (message != _repeatMessageCountHash.end()) {
if (message.value() > 0) { if (message.messageCount > 1) {
QString repeatMessage = QString("%1 repeated log entries matching \"%2\" - Last entry: \"%3\"") QString repeatMessage = QString("%1 repeated log entries matching \"%2\" - Last entry: \"%3\"")
.arg(message.value()).arg(message.key()).arg(_lastRepeatedMessage.value(message.key())); .arg(message.messageCount - 1)
.arg(message.regexp.pattern())
.arg(message.lastMessage);
QMessageLogContext emptyContext; QMessageLogContext emptyContext;
lock.unlock(); lock.unlock();
@ -105,8 +105,7 @@ void LogHandler::flushRepeatedMessages() {
lock.relock(); lock.relock();
} }
_lastRepeatedMessage.remove(message.key()); message.messageCount = 0;
message = _repeatMessageCountHash.erase(message);
} }
} }
@ -118,36 +117,24 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
if (type == LogDebug) { if (type == LogDebug) {
// for debug messages, check if this matches any of our regexes for repeated log messages // for debug messages, check if this matches any of our regexes for repeated log messages
foreach(const QString& regexString, getInstance()._repeatedMessageRegexes) { for (auto& repeatRegex : _repeatedMessages) {
QRegExp repeatRegex(regexString); if (repeatRegex.regexp.indexIn(message) != -1) {
if (repeatRegex.indexIn(message) != -1) { // If we've printed the first one then return out.
if (repeatRegex.messageCount++ == 0) {
if (!_repeatMessageCountHash.contains(regexString)) {
// we have a match but didn't have this yet - output the first one
_repeatMessageCountHash[regexString] = 0;
// break the foreach so we output the first match
break; break;
} else {
// we have a match - add 1 to the count of repeats for this message and set this as the last repeated message
_repeatMessageCountHash[regexString] += 1;
_lastRepeatedMessage[regexString] = message;
// return out, we're not printing this one
return QString();
} }
repeatRegex.lastMessage = message;
return QString();
} }
} }
} }
if (type == LogDebug) { if (type == LogDebug) {
// see if this message is one we should only print once // see if this message is one we should only print once
foreach(const QString& regexString, getInstance()._onlyOnceMessageRegexes) { for (auto& onceOnly : _onetimeMessages) {
QRegExp onlyOnceRegex(regexString); if (onceOnly.regexp.indexIn(message) != -1) {
if (onlyOnceRegex.indexIn(message) != -1) { if (onceOnly.messageCount++ == 0) {
if (!_onlyOnceMessageCountHash.contains(message)) {
// we have a match and haven't yet printed this message. // we have a match and haven't yet printed this message.
_onlyOnceMessageCountHash[message] = 1;
// break the foreach so we output the first match
break; break;
} else { } else {
// We've already printed this message, don't print it again. // We've already printed this message, don't print it again.
@ -217,10 +204,16 @@ const QString& LogHandler::addRepeatedMessageRegex(const QString& regexString) {
QMetaObject::invokeMethod(this, "setupRepeatedMessageFlusher"); QMetaObject::invokeMethod(this, "setupRepeatedMessageFlusher");
QMutexLocker lock(&_mutex); QMutexLocker lock(&_mutex);
return *_repeatedMessageRegexes.insert(regexString); RepeatedMessage repeatRecord;
repeatRecord.regexp = QRegExp(regexString);
_repeatedMessages.push_back(repeatRecord);
return regexString;
} }
const QString& LogHandler::addOnlyOnceMessageRegex(const QString& regexString) { const QString& LogHandler::addOnlyOnceMessageRegex(const QString& regexString) {
QMutexLocker lock(&_mutex); QMutexLocker lock(&_mutex);
return *_onlyOnceMessageRegexes.insert(regexString); OnceOnlyMessage onetimeMessage;
onetimeMessage.regexp = QRegExp(regexString);
_onetimeMessages.push_back(onetimeMessage);
return regexString;
} }

View file

@ -13,11 +13,12 @@
#ifndef hifi_LogHandler_h #ifndef hifi_LogHandler_h
#define hifi_LogHandler_h #define hifi_LogHandler_h
#include <QHash>
#include <QObject> #include <QObject>
#include <QSet>
#include <QString> #include <QString>
#include <QRegExp>
#include <QMutex> #include <QMutex>
#include <vector>
#include <memory>
const int VERBOSE_LOG_INTERVAL_SECONDS = 5; const int VERBOSE_LOG_INTERVAL_SECONDS = 5;
@ -66,12 +67,19 @@ private:
bool _shouldOutputProcessID { false }; bool _shouldOutputProcessID { false };
bool _shouldOutputThreadID { false }; bool _shouldOutputThreadID { false };
bool _shouldDisplayMilliseconds { false }; bool _shouldDisplayMilliseconds { false };
QSet<QString> _repeatedMessageRegexes;
QHash<QString, int> _repeatMessageCountHash;
QHash<QString, QString> _lastRepeatedMessage;
QSet<QString> _onlyOnceMessageRegexes; struct RepeatedMessage {
QHash<QString, int> _onlyOnceMessageCountHash; QRegExp regexp;
int messageCount { 0 };
QString lastMessage;
};
std::vector<RepeatedMessage> _repeatedMessages;
struct OnceOnlyMessage {
QRegExp regexp;
int messageCount { 0 };
};
std::vector<OnceOnlyMessage> _onetimeMessages;
static QMutex _mutex; static QMutex _mutex;
}; };

View file

@ -272,17 +272,19 @@ SelectionDisplay = (function() {
var STRETCH_SPHERE_OFFSET = 0.06; var STRETCH_SPHERE_OFFSET = 0.06;
var STRETCH_SPHERE_CAMERA_DISTANCE_MULTIPLE = 0.01; var STRETCH_SPHERE_CAMERA_DISTANCE_MULTIPLE = 0.01;
var STRETCH_MINIMUM_DIMENSION = 0.001; var STRETCH_MINIMUM_DIMENSION = 0.001;
var STRETCH_DIRECTION_ALL_CAMERA_DISTANCE_MULTIPLE = 2; var STRETCH_ALL_MINIMUM_DIMENSION = 0.01;
var STRETCH_DIRECTION_ALL_CAMERA_DISTANCE_MULTIPLE = 6;
var STRETCH_PANEL_WIDTH = 0.01; var STRETCH_PANEL_WIDTH = 0.01;
var SCALE_CUBE_OFFSET = 0.5; var SCALE_CUBE_OFFSET = 0.5;
var SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE = 0.015; var SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE = 0.015;
var SCALE_MINIMUM_DIMENSION = 0.02;
var CLONER_OFFSET = { x:0.9, y:-0.9, z:0.9 }; var CLONER_OFFSET = { x:0.9, y:-0.9, z:0.9 };
var CTRL_KEY_CODE = 16777249; var CTRL_KEY_CODE = 16777249;
var AVATAR_COLLISIONS_OPTION = "Enable Avatar Collisions";
var TRANSLATE_DIRECTION = { var TRANSLATE_DIRECTION = {
X : 0, X : 0,
Y : 1, Y : 1,
@ -336,6 +338,8 @@ SelectionDisplay = (function() {
var ctrlPressed = false; var ctrlPressed = false;
var handleStretchCollisionOverride = false;
var handlePropertiesTranslateArrowCones = { var handlePropertiesTranslateArrowCones = {
shape: "Cone", shape: "Cone",
solid: true, solid: true,
@ -458,12 +462,12 @@ SelectionDisplay = (function() {
borderSize: 1.4 borderSize: 1.4
}; };
var handleScaleLBNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, -y, -z) var handleScaleLBNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, -y, -z)
var handleScaleRBNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, -y, z) var handleScaleRBNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, -y, -z)
var handleScaleLBFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, -y, -z) var handleScaleLBFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, -y, z)
var handleScaleRBFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, -y, z) var handleScaleRBFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, -y, z)
var handleScaleLTNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, y, -z) var handleScaleLTNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, y, -z)
var handleScaleRTNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, y, z) var handleScaleRTNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, y, -z)
var handleScaleLTFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, y, -z) var handleScaleLTFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, y, z)
var handleScaleRTFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, y, z) var handleScaleRTFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, y, z)
var handlePropertiesScaleEdge = { var handlePropertiesScaleEdge = {
@ -597,6 +601,11 @@ SelectionDisplay = (function() {
var activeTool = null; var activeTool = null;
var handleTools = {}; var handleTools = {};
that.shutdown = function() {
that.restoreAvatarCollisionsFromStretch();
}
Script.scriptEnding.connect(that.shutdown);
// We get mouseMoveEvents from the handControllers, via handControllerPointer. // We get mouseMoveEvents from the handControllers, via handControllerPointer.
// But we dont' get mousePressEvents. // But we dont' get mousePressEvents.
that.triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click'); that.triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click');
@ -1021,7 +1030,6 @@ SelectionDisplay = (function() {
return; return;
} }
if (SelectionManager.hasSelection()) { if (SelectionManager.hasSelection()) {
var position = SelectionManager.worldPosition; var position = SelectionManager.worldPosition;
var rotation = spaceMode === SPACE_LOCAL ? SelectionManager.localRotation : SelectionManager.worldRotation; var rotation = spaceMode === SPACE_LOCAL ? SelectionManager.localRotation : SelectionManager.worldRotation;
@ -1147,14 +1155,14 @@ SelectionDisplay = (function() {
rotation: scaleCubeRotation, rotation: scaleCubeRotation,
dimensions: scaleCubeDimensions dimensions: scaleCubeDimensions
}); });
var scaleRBNCubePosition = { x:-scaleCubeOffsetX, y:-scaleCubeOffsetY, z:scaleCubeOffsetZ }; var scaleRBNCubePosition = { x:scaleCubeOffsetX, y:-scaleCubeOffsetY, z:-scaleCubeOffsetZ };
scaleRBNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRBNCubePosition)); scaleRBNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRBNCubePosition));
Overlays.editOverlay(handleScaleRBNCube, { Overlays.editOverlay(handleScaleRBNCube, {
position: scaleRBNCubePosition, position: scaleRBNCubePosition,
rotation: scaleCubeRotation, rotation: scaleCubeRotation,
dimensions: scaleCubeDimensions dimensions: scaleCubeDimensions
}); });
var scaleLBFCubePosition = { x:scaleCubeOffsetX, y:-scaleCubeOffsetY, z:-scaleCubeOffsetZ }; var scaleLBFCubePosition = { x:-scaleCubeOffsetX, y:-scaleCubeOffsetY, z:scaleCubeOffsetZ };
scaleLBFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLBFCubePosition)); scaleLBFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLBFCubePosition));
Overlays.editOverlay(handleScaleLBFCube, { Overlays.editOverlay(handleScaleLBFCube, {
position: scaleLBFCubePosition, position: scaleLBFCubePosition,
@ -1175,14 +1183,14 @@ SelectionDisplay = (function() {
rotation: scaleCubeRotation, rotation: scaleCubeRotation,
dimensions: scaleCubeDimensions dimensions: scaleCubeDimensions
}); });
var scaleRTNCubePosition = { x:-scaleCubeOffsetX, y:scaleCubeOffsetY, z:scaleCubeOffsetZ }; var scaleRTNCubePosition = { x:scaleCubeOffsetX, y:scaleCubeOffsetY, z:-scaleCubeOffsetZ };
scaleRTNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRTNCubePosition)); scaleRTNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRTNCubePosition));
Overlays.editOverlay(handleScaleRTNCube, { Overlays.editOverlay(handleScaleRTNCube, {
position: scaleRTNCubePosition, position: scaleRTNCubePosition,
rotation: scaleCubeRotation, rotation: scaleCubeRotation,
dimensions: scaleCubeDimensions dimensions: scaleCubeDimensions
}); });
var scaleLTFCubePosition = { x:scaleCubeOffsetX, y:scaleCubeOffsetY, z:-scaleCubeOffsetZ }; var scaleLTFCubePosition = { x:-scaleCubeOffsetX, y:scaleCubeOffsetY, z:scaleCubeOffsetZ };
scaleLTFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLTFCubePosition)); scaleLTFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLTFCubePosition));
Overlays.editOverlay(handleScaleLTFCube, { Overlays.editOverlay(handleScaleLTFCube, {
position: scaleLTFCubePosition, position: scaleLTFCubePosition,
@ -1236,9 +1244,11 @@ SelectionDisplay = (function() {
}); });
// UPDATE STRETCH HIGHLIGHT PANELS // UPDATE STRETCH HIGHLIGHT PANELS
var scaleLTFCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleLTFCubePosition);
var scaleRBFCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleRBFCubePosition); var scaleRBFCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleRBFCubePosition);
var stretchPanelXDimensions = Vec3.subtract(scaleLTFCubePositionRotated, scaleRBFCubePositionRotated); var scaleRTFCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleRTFCubePosition);
var scaleLTNCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleLTNCubePosition);
var scaleRTNCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleRTNCubePosition);
var stretchPanelXDimensions = Vec3.subtract(scaleRTNCubePositionRotated, scaleRBFCubePositionRotated);
var tempY = Math.abs(stretchPanelXDimensions.y); var tempY = Math.abs(stretchPanelXDimensions.y);
stretchPanelXDimensions.x = STRETCH_PANEL_WIDTH; stretchPanelXDimensions.x = STRETCH_PANEL_WIDTH;
stretchPanelXDimensions.y = Math.abs(stretchPanelXDimensions.z); stretchPanelXDimensions.y = Math.abs(stretchPanelXDimensions.z);
@ -1249,8 +1259,6 @@ SelectionDisplay = (function() {
rotation: rotationZ, rotation: rotationZ,
dimensions: stretchPanelXDimensions dimensions: stretchPanelXDimensions
}); });
var scaleLTNCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleLTNCubePosition);
var scaleRTFCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleRTFCubePosition);
var stretchPanelYDimensions = Vec3.subtract(scaleLTNCubePositionRotated, scaleRTFCubePositionRotated); var stretchPanelYDimensions = Vec3.subtract(scaleLTNCubePositionRotated, scaleRTFCubePositionRotated);
var tempX = Math.abs(stretchPanelYDimensions.x); var tempX = Math.abs(stretchPanelYDimensions.x);
stretchPanelYDimensions.x = Math.abs(stretchPanelYDimensions.z); stretchPanelYDimensions.x = Math.abs(stretchPanelYDimensions.z);
@ -1262,9 +1270,7 @@ SelectionDisplay = (function() {
rotation: rotationY, rotation: rotationY,
dimensions: stretchPanelYDimensions dimensions: stretchPanelYDimensions
}); });
var scaleRTFCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleRTFCubePosition); var stretchPanelZDimensions = Vec3.subtract(scaleLTNCubePositionRotated, scaleRBFCubePositionRotated);
var scaleRBNCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleRBNCubePosition);
var stretchPanelZDimensions = Vec3.subtract(scaleRTFCubePositionRotated, scaleRBNCubePositionRotated);
var tempX = Math.abs(stretchPanelZDimensions.x); var tempX = Math.abs(stretchPanelZDimensions.x);
stretchPanelZDimensions.x = Math.abs(stretchPanelZDimensions.y); stretchPanelZDimensions.x = Math.abs(stretchPanelZDimensions.y);
stretchPanelZDimensions.y = tempX; stretchPanelZDimensions.y = tempX;
@ -1743,6 +1749,13 @@ SelectionDisplay = (function() {
}; };
}; };
that.restoreAvatarCollisionsFromStretch = function() {
if (handleStretchCollisionOverride) {
Menu.setIsOptionChecked(AVATAR_COLLISIONS_OPTION, true);
handleStretchCollisionOverride = false;
}
}
// TOOL DEFINITION: HANDLE STRETCH TOOL // TOOL DEFINITION: HANDLE STRETCH TOOL
function makeStretchTool(stretchMode, directionEnum, directionVec, pivot, offset, stretchPanel, scaleHandle) { function makeStretchTool(stretchMode, directionEnum, directionVec, pivot, offset, stretchPanel, scaleHandle) {
var directionFor3DStretch = directionVec; var directionFor3DStretch = directionVec;
@ -1945,6 +1958,10 @@ SelectionDisplay = (function() {
if (scaleHandle != null) { if (scaleHandle != null) {
Overlays.editOverlay(scaleHandle, { color: COLOR_SCALE_CUBE_SELECTED }); Overlays.editOverlay(scaleHandle, { color: COLOR_SCALE_CUBE_SELECTED });
} }
if (Menu.isOptionChecked(AVATAR_COLLISIONS_OPTION)) {
Menu.setIsOptionChecked(AVATAR_COLLISIONS_OPTION, false);
handleStretchCollisionOverride = true;
}
}; };
var onEnd = function(event, reason) { var onEnd = function(event, reason) {
@ -1954,11 +1971,12 @@ SelectionDisplay = (function() {
if (scaleHandle != null) { if (scaleHandle != null) {
Overlays.editOverlay(scaleHandle, { color: COLOR_SCALE_CUBE }); Overlays.editOverlay(scaleHandle, { color: COLOR_SCALE_CUBE });
} }
that.restoreAvatarCollisionsFromStretch();
pushCommandForSelections(); pushCommandForSelections();
}; };
var onMove = function(event) { var onMove = function(event) {
var proportional = (spaceMode === SPACE_WORLD) || event.isShifted || directionEnum === STRETCH_DIRECTION.ALL; var proportional = (spaceMode === SPACE_WORLD) || directionEnum === STRETCH_DIRECTION.ALL;
var position, dimensions, rotation; var position, dimensions, rotation;
if (spaceMode === SPACE_LOCAL) { if (spaceMode === SPACE_LOCAL) {
@ -1999,10 +2017,10 @@ SelectionDisplay = (function() {
vector = grid.snapToSpacing(vector); vector = grid.snapToSpacing(vector);
var changeInDimensions = Vec3.multiply(NEGATE_VECTOR, vec3Mult(localSigns, vector)); var changeInDimensions = Vec3.multiply(NEGATE_VECTOR, vec3Mult(localSigns, vector));
if (directionEnum === STRETCH_DIRECTION.ALL) { if (directionEnum === STRETCH_DIRECTION.ALL) {
var toCameraDistance = getDistanceToCamera(position); var toCameraDistance = getDistanceToCamera(position);
var dimensionsMultiple = toCameraDistance * STRETCH_DIRECTION_ALL_CAMERA_DISTANCE_MULTIPLE; var dimensionsMultiple = toCameraDistance * STRETCH_DIRECTION_ALL_CAMERA_DISTANCE_MULTIPLE;
changeInDimensions = Vec3.multiply(changeInDimensions, dimensionsMultiple); changeInDimensions = Vec3.multiply(changeInDimensions, dimensionsMultiple);
} }
var newDimensions; var newDimensions;
@ -2027,9 +2045,11 @@ SelectionDisplay = (function() {
newDimensions = Vec3.sum(initialDimensions, changeInDimensions); newDimensions = Vec3.sum(initialDimensions, changeInDimensions);
} }
newDimensions.x = Math.max(newDimensions.x, STRETCH_MINIMUM_DIMENSION); var minimumDimension = directionEnum === STRETCH_DIRECTION.ALL ? STRETCH_ALL_MINIMUM_DIMENSION :
newDimensions.y = Math.max(newDimensions.y, STRETCH_MINIMUM_DIMENSION); STRETCH_MINIMUM_DIMENSION;
newDimensions.z = Math.max(newDimensions.z, STRETCH_MINIMUM_DIMENSION); newDimensions.x = Math.max(newDimensions.x, minimumDimension);
newDimensions.y = Math.max(newDimensions.y, minimumDimension);
newDimensions.z = Math.max(newDimensions.z, minimumDimension);
var changeInPosition = Vec3.multiplyQbyV(rotation, vec3Mult(localDeltaPivot, changeInDimensions)); var changeInPosition = Vec3.multiplyQbyV(rotation, vec3Mult(localDeltaPivot, changeInDimensions));
if (directionEnum === STRETCH_DIRECTION.ALL) { if (directionEnum === STRETCH_DIRECTION.ALL) {
@ -2089,10 +2109,10 @@ SelectionDisplay = (function() {
directionVector = { x:1, y:1, z:1 }; directionVector = { x:1, y:1, z:1 };
selectedHandle = handleScaleLBNCube; selectedHandle = handleScaleLBNCube;
} else if (directionEnum === SCALE_DIRECTION.RBN) { } else if (directionEnum === SCALE_DIRECTION.RBN) {
directionVector = { x:1, y:1, z:-1 }; directionVector = { x:-1, y:1, z:1 };
selectedHandle = handleScaleRBNCube; selectedHandle = handleScaleRBNCube;
} else if (directionEnum === SCALE_DIRECTION.LBF) { } else if (directionEnum === SCALE_DIRECTION.LBF) {
directionVector = { x:-1, y:1, z:1 }; directionVector = { x:1, y:1, z:-1 };
selectedHandle = handleScaleLBFCube; selectedHandle = handleScaleLBFCube;
} else if (directionEnum === SCALE_DIRECTION.RBF) { } else if (directionEnum === SCALE_DIRECTION.RBF) {
directionVector = { x:-1, y:1, z:-1 }; directionVector = { x:-1, y:1, z:-1 };
@ -2101,10 +2121,10 @@ SelectionDisplay = (function() {
directionVector = { x:1, y:-1, z:1 }; directionVector = { x:1, y:-1, z:1 };
selectedHandle = handleScaleLTNCube; selectedHandle = handleScaleLTNCube;
} else if (directionEnum === SCALE_DIRECTION.RTN) { } else if (directionEnum === SCALE_DIRECTION.RTN) {
directionVector = { x:1, y:-1, z:-1 }; directionVector = { x:-1, y:-1, z:1 };
selectedHandle = handleScaleRTNCube; selectedHandle = handleScaleRTNCube;
} else if (directionEnum === SCALE_DIRECTION.LTF) { } else if (directionEnum === SCALE_DIRECTION.LTF) {
directionVector = { x:-1, y:-1, z:1 }; directionVector = { x:1, y:-1, z:-1 };
selectedHandle = handleScaleLTFCube; selectedHandle = handleScaleLTFCube;
} else if (directionEnum === SCALE_DIRECTION.RTF) { } else if (directionEnum === SCALE_DIRECTION.RTF) {
directionVector = { x:-1, y:-1, z:-1 }; directionVector = { x:-1, y:-1, z:-1 };

View file

@ -439,8 +439,9 @@ HifiEntityUI.prototype = {
$colPickContainer.colpick({ $colPickContainer.colpick({
colorScheme: 'dark', colorScheme: (group.layoutColorScheme === undefined ? 'dark' : group.layoutColorScheme),
layout: 'hex', layout: (group.layoutType === undefined ? 'hex' : group.layoutType),
submit: (group.useSubmitButton === undefined ? true : group.useSubmitButton),
color: { color: {
r: domArray[0].value, r: domArray[0].value,
g: domArray[1].value, g: domArray[1].value,

View file

@ -27,6 +27,7 @@
<link rel="stylesheet" type="text/css" href="../html/css/hifi-style.css"> <link rel="stylesheet" type="text/css" href="../html/css/hifi-style.css">
<link rel="stylesheet" type="text/css" href="../html/css/edit-style.css"> <link rel="stylesheet" type="text/css" href="../html/css/edit-style.css">
<link rel="stylesheet" type="text/css" href="../html/css/colpick.css">
<link rel="stylesheet" type="text/css" href="particle-style.css"> <link rel="stylesheet" type="text/css" href="particle-style.css">
</head> </head>
<body> <body>

View file

@ -236,7 +236,10 @@
red: 255, red: 255,
green: 255, green: 255,
blue: 255 blue: 255
} },
layoutType: "hex",
layoutColorScheme: "dark",
useSubmitButton: false
}, },
{ {
type: "Row" type: "Row"
@ -249,7 +252,10 @@
red: 0, red: 0,
green: 0, green: 0,
blue: 0 blue: 0
} },
layoutType: "hex",
layoutColorScheme: "dark",
useSubmitButton: false
}, },
{ {
type: "Row" type: "Row"
@ -262,7 +268,10 @@
red: 255, red: 255,
green: 255, green: 255,
blue: 255 blue: 255
} },
layoutType: "hex",
layoutColorScheme: "dark",
useSubmitButton: false
}, },
{ {
type: "Row" type: "Row"
@ -275,7 +284,10 @@
red: 255, red: 255,
green: 255, green: 255,
blue: 255 blue: 255
} },
layoutType: "hex",
layoutColorScheme: "dark",
useSubmitButton: false
}, },
{ {
type: "Row" type: "Row"