mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 05:57:29 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into addRecursionToAutotester
This commit is contained in:
commit
cb24fe6166
82 changed files with 424 additions and 340 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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!";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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*)
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -2984,4 +2984,4 @@ std::unordered_map<std::string, graphics::MultiMaterial> EntityItem::getMaterial
|
||||||
toReturn = _materials;
|
toReturn = _materials;
|
||||||
}
|
}
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()>;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue