mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge remote-tracking branch 'hifi/master' into android_joystick_rotate_move
This commit is contained in:
commit
ce0d76be2b
154 changed files with 1357 additions and 617 deletions
|
@ -1937,9 +1937,11 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
|||
|
||||
const QString UUID_REGEX_STRING = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
||||
|
||||
QPointer<HTTPConnection> connectionPtr { connection };
|
||||
|
||||
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
||||
|
||||
auto getSetting = [this](QString keyPath, QVariant value) -> bool {
|
||||
auto getSetting = [this](QString keyPath, QVariant& value) -> bool {
|
||||
|
||||
value = _settingsManager.valueForKeyPath(keyPath);
|
||||
if (!value.isValid()) {
|
||||
|
@ -2120,30 +2122,38 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
|||
return true;
|
||||
} else if (url.path() == URI_API_BACKUPS) {
|
||||
auto deferred = makePromise("getAllBackupsAndStatus");
|
||||
deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
if (!connectionPtr) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonDocument docJSON(QJsonObject::fromVariantMap(result));
|
||||
|
||||
connection->respond(HTTPConnection::StatusCode200, docJSON.toJson(), JSON_MIME_TYPE.toUtf8());
|
||||
connectionPtr->respond(HTTPConnection::StatusCode200, docJSON.toJson(), JSON_MIME_TYPE.toUtf8());
|
||||
});
|
||||
_contentManager->getAllBackupsAndStatus(deferred);
|
||||
return true;
|
||||
} else if (url.path().startsWith(URI_API_BACKUPS_ID)) {
|
||||
auto id = url.path().mid(QString(URI_API_BACKUPS_ID).length());
|
||||
auto deferred = makePromise("consolidateBackup");
|
||||
deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
if (!connectionPtr) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject rootJSON;
|
||||
auto success = result["success"].toBool();
|
||||
if (success) {
|
||||
auto path = result["backupFilePath"].toString();
|
||||
auto file { std::unique_ptr<QFile>(new QFile(path)) };
|
||||
if (file->open(QIODevice::ReadOnly)) {
|
||||
connection->respond(HTTPConnection::StatusCode200, std::move(file));
|
||||
connectionPtr->respond(HTTPConnection::StatusCode200, std::move(file));
|
||||
} else {
|
||||
qCritical(domain_server) << "Unable to load consolidated backup at:" << path << result;
|
||||
connection->respond(HTTPConnection::StatusCode500, "Error opening backup");
|
||||
connectionPtr->respond(HTTPConnection::StatusCode500, "Error opening backup");
|
||||
}
|
||||
} else {
|
||||
connection->respond(HTTPConnection::StatusCode400);
|
||||
connectionPtr->respond(HTTPConnection::StatusCode400);
|
||||
}
|
||||
});
|
||||
_contentManager->consolidateBackup(deferred, id);
|
||||
|
@ -2264,12 +2274,16 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
|||
} else if (uploadedFilename.endsWith(".zip", Qt::CaseInsensitive)) {
|
||||
auto deferred = makePromise("recoverFromUploadedBackup");
|
||||
|
||||
deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
if (!connectionPtr) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject rootJSON;
|
||||
auto success = result["success"].toBool();
|
||||
rootJSON["success"] = success;
|
||||
QJsonDocument docJSON(rootJSON);
|
||||
connection->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(),
|
||||
connectionPtr->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(),
|
||||
JSON_MIME_TYPE.toUtf8());
|
||||
});
|
||||
|
||||
|
@ -2297,12 +2311,16 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
|||
}
|
||||
|
||||
auto deferred = makePromise("createManualBackup");
|
||||
deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
if (!connectionPtr) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject rootJSON;
|
||||
auto success = result["success"].toBool();
|
||||
rootJSON["success"] = success;
|
||||
QJsonDocument docJSON(rootJSON);
|
||||
connection->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(),
|
||||
connectionPtr->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(),
|
||||
JSON_MIME_TYPE.toUtf8());
|
||||
});
|
||||
_contentManager->createManualBackup(deferred, it.value());
|
||||
|
@ -2322,12 +2340,16 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
|||
} else if (url.path().startsWith(URI_API_BACKUPS_RECOVER)) {
|
||||
auto id = url.path().mid(QString(URI_API_BACKUPS_RECOVER).length());
|
||||
auto deferred = makePromise("recoverFromBackup");
|
||||
deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
if (!connectionPtr) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject rootJSON;
|
||||
auto success = result["success"].toBool();
|
||||
rootJSON["success"] = success;
|
||||
QJsonDocument docJSON(rootJSON);
|
||||
connection->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(),
|
||||
connectionPtr->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(),
|
||||
JSON_MIME_TYPE.toUtf8());
|
||||
});
|
||||
_contentManager->recoverFromBackup(deferred, id);
|
||||
|
@ -2423,12 +2445,16 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
|||
if (url.path().startsWith(URI_API_BACKUPS_ID)) {
|
||||
auto id = url.path().mid(QString(URI_API_BACKUPS_ID).length());
|
||||
auto deferred = makePromise("deleteBackup");
|
||||
deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
if (!connectionPtr) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject rootJSON;
|
||||
auto success = result["success"].toBool();
|
||||
rootJSON["success"] = success;
|
||||
QJsonDocument docJSON(rootJSON);
|
||||
connection->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(),
|
||||
connectionPtr->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(),
|
||||
JSON_MIME_TYPE.toUtf8());
|
||||
});
|
||||
_contentManager->deleteBackup(deferred, id);
|
||||
|
|
|
@ -33,8 +33,6 @@ Item {
|
|||
width: parent.width
|
||||
height: parent.height
|
||||
}
|
||||
|
||||
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
|
||||
|
||||
Timer {
|
||||
id: updateList
|
||||
|
|
|
@ -257,11 +257,7 @@ Item {
|
|||
id: octreeCol
|
||||
spacing: 4; x: 4; y: 4;
|
||||
StatText {
|
||||
text: "Render Engine: " + root.engineFrameTime.toFixed(1) + " ms"
|
||||
}
|
||||
StatText {
|
||||
visible: root.expanded
|
||||
text: root.renderEngineStats
|
||||
text: "Engine: " + root.engineFrameTime.toFixed(1) + " ms"
|
||||
}
|
||||
StatText {
|
||||
text: "Batch: " + root.batchFrameTime.toFixed(1) + " ms"
|
||||
|
|
|
@ -109,9 +109,9 @@ CheckBox {
|
|||
|
||||
contentItem: Text {
|
||||
id: root
|
||||
FontLoader { id: ralewaySemiBold; source: "qrc:/fonts/Raleway-SemiBold.ttf"; }
|
||||
font.pixelSize: hifi.fontSizes.inputLabel
|
||||
font.family: ralewaySemiBold.name
|
||||
font.family: "Raleway"
|
||||
font.weight: Font.DemiBold
|
||||
text: checkBox.text
|
||||
color: checkBox.color
|
||||
x: 2
|
||||
|
|
|
@ -125,8 +125,7 @@ Rectangle {
|
|||
TextInput {
|
||||
id: mirrorText
|
||||
visible: showMirrorText
|
||||
FontLoader { id: font; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
|
||||
font.family: font.name
|
||||
font.family: "Fira Sans"
|
||||
font.pixelSize: 20
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
@ -165,8 +164,6 @@ Rectangle {
|
|||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 0
|
||||
|
||||
FontLoader { id: hiFiGlyphs; source: "qrc:/fonts/hifi-glyphs.ttf"; }
|
||||
|
||||
Column {
|
||||
id: columnAlpha
|
||||
width: keyboardWidth
|
||||
|
@ -250,7 +247,7 @@ Rectangle {
|
|||
Key { width: 43; glyph: ","; }
|
||||
Key { width: 43; glyph: "."; }
|
||||
Key {
|
||||
fontFamily: hiFiGlyphs.name;
|
||||
fontFamily: "hifi-glyphs";
|
||||
fontPixelSize: 48;
|
||||
letterAnchors.topMargin: -4;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
@ -343,7 +340,7 @@ Rectangle {
|
|||
Key { width: 43; glyph: ","; }
|
||||
Key { width: 43; glyph: "."; }
|
||||
Key {
|
||||
fontFamily: hiFiGlyphs.name;
|
||||
fontFamily: "hifi-glyphs";
|
||||
fontPixelSize: 48;
|
||||
letterAnchors.topMargin: -4;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
|
|
@ -25,8 +25,7 @@ SpinBox {
|
|||
property color colorLabelInside: hifi.colors.white
|
||||
property real controlHeight: height + (spinBoxLabel.visible ? spinBoxLabel.height + spinBoxLabel.anchors.bottomMargin : 0)
|
||||
|
||||
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
|
||||
font.family: firaSansSemiBold.name
|
||||
font.family: "Fira Sans SemiBold"
|
||||
font.pixelSize: hifi.fontSizes.textFieldInput
|
||||
height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control.
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@ import "../styles-uit"
|
|||
TextEdit {
|
||||
|
||||
property real size: 32
|
||||
|
||||
FontLoader { id: ralewaySemiBold; source: "qrc:/fonts/Raleway-SemiBold.ttf"; }
|
||||
font.family: ralewaySemiBold.name
|
||||
|
||||
font.family: "Raleway"
|
||||
font.weight: Font.DemiBold
|
||||
font.pointSize: size
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
|
|
|
@ -34,9 +34,7 @@ TextField {
|
|||
|
||||
placeholderText: textField.placeholderText
|
||||
|
||||
FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
|
||||
FontLoader { id: hifiGlyphs; source: "qrc:/fonts/hifi-glyphs.ttf"; }
|
||||
font.family: firaSansRegular.name
|
||||
font.family: "Fira Sans"
|
||||
font.pixelSize: hifi.fontSizes.textFieldInput
|
||||
height: implicitHeight + 3 // Make surrounding box higher so that highlight is vertically centered.
|
||||
property alias textFieldLabel: textFieldLabel
|
||||
|
|
|
@ -4,13 +4,12 @@ import QtQuick.Controls.Styles 1.3
|
|||
|
||||
Text {
|
||||
id: root
|
||||
FontLoader { id: iconFont; source: "qrc:/fonts/fontawesome-webfont.ttf"; }
|
||||
property int size: 32
|
||||
width: size
|
||||
height: size
|
||||
font.pixelSize: size
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.family: iconFont.name
|
||||
font.family: "FontAwesome"
|
||||
}
|
||||
|
||||
|
|
|
@ -532,9 +532,6 @@ ModalWindow {
|
|||
itemDelegate: Item {
|
||||
clip: true
|
||||
|
||||
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
|
||||
FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
|
||||
|
||||
FiraSansSemiBold {
|
||||
text: getText();
|
||||
elide: styleData.elideMode
|
||||
|
@ -548,7 +545,7 @@ ModalWindow {
|
|||
size: hifi.fontSizes.tableText
|
||||
color: hifi.colors.baseGrayHighlight
|
||||
font.family: (styleData.row !== -1 && fileTableView.model.get(styleData.row).fileIsDir)
|
||||
? firaSansSemiBold.name : firaSansRegular.name
|
||||
? "Fira Sans SemiBold" : "Fira Sans"
|
||||
|
||||
function getText() {
|
||||
if (styleData.row === -1) {
|
||||
|
|
|
@ -496,9 +496,6 @@ TabletModalWindow {
|
|||
itemDelegate: Item {
|
||||
clip: true
|
||||
|
||||
//FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
|
||||
//FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
|
||||
|
||||
FiraSansSemiBold {
|
||||
text: getText();
|
||||
elide: styleData.elideMode
|
||||
|
@ -512,7 +509,7 @@ TabletModalWindow {
|
|||
size: hifi.fontSizes.tableText
|
||||
color: hifi.colors.baseGrayHighlight
|
||||
//font.family: (styleData.row !== -1 && fileTableView.model.get(styleData.row).fileIsDir)
|
||||
//? firaSansSemiBold.name : firaSansRegular.name
|
||||
//? "Fira Sans SemiBold" : "Fira Sans"
|
||||
|
||||
function getText() {
|
||||
if (styleData.row === -1) {
|
||||
|
|
|
@ -345,9 +345,6 @@ Item {
|
|||
itemDelegate: Item {
|
||||
clip: true
|
||||
|
||||
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
|
||||
FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
|
||||
|
||||
FiraSansSemiBold {
|
||||
text: styleData.value
|
||||
elide: styleData.elideMode
|
||||
|
@ -361,7 +358,7 @@ Item {
|
|||
size: hifi.fontSizes.tableText
|
||||
color: hifi.colors.baseGrayHighlight
|
||||
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
|
||||
|
||||
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
|
||||
font.family: firaSansSemiBold.name
|
||||
font.family: "Fira Sans SemiBold"
|
||||
font.pixelSize: hifi.fontSizes.textFieldInput
|
||||
height: hifi.dimensions.tableRowHeight
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@ Item {
|
|||
property int dialogHeight;
|
||||
property int comboOptionTextSize: 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;
|
||||
id: combo;
|
||||
anchors.fill: parent;
|
||||
|
|
|
@ -24,8 +24,6 @@ Item {
|
|||
property real headerTextMargin: -5
|
||||
property real headerGlyphMargin: -15
|
||||
property bool isDesktop: false
|
||||
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
|
||||
FontLoader { id: ralewaySemiBold; source: "qrc:/fonts/Raleway-SemiBold.ttf"; }
|
||||
visible: false
|
||||
id: letterbox
|
||||
anchors.fill: parent
|
||||
|
@ -78,7 +76,8 @@ Item {
|
|||
// Text Size
|
||||
font.pixelSize: headerTextPixelSize
|
||||
// Style
|
||||
font.family: ralewaySemiBold.name
|
||||
font.family: "Raleway"
|
||||
font.weight: Font.DemiBold
|
||||
color: hifi.colors.darkGray
|
||||
horizontalAlignment: Text.AlignHLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
@ -101,7 +100,7 @@ Item {
|
|||
horizontalAlignment: Text.AlignHLeft
|
||||
// Style
|
||||
font.pixelSize: popupTextPixelSize
|
||||
font.family: ralewayRegular.name
|
||||
font.family: "Raleway"
|
||||
color: hifi.colors.darkGray
|
||||
wrapMode: Text.WordWrap
|
||||
textFormat: Text.StyledText
|
||||
|
|
|
@ -23,8 +23,6 @@ Item {
|
|||
property real popupTextPixelSize: 16
|
||||
property real headerTextMargin: -5
|
||||
property real headerGlyphMargin: -15
|
||||
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
|
||||
FontLoader { id: ralewaySemiBold; source: "qrc:/fonts/Raleway-SemiBold.ttf"; }
|
||||
visible: false
|
||||
id: letterbox
|
||||
anchors.fill: parent
|
||||
|
@ -82,7 +80,8 @@ Item {
|
|||
// Text Size
|
||||
font.pixelSize: headerTextPixelSize
|
||||
// Style
|
||||
font.family: ralewaySemiBold.name
|
||||
font.family: "Raleway"
|
||||
font.weight: Font.DemiBold
|
||||
color: hifi.colors.darkGray
|
||||
horizontalAlignment: Text.AlignHLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
@ -127,7 +126,7 @@ Item {
|
|||
horizontalAlignment: Text.AlignHLeft
|
||||
// Style
|
||||
font.pixelSize: popupTextPixelSize
|
||||
font.family: ralewayRegular.name
|
||||
font.family: "Raleway"
|
||||
color: hifi.colors.darkGray
|
||||
wrapMode: Text.WordWrap
|
||||
textFormat: Text.StyledText
|
||||
|
|
|
@ -177,8 +177,7 @@ Item {
|
|||
anchors.right: parent.right
|
||||
anchors.rightMargin: editGlyph.width + editGlyph.anchors.rightMargin
|
||||
// Style
|
||||
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
|
||||
font.family: firaSansSemiBold.name
|
||||
font.family: "Fira Sans SemiBold"
|
||||
font.pixelSize: displayNameTextPixelSize
|
||||
selectionColor: hifi.colors.blueAccent
|
||||
selectedTextColor: "black"
|
||||
|
|
|
@ -908,7 +908,6 @@ Rectangle {
|
|||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
}
|
||||
|
||||
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
|
||||
Text {
|
||||
id: connectionHelpText;
|
||||
// Anchors
|
||||
|
@ -923,7 +922,7 @@ Rectangle {
|
|||
horizontalAlignment: Text.AlignHLeft
|
||||
// Style
|
||||
font.pixelSize: 18;
|
||||
font.family: ralewayRegular.name
|
||||
font.family: "Raleway"
|
||||
color: hifi.colors.darkGray
|
||||
wrapMode: Text.WordWrap
|
||||
textFormat: Text.StyledText;
|
||||
|
|
|
@ -112,6 +112,7 @@ Rectangle {
|
|||
|
||||
// mute is in its own row
|
||||
RowLayout {
|
||||
spacing: (margins.sizeCheckBox - 10.5) * 3;
|
||||
AudioControls.CheckBox {
|
||||
id: muteMic
|
||||
text: qsTr("Mute microphone");
|
||||
|
@ -123,6 +124,19 @@ Rectangle {
|
|||
checked = Qt.binding(function() { return AudioScriptingInterface.muted; }); // restore binding
|
||||
}
|
||||
}
|
||||
|
||||
AudioControls.CheckBox {
|
||||
id: stereoMic
|
||||
spacing: muteMic.spacing;
|
||||
text: qsTr("Enable stereo input");
|
||||
checked: AudioScriptingInterface.isStereoInput();
|
||||
onClicked: {
|
||||
var success = AudioScriptingInterface.setStereoInput(checked);
|
||||
if (!success) {
|
||||
checked = !checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
|
@ -204,6 +218,8 @@ Rectangle {
|
|||
text: devicename
|
||||
onPressed: {
|
||||
if (!checked) {
|
||||
stereoMic.checked = false;
|
||||
AudioScriptingInterface.setStereoInput(false); // the next selected audio device might not support stereo
|
||||
AudioScriptingInterface.setInputDevice(info, bar.currentIndex === 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,8 +147,7 @@ Rectangle {
|
|||
} else if (root.itemHref.indexOf('.json') > -1) {
|
||||
root.itemType = "entity"; // "wearable" type handled later
|
||||
} else {
|
||||
console.log("WARNING - Item type is UNKNOWN!");
|
||||
root.itemType = "entity";
|
||||
root.itemType = "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -141,10 +141,9 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
|
||||
TextMetrics {
|
||||
id: textMetrics;
|
||||
font.family: ralewayRegular.name
|
||||
font.family: "Raleway"
|
||||
text: usernameText.text;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,10 @@ Item {
|
|||
hoverEnabled: true;
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
sendSignalToParent({method: 'maybeEnableHmdPreview'});
|
||||
}
|
||||
|
||||
// This will cause a bug -- if you bring up passphrase selection in HUD mode while
|
||||
// in HMD while having HMD preview enabled, then move, then finish passphrase selection,
|
||||
// HMD preview will stay off.
|
||||
|
|
|
@ -174,11 +174,12 @@ Rectangle {
|
|||
WalletChoice {
|
||||
id: walletChoice;
|
||||
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();
|
||||
if (isReset) {
|
||||
walletResetSetup();
|
||||
} else {
|
||||
Commerce.clearWallet();
|
||||
var msg = { referrer: walletChoice.referrer }
|
||||
followReferrer(msg);
|
||||
}
|
||||
|
@ -236,6 +237,8 @@ Rectangle {
|
|||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
} else if (msg.method === 'maybeEnableHmdPreview') {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -398,6 +398,7 @@ Item {
|
|||
//
|
||||
Item {
|
||||
id: filterBarContainer;
|
||||
visible: !connectionInstructions.visible;
|
||||
// Size
|
||||
height: 40;
|
||||
// Anchors
|
||||
|
@ -495,6 +496,78 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "Make a Connection" instructions
|
||||
Rectangle {
|
||||
id: connectionInstructions;
|
||||
visible: connectionsModel.count === 0 && !connectionsLoading.visible;
|
||||
anchors.fill: parent;
|
||||
color: "white";
|
||||
|
||||
RalewayRegular {
|
||||
id: makeAConnectionText;
|
||||
// Properties
|
||||
text: "Make a Connection";
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 20;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
// Text Size
|
||||
size: 24;
|
||||
// Text Positioning
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
// Style
|
||||
color: hifi.colors.darkGray;
|
||||
}
|
||||
|
||||
Image {
|
||||
id: connectionImage;
|
||||
source: "qrc:/icons/connection.svg";
|
||||
width: 150;
|
||||
height: 150;
|
||||
mipmap: true;
|
||||
// Anchors
|
||||
anchors.top: makeAConnectionText.bottom;
|
||||
anchors.topMargin: 15;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
}
|
||||
|
||||
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
|
||||
Text {
|
||||
id: connectionHelpText;
|
||||
// Anchors
|
||||
anchors.top: connectionImage.bottom;
|
||||
anchors.topMargin: 15;
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 40;
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 40;
|
||||
// Text alignment
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHLeft
|
||||
// Style
|
||||
font.pixelSize: 18;
|
||||
font.family: ralewayRegular.name
|
||||
color: hifi.colors.darkGray
|
||||
wrapMode: Text.Wrap
|
||||
textFormat: Text.StyledText;
|
||||
property string instructions:
|
||||
"<b>When you meet someone you want to remember later, you can <font color='purple'>connect</font> with a handshake:</b><br><br>"
|
||||
property string hmdMountedInstructions:
|
||||
"1. Put your hand out onto their hand and squeeze your controller's grip button on its side.<br>" +
|
||||
"2. Once the other person puts their hand onto yours, you'll see your connection form.<br>" +
|
||||
"3. After about 3 seconds, you're connected!"
|
||||
property string hmdNotMountedInstructions:
|
||||
"1. Press and hold the 'x' key to extend your arm.<br>" +
|
||||
"2. Once the other person puts their hand onto yours, you'll see your connection form.<br>" +
|
||||
"3. After about 3 seconds, you're connected!";
|
||||
// Text
|
||||
text:
|
||||
HMD.mounted ? instructions + hmdMountedInstructions : instructions + hmdNotMountedInstructions
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -924,14 +997,13 @@ Item {
|
|||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
height: 95;
|
||||
|
||||
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
|
||||
|
||||
TextArea {
|
||||
id: optionalMessage;
|
||||
property int maximumLength: 72;
|
||||
property string previousText: text;
|
||||
placeholderText: "<i>Optional Public Message (" + maximumLength + " character limit)</i>";
|
||||
font.family: firaSansSemiBold.name;
|
||||
font.family: "Fira Sans SemiBold";
|
||||
font.pixelSize: 20;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
import QtQuick 2.5
|
||||
import Qt.labs.settings 1.0
|
||||
|
||||
import "../../dialogs"
|
||||
|
||||
PreferencesDialog {
|
||||
id: root
|
||||
objectName: "GraphicsPreferencesDialog"
|
||||
title: "Graphics Settings"
|
||||
showCategories: ["Graphics"]
|
||||
property var settings: Settings {
|
||||
category: root.objectName
|
||||
property alias x: root.x
|
||||
property alias y: root.y
|
||||
property alias width: root.width
|
||||
property alias height: root.height
|
||||
}
|
||||
}
|
||||
|
|
@ -659,8 +659,7 @@ Rectangle {
|
|||
|
||||
text: styleData.value
|
||||
|
||||
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
|
||||
font.family: firaSansSemiBold.name
|
||||
font.family: "Fira Sans SemiBold"
|
||||
font.pixelSize: hifi.fontSizes.textFieldInput
|
||||
height: hifi.dimensions.tableRowHeight
|
||||
|
||||
|
|
|
@ -478,9 +478,6 @@ Rectangle {
|
|||
itemDelegate: Item {
|
||||
clip: true
|
||||
|
||||
//FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
|
||||
//FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
|
||||
|
||||
FiraSansSemiBold {
|
||||
text: getText();
|
||||
elide: styleData.elideMode
|
||||
|
@ -494,7 +491,7 @@ Rectangle {
|
|||
size: hifi.fontSizes.tableText
|
||||
color: hifi.colors.baseGrayHighlight
|
||||
//font.family: (styleData.row !== -1 && fileTableView.model.get(styleData.row).fileIsDir)
|
||||
//? firaSansSemiBold.name : firaSansRegular.name
|
||||
//? "Fira Sans SemiBold" : "Fira Sans"
|
||||
|
||||
function getText() {
|
||||
if (styleData.row === -1) {
|
||||
|
|
|
@ -14,10 +14,9 @@ import QtQuick.Controls.Styles 1.4
|
|||
|
||||
Text {
|
||||
id: root
|
||||
FontLoader { id: anonymousProRegular; source: "qrc:/fonts/AnonymousPro-Regular.ttf"; }
|
||||
property real size: 32
|
||||
font.pixelSize: size
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.family: anonymousProRegular.name
|
||||
font.family: "Anonymous Pro"
|
||||
}
|
||||
|
|
|
@ -14,10 +14,9 @@ import QtQuick.Controls.Styles 1.4
|
|||
|
||||
Text {
|
||||
id: root
|
||||
FontLoader { id: firaSansRegular; source: "qrc:/fonts/FiraSans-Regular.ttf"; }
|
||||
property real size: 32
|
||||
font.pixelSize: size
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.family: firaSansRegular.name
|
||||
font.family: "Fira Sans"
|
||||
}
|
||||
|
|
|
@ -14,10 +14,9 @@ import QtQuick.Controls.Styles 1.4
|
|||
|
||||
Text {
|
||||
id: root
|
||||
FontLoader { id: firaSansSemiBold; source: "qrc:/fonts/FiraSans-SemiBold.ttf"; }
|
||||
property real size: 32
|
||||
font.pixelSize: size
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.family: firaSansSemiBold.name
|
||||
font.family: "Fira Sans SemiBold"
|
||||
}
|
||||
|
|
|
@ -12,12 +12,11 @@ import QtQuick 2.5
|
|||
|
||||
Text {
|
||||
id: root
|
||||
FontLoader { id: hiFiGlyphs; source: "qrc:/fonts/hifi-glyphs.ttf"; }
|
||||
property int size: 32
|
||||
font.pixelSize: size
|
||||
width: size
|
||||
height: size
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.family: hiFiGlyphs.name
|
||||
font.family: "hifi-glyphs"
|
||||
}
|
||||
|
|
|
@ -14,11 +14,10 @@ import QtQuick.Controls.Styles 1.4
|
|||
|
||||
Text {
|
||||
id: root
|
||||
FontLoader { id: ralewayBold; source: "qrc:/fonts/Raleway-Bold.ttf"; }
|
||||
property real size: 32
|
||||
font.pixelSize: size
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.family: ralewayBold.name
|
||||
font.bold: true // Font seems to need this in order to display bold.
|
||||
font.family: "Raleway"
|
||||
font.bold: true
|
||||
}
|
||||
|
|
|
@ -14,10 +14,9 @@ import QtQuick.Controls.Styles 1.4
|
|||
|
||||
Text {
|
||||
id: root
|
||||
FontLoader { id: ralewayLight; source: "qrc:/fonts/Raleway-Light.ttf"; }
|
||||
property real size: 32
|
||||
font.pixelSize: size
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.family: ralewayLight.name
|
||||
font.family: "Raleway Light"
|
||||
}
|
||||
|
|
|
@ -14,10 +14,9 @@ import QtQuick.Controls.Styles 1.4
|
|||
|
||||
Text {
|
||||
id: root
|
||||
FontLoader { id: ralewayRegular; source: "qrc:/fonts/Raleway-Regular.ttf"; }
|
||||
property real size: 32
|
||||
font.pixelSize: size
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.family: ralewayRegular.name
|
||||
font.family: "Raleway"
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@ import QtQuick.Controls.Styles 1.4
|
|||
|
||||
Text {
|
||||
id: root
|
||||
FontLoader { id: ralewaySemiBold; source: "qrc:/fonts/Raleway-SemiBold.ttf"; }
|
||||
property real size: 32
|
||||
font.pixelSize: size
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.family: ralewaySemiBold.name
|
||||
font.family: "Raleway"
|
||||
font.weight: Font.DemiBold
|
||||
}
|
||||
|
|
|
@ -891,7 +891,7 @@ Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context);
|
|||
|
||||
Setting::Handle<int> sessionRunTime{ "sessionRunTime", 0 };
|
||||
|
||||
const float DEFAULT_HMD_TABLET_SCALE_PERCENT = 100.0f;
|
||||
const float DEFAULT_HMD_TABLET_SCALE_PERCENT = 70.0f;
|
||||
const float DEFAULT_DESKTOP_TABLET_SCALE_PERCENT = 75.0f;
|
||||
const bool DEFAULT_DESKTOP_TABLET_BECOMES_TOOLBAR = true;
|
||||
const bool DEFAULT_HMD_TABLET_BECOMES_TOOLBAR = false;
|
||||
|
@ -981,6 +981,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
qInstallMessageHandler(messageHandler);
|
||||
|
||||
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");
|
||||
|
||||
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.");
|
||||
|
||||
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);
|
||||
|
||||
QObject::connect(request, &GetMappingRequest::finished, this, [=](GetMappingRequest* request) mutable {
|
||||
const int MAX_COPY_COUNT = 100; // Limit number of duplicate assets; recursion guard.
|
||||
auto result = request->getError();
|
||||
if (result == GetMappingRequest::NotFound) {
|
||||
addAssetToWorldUpload(filePath, mapping);
|
||||
addAssetToWorldUpload(filePath, mapping, isZip, isBlocks);
|
||||
} else if (result != GetMappingRequest::NoError) {
|
||||
QString errorInfo = "Could not map asset name: "
|
||||
+ mapping.left(mapping.length() - QString::number(copy).length() - 1);
|
||||
|
@ -6658,7 +6667,7 @@ void Application::addAssetToWorldWithNewMapping(QString filePath, QString mappin
|
|||
}
|
||||
copy++;
|
||||
mapping = mapping.insert(mapping.lastIndexOf("."), "-" + QString::number(copy));
|
||||
addAssetToWorldWithNewMapping(filePath, mapping, copy);
|
||||
addAssetToWorldWithNewMapping(filePath, mapping, copy, isZip, isBlocks);
|
||||
} else {
|
||||
QString errorInfo = "Too many copies of asset name: "
|
||||
+ mapping.left(mapping.length() - QString::number(copy).length() - 1);
|
||||
|
@ -6671,7 +6680,7 @@ void Application::addAssetToWorldWithNewMapping(QString filePath, QString mappin
|
|||
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;
|
||||
auto upload = DependencyManager::get<AssetClient>()->createUpload(filePath);
|
||||
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;
|
||||
addAssetToWorldError(filenameFromPath(filePath), errorInfo);
|
||||
} else {
|
||||
addAssetToWorldSetMapping(filePath, mapping, hash);
|
||||
addAssetToWorldSetMapping(filePath, mapping, hash, isZip, isBlocks);
|
||||
}
|
||||
|
||||
// Remove temporary directory created by Clara.io market place download.
|
||||
|
@ -6697,7 +6706,7 @@ void Application::addAssetToWorldUpload(QString filePath, QString mapping) {
|
|||
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);
|
||||
connect(request, &SetMappingRequest::finished, this, [=](SetMappingRequest* request) mutable {
|
||||
if (request->getError() != SetMappingRequest::NoError) {
|
||||
|
@ -6705,9 +6714,10 @@ void Application::addAssetToWorldSetMapping(QString filePath, QString mapping, Q
|
|||
qWarning(interfaceapp) << "Error downloading model: " + errorInfo;
|
||||
addAssetToWorldError(filenameFromPath(filePath), errorInfo);
|
||||
} else {
|
||||
// to prevent files that aren't models from being loaded into world automatically
|
||||
if (filePath.toLower().endsWith(OBJ_EXTENSION) || filePath.toLower().endsWith(FBX_EXTENSION) ||
|
||||
filePath.toLower().endsWith(JPG_EXTENSION) || filePath.toLower().endsWith(PNG_EXTENSION)) {
|
||||
// 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)) ||
|
||||
((filePath.toLower().endsWith(JPG_EXTENSION) || filePath.toLower().endsWith(PNG_EXTENSION)) &&
|
||||
((!isBlocks) && (!isZip)))) {
|
||||
addAssetToWorldAddEntity(filePath, mapping);
|
||||
} else {
|
||||
qCDebug(interfaceapp) << "Zipped contents are not supported entity files";
|
||||
|
|
|
@ -321,11 +321,11 @@ public slots:
|
|||
// FIXME: Move addAssetToWorld* methods to own class?
|
||||
void addAssetToWorldFromURL(QString url);
|
||||
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 addAssetToWorldWithNewMapping(QString filePath, QString mapping, int copy);
|
||||
void addAssetToWorldUpload(QString filePath, QString mapping);
|
||||
void addAssetToWorldSetMapping(QString filePath, QString mapping, QString hash);
|
||||
void addAssetToWorldWithNewMapping(QString filePath, QString mapping, int copy, bool isZip = false, bool isBlocks = false);
|
||||
void addAssetToWorldUpload(QString filePath, QString mapping, bool isZip = false, bool isBlocks = false);
|
||||
void addAssetToWorldSetMapping(QString filePath, QString mapping, QString hash, bool isZip = false, bool isBlocks = false);
|
||||
void addAssetToWorldAddEntity(QString filePath, QString mapping);
|
||||
|
||||
void handleUnzip(QString sourceFile, QStringList destinationFile, bool autoAdd, bool isZip, bool isBlocks);
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "ui/StandAloneJSConsole.h"
|
||||
#include "InterfaceLogging.h"
|
||||
#include "LocationBookmarks.h"
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
#include "SpeechRecognizer.h"
|
||||
|
@ -360,11 +361,16 @@ Menu::Menu() {
|
|||
// Developer menu ----------------------------------
|
||||
MenuWrapper* developerMenu = addMenu("Developer", "Developer");
|
||||
|
||||
// Developer > Graphics...
|
||||
action = addActionToQMenuAndActionHash(developerMenu, "Graphics...");
|
||||
connect(action, &QAction::triggered, [] {
|
||||
qApp->showDialog(QString("hifi/dialogs/GraphicsPreferencesDialog.qml"),
|
||||
QString("hifi/tablet/TabletGraphicsPreferences.qml"), "GraphicsPreferencesDialog");
|
||||
// Developer > Graphics
|
||||
MenuWrapper* graphicsOptionsMenu = developerMenu->addMenu("Render");
|
||||
action = addCheckableActionToQMenuAndActionHash(graphicsOptionsMenu, MenuOption::Shadows, 0, true);
|
||||
connect(action, &QAction::triggered, [action] {
|
||||
DependencyManager::get<DeferredLightingEffect>()->setShadowMapEnabled(action->isChecked());
|
||||
});
|
||||
|
||||
action = addCheckableActionToQMenuAndActionHash(graphicsOptionsMenu, MenuOption::AmbientOcclusion, 0, false);
|
||||
connect(action, &QAction::triggered, [action] {
|
||||
DependencyManager::get<DeferredLightingEffect>()->setAmbientOcclusionEnabled(action->isChecked());
|
||||
});
|
||||
|
||||
// Developer > UI >>>
|
||||
|
|
|
@ -204,6 +204,8 @@ namespace MenuOption {
|
|||
const QString WorldAxes = "World Axes";
|
||||
const QString DesktopTabletToToolbar = "Desktop Tablet Becomes Toolbar";
|
||||
const QString HMDTabletToToolbar = "HMD Tablet Becomes Toolbar";
|
||||
const QString Shadows = "Shadows";
|
||||
const QString AmbientOcclusion = "AmbientOcclusion";
|
||||
}
|
||||
|
||||
#endif // hifi_Menu_h
|
||||
|
|
|
@ -1115,6 +1115,7 @@ void MyAvatar::setEnableDebugDrawIKChains(bool isEnabled) {
|
|||
|
||||
void MyAvatar::setEnableMeshVisible(bool isEnabled) {
|
||||
_skeletonModel->setVisibleInScene(isEnabled, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE, true);
|
||||
_skeletonModel->setCanCastShadow(isEnabled, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE, true);
|
||||
}
|
||||
|
||||
void MyAvatar::setEnableInverseKinematics(bool isEnabled) {
|
||||
|
@ -1467,6 +1468,7 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
|||
int skeletonModelChangeCount = _skeletonModelChangeCount;
|
||||
Avatar::setSkeletonModelURL(skeletonModelURL);
|
||||
_skeletonModel->setVisibleInScene(true, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE, true);
|
||||
_skeletonModel->setCanCastShadow(true, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE, true);
|
||||
_headBoneSet.clear();
|
||||
_cauterizationNeedsUpdate = true;
|
||||
|
||||
|
@ -1848,12 +1850,6 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName,
|
|||
Avatar::attach(modelURL, jointName, translation, rotation, scale, isSoft, allowDuplicates, useSaved);
|
||||
}
|
||||
|
||||
void MyAvatar::setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visible) {
|
||||
if (model->isActive() && model->isRenderable()) {
|
||||
model->setVisibleInScene(visible, scene, render::ItemKey::TAG_BITS_NONE, true);
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::initHeadBones() {
|
||||
int neckJointIndex = -1;
|
||||
if (_skeletonModel->isLoaded()) {
|
||||
|
@ -2043,8 +2039,12 @@ void MyAvatar::preDisplaySide(RenderArgs* renderArgs) {
|
|||
_attachmentData[i].jointName.compare("RightEye", Qt::CaseInsensitive) == 0 ||
|
||||
_attachmentData[i].jointName.compare("HeadTop_End", Qt::CaseInsensitive) == 0 ||
|
||||
_attachmentData[i].jointName.compare("Face", Qt::CaseInsensitive) == 0) {
|
||||
|
||||
_attachmentModels[i]->setVisibleInScene(shouldDrawHead, qApp->getMain3DScene(),
|
||||
render::ItemKey::TAG_BITS_NONE, true);
|
||||
|
||||
_attachmentModels[i]->setCanCastShadow(shouldDrawHead, qApp->getMain3DScene(),
|
||||
render::ItemKey::TAG_BITS_NONE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -346,7 +346,7 @@ public:
|
|||
* restoreRoleAnimation() is used to restore a specified animation role's default animation clip. If you have not specified an override animation
|
||||
* for the specified role, this function will have no effect.
|
||||
* @function MyAvatar.restoreRoleAnimation
|
||||
* @param rule {string} The animation role clip to restore
|
||||
* @param role {string} The animation role clip to restore
|
||||
*/
|
||||
Q_INVOKABLE void restoreRoleAnimation(const QString& role);
|
||||
|
||||
|
@ -681,8 +681,6 @@ private:
|
|||
// These are made private for MyAvatar so that you will use the "use" methods instead
|
||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
|
||||
|
||||
void setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visiblity);
|
||||
|
||||
virtual void updatePalms() override {}
|
||||
void lateUpdatePalms();
|
||||
|
||||
|
|
|
@ -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) {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
requestParams["public_keys"] = QJsonArray::fromStringList(wallet->listPublicKeys());
|
||||
|
||||
send(endpoint, success, fail, QNetworkAccessManager::PostOperation, AccountManagerAuth::Required, requestParams);
|
||||
QStringList cachedPublicKeys = wallet->listPublicKeys();
|
||||
if (!cachedPublicKeys.isEmpty()) {
|
||||
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) {
|
||||
|
@ -296,14 +300,18 @@ void Ledger::updateLocation(const QString& asset_id, const QString location, con
|
|||
emit walletScriptingInterface->walletNotSetup();
|
||||
qDebug(commerce) << "User attempted to update the location of a certificate, but their wallet wasn't ready. Status:" << walletStatus;
|
||||
} else {
|
||||
QStringList keys = wallet->listPublicKeys();
|
||||
QString key = keys[0];
|
||||
QJsonObject transaction;
|
||||
transaction["certificate_id"] = asset_id;
|
||||
transaction["place_name"] = location;
|
||||
QJsonDocument transactionDoc{ transaction };
|
||||
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
|
||||
signedSend("transaction", transactionString, key, "location", "updateLocationSuccess", "updateLocationFailure", controlledFailure);
|
||||
QStringList cachedPublicKeys = wallet->listPublicKeys();
|
||||
if (!cachedPublicKeys.isEmpty()) {
|
||||
QString key = cachedPublicKeys[0];
|
||||
QJsonObject transaction;
|
||||
transaction["certificate_id"] = asset_id;
|
||||
transaction["place_name"] = location;
|
||||
QJsonDocument transactionDoc{ transaction };
|
||||
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>();
|
||||
QString endpoint = "already_owned";
|
||||
QJsonObject request;
|
||||
request["public_keys"] = QJsonArray::fromStringList(wallet->listPublicKeys());
|
||||
request["marketplace_item_id"] = marketplaceId;
|
||||
send(endpoint, "alreadyOwnedSuccess", "alreadyOwnedFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, request);
|
||||
QStringList cachedPublicKeys = wallet->listPublicKeys();
|
||||
if (!cachedPublicKeys.isEmpty()) {
|
||||
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();
|
||||
}
|
||||
|
||||
void QmlCommerce::clearWallet() {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->clear();
|
||||
}
|
||||
|
||||
void QmlCommerce::setPassphrase(const QString& passphrase) {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->setPassphrase(passphrase);
|
||||
|
|
|
@ -67,6 +67,7 @@ protected:
|
|||
Q_INVOKABLE void setPassphrase(const QString& passphrase);
|
||||
Q_INVOKABLE void changePassphrase(const QString& oldPassphrase, const QString& newPassphrase);
|
||||
Q_INVOKABLE void setSoftReset();
|
||||
Q_INVOKABLE void clearWallet();
|
||||
|
||||
Q_INVOKABLE void buy(const QString& assetId, int cost, const bool controlledFailure = false);
|
||||
Q_INVOKABLE void balance();
|
||||
|
|
|
@ -343,19 +343,23 @@ Wallet::Wallet() {
|
|||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() {
|
||||
getWalletStatus();
|
||||
_publicKeys.clear();
|
||||
|
||||
if (_securityImage) {
|
||||
delete _securityImage;
|
||||
}
|
||||
_securityImage = nullptr;
|
||||
|
||||
// tell the provider we got nothing
|
||||
updateImageProvider();
|
||||
_passphrase->clear();
|
||||
clear();
|
||||
});
|
||||
}
|
||||
|
||||
void Wallet::clear() {
|
||||
_publicKeys.clear();
|
||||
|
||||
if (_securityImage) {
|
||||
delete _securityImage;
|
||||
}
|
||||
_securityImage = nullptr;
|
||||
|
||||
// tell the provider we got nothing
|
||||
updateImageProvider();
|
||||
_passphrase->clear();
|
||||
}
|
||||
|
||||
Wallet::~Wallet() {
|
||||
if (_securityImage) {
|
||||
delete _securityImage;
|
||||
|
|
|
@ -49,8 +49,9 @@ public:
|
|||
bool getPassphraseIsCached() { return !(_passphrase->isEmpty()); }
|
||||
bool walletIsAuthenticatedWithPassphrase();
|
||||
bool changePassphrase(const QString& newPassphrase);
|
||||
void setSoftReset() { _isOverridingServer = true; }
|
||||
void setSoftReset() { _isOverridingServer = true; }
|
||||
bool wasSoftReset() { bool was = _isOverridingServer; _isOverridingServer = false; return was; }
|
||||
void clear();
|
||||
|
||||
void getWalletStatus();
|
||||
enum WalletStatus {
|
||||
|
|
|
@ -174,4 +174,12 @@ void PickScriptingInterface::registerMetaTypes(QScriptEngine* engine) {
|
|||
engine->globalObject().setProperty("PickType", pickTypes);
|
||||
|
||||
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_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:
|
||||
static constexpr unsigned int PICK_NOTHING() { return 0; }
|
||||
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; }
|
||||
};
|
||||
|
||||
#endif // hifi_PickScriptingInterface_h
|
||||
#endif // hifi_PickScriptingInterface_h
|
||||
|
|
|
@ -259,7 +259,6 @@ void WindowScriptingInterface::browseAsync(const QString& title, const QString&
|
|||
setPreviousBrowseLocation(QFileInfo(result).absolutePath());
|
||||
}
|
||||
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
|
||||
* {@link Window.browseChanged|browseChanged} signal is emitted when a file is chosen; no signal is emitted if the user
|
||||
* cancels the dialog.
|
||||
* @deprecated A deprecated {@link Window.openFileChanged|openFileChanged} signal is also emitted when a file is chosen.
|
||||
* @function Window.browseAsync
|
||||
* @param {string} title="" - The title to display at the top of the dialog.
|
||||
* @param {string} directory="" - The initial directory to start browsing at.
|
||||
|
@ -660,15 +659,6 @@ signals:
|
|||
*/
|
||||
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
|
||||
* Triggered when the user OKs a {@link Window.promptAsync|promptAsync} dialog.
|
||||
* @function Window.promptTextChanged
|
||||
|
|
|
@ -479,7 +479,7 @@ void Stats::updateStats(bool force) {
|
|||
float dt = (float)itr.value().getMovingAverage() / (float)USECS_PER_MSEC;
|
||||
_gameUpdateStats = QString("/idle/update = %1 ms").arg(dt);
|
||||
|
||||
QVector<QString> categories = { "devices", "physics", "otherAvatars", "MyAvatar", "pickManager", "postUpdateLambdas", "misc" };
|
||||
QVector<QString> categories = { "devices", "physics", "otherAvatars", "MyAvatar", "misc" };
|
||||
for (int32_t j = 0; j < categories.size(); ++j) {
|
||||
QString recordKey = "/idle/update/" + categories[j];
|
||||
itr = allRecords.find(recordKey);
|
||||
|
@ -499,39 +499,10 @@ void Stats::updateStats(bool force) {
|
|||
_gameUpdateStats = "";
|
||||
emit gameUpdateStatsChanged();
|
||||
}
|
||||
|
||||
itr = allRecords.find("/paintGL/display/EngineRun/Engine");
|
||||
std::priority_queue<SortableStat> renderEngineStats;
|
||||
if (itr != allRecords.end()) {
|
||||
float dt = (float)itr.value().getMovingAverage() / (float)USECS_PER_MSEC;
|
||||
_renderEngineStats = QString("/render = %1 ms").arg(dt);
|
||||
|
||||
QVector<QString> categories = { "RenderMainView", "SecondaryCameraJob", "UpdateScene"};
|
||||
for (int32_t j = 0; j < categories.size(); ++j) {
|
||||
QString recordKey = "/paintGL/display/EngineRun/Engine/" + categories[j];
|
||||
itr = allRecords.find(recordKey);
|
||||
if (itr != allRecords.end()) {
|
||||
float dt = (float)itr.value().getMovingAverage() / (float)USECS_PER_MSEC;
|
||||
QString message = QString("\n %1 = %2").arg(categories[j]).arg(dt);
|
||||
renderEngineStats.push(SortableStat(message, dt));
|
||||
}
|
||||
}
|
||||
while (!renderEngineStats.empty()) {
|
||||
SortableStat stat = renderEngineStats.top();
|
||||
_renderEngineStats += stat.message;
|
||||
renderEngineStats.pop();
|
||||
}
|
||||
emit renderEngineStatsChanged();
|
||||
} else if (_renderEngineStats != "") {
|
||||
_renderEngineStats = "";
|
||||
emit renderEngineStatsChanged();
|
||||
}
|
||||
} else if (_showGameUpdateStats) {
|
||||
_showGameUpdateStats = false;
|
||||
_gameUpdateStats = "";
|
||||
_renderEngineStats = "";
|
||||
emit gameUpdateStatsChanged();
|
||||
emit renderEngineStatsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,6 @@ class Stats : public QQuickItem {
|
|||
STATS_PROPERTY(QString, lodStatus, QString())
|
||||
STATS_PROPERTY(QString, timingStats, QString())
|
||||
STATS_PROPERTY(QString, gameUpdateStats, QString())
|
||||
STATS_PROPERTY(QString, renderEngineStats, QString())
|
||||
STATS_PROPERTY(int, serverElements, 0)
|
||||
STATS_PROPERTY(int, serverInternal, 0)
|
||||
STATS_PROPERTY(int, serverLeaves, 0)
|
||||
|
@ -240,7 +239,6 @@ signals:
|
|||
void localLeavesChanged();
|
||||
void timingStatsChanged();
|
||||
void gameUpdateStatsChanged();
|
||||
void renderEngineStatsChanged();
|
||||
void glContextSwapchainMemoryChanged();
|
||||
void qmlTextureMemoryChanged();
|
||||
void texturePendingTransfersChanged();
|
||||
|
|
|
@ -681,5 +681,9 @@ scriptable::ScriptableModelBase ModelOverlay::getScriptableModel() {
|
|||
}
|
||||
auto result = _model->getScriptableModel();
|
||||
result.objectID = getID();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
||||
result.appendMaterials(_materials);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1397,9 +1397,11 @@ void AudioClient::setNoiseReduction(bool enable) {
|
|||
}
|
||||
|
||||
|
||||
void AudioClient::setIsStereoInput(bool isStereoInput) {
|
||||
if (isStereoInput != _isStereoInput) {
|
||||
bool AudioClient::setIsStereoInput(bool isStereoInput) {
|
||||
bool stereoInputChanged = false;
|
||||
if (isStereoInput != _isStereoInput && _inputDeviceInfo.supportedChannelCounts().contains(2)) {
|
||||
_isStereoInput = isStereoInput;
|
||||
stereoInputChanged = true;
|
||||
|
||||
if (_isStereoInput) {
|
||||
_desiredInputFormat.setChannelCount(2);
|
||||
|
@ -1419,6 +1421,8 @@ void AudioClient::setIsStereoInput(bool isStereoInput) {
|
|||
// restart the input device
|
||||
switchInputToAudioDevice(_inputDeviceInfo);
|
||||
}
|
||||
|
||||
return stereoInputChanged;
|
||||
}
|
||||
|
||||
bool AudioClient::outputLocalInjector(const AudioInjectorPointer& injector) {
|
||||
|
|
|
@ -192,7 +192,8 @@ public slots:
|
|||
void toggleMute();
|
||||
bool isMuted() { return _muted; }
|
||||
|
||||
virtual void setIsStereoInput(bool stereo) override;
|
||||
virtual bool setIsStereoInput(bool stereo) override;
|
||||
virtual bool isStereoInput() override { return _isStereoInput; }
|
||||
|
||||
void setNoiseReduction(bool isNoiseGateEnabled);
|
||||
bool isNoiseReductionEnabled() const { return _isNoiseGateEnabled; }
|
||||
|
|
|
@ -28,7 +28,7 @@ class AbstractAudioInterface : public QObject {
|
|||
Q_OBJECT
|
||||
public:
|
||||
AbstractAudioInterface(QObject* parent = 0) : QObject(parent) {};
|
||||
|
||||
|
||||
static void emitAudioPacket(const void* audioData, size_t bytes, quint16& sequenceNumber, bool isStereo,
|
||||
const Transform& transform, glm::vec3 avatarBoundingBoxCorner, glm::vec3 avatarBoundingBoxScale,
|
||||
PacketType packetType, QString codecName = QString(""));
|
||||
|
@ -40,8 +40,10 @@ public:
|
|||
|
||||
public slots:
|
||||
virtual bool shouldLoopbackInjectors() { return false; }
|
||||
|
||||
virtual void setIsStereoInput(bool stereo) = 0;
|
||||
|
||||
virtual bool setIsStereoInput(bool stereo) = 0;
|
||||
|
||||
virtual bool isStereoInput() = 0;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(AbstractAudioInterface*)
|
||||
|
|
|
@ -1801,5 +1801,9 @@ scriptable::ScriptableModelBase Avatar::getScriptableModel() {
|
|||
}
|
||||
auto result = _skeletonModel->getScriptableModel();
|
||||
result.objectID = getSessionUUID().isNull() ? AVATAR_SELF_ID : getSessionUUID();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
||||
result.appendMaterials(_materials);
|
||||
}
|
||||
return result;
|
||||
}
|
|
@ -164,7 +164,12 @@ ItemKey EntityRenderer::getKey() {
|
|||
return ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1);
|
||||
}
|
||||
|
||||
return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1);
|
||||
// This allows shapes to cast shadows
|
||||
if (_canCastShadow) {
|
||||
return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1).withShadowCaster();
|
||||
} else {
|
||||
return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t EntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) {
|
||||
|
@ -377,6 +382,7 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa
|
|||
|
||||
_moving = entity->isMovingRelativeToParent();
|
||||
_visible = entity->getVisible();
|
||||
_canCastShadow = entity->getCanCastShadow();
|
||||
_cauterized = entity->getCauterized();
|
||||
_needsRenderUpdate = false;
|
||||
});
|
||||
|
|
|
@ -129,6 +129,7 @@ protected:
|
|||
bool _isFading{ _entitiesShouldFadeFunction() };
|
||||
bool _prevIsTransparent { false };
|
||||
bool _visible { false };
|
||||
bool _canCastShadow { false };
|
||||
bool _cauterized { false };
|
||||
bool _moving { false };
|
||||
bool _needsRenderUpdate { false };
|
||||
|
|
|
@ -286,7 +286,7 @@ bool RenderableModelEntityItem::supportsDetailedRayIntersection() const {
|
|||
}
|
||||
|
||||
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 {
|
||||
auto model = getModel();
|
||||
if (!model) {
|
||||
|
@ -974,6 +974,10 @@ scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScript
|
|||
|
||||
auto result = _model->getScriptableModel();
|
||||
result.objectID = getEntity()->getID();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
||||
result.appendMaterials(_materials);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1395,6 +1399,10 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
}
|
||||
// TODO? early exit here when not visible?
|
||||
|
||||
if (model->canCastShadow() != _canCastShadow) {
|
||||
model->setCanCastShadow(_canCastShadow, scene, viewTaskBits, false);
|
||||
}
|
||||
|
||||
if (_needsCollisionGeometryUpdate) {
|
||||
setCollisionMeshKey(entity->getCollisionMeshKey());
|
||||
_needsCollisionGeometryUpdate = false;
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
|
||||
virtual bool supportsDetailedRayIntersection() const override;
|
||||
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,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||
|
||||
|
|
|
@ -565,7 +565,7 @@ public:
|
|||
#endif
|
||||
|
||||
bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElementPointer& element,
|
||||
OctreeElementPointer& element,
|
||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const
|
||||
{
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
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,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||
|
||||
|
|
|
@ -169,8 +169,12 @@ scriptable::ScriptableModelBase ShapeEntityRenderer::getScriptableModel() {
|
|||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto geometryShape = geometryCache->getShapeForEntityShape(_shape);
|
||||
glm::vec3 vertexColor;
|
||||
if (_materials["0"].top().material) {
|
||||
vertexColor = _materials["0"].top().material->getAlbedo();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
||||
result.appendMaterials(_materials);
|
||||
if (_materials["0"].top().material) {
|
||||
vertexColor = _materials["0"].top().material->getAlbedo();
|
||||
}
|
||||
}
|
||||
if (auto mesh = geometryCache->meshFromShape(geometryShape, vertexColor)) {
|
||||
result.objectID = getEntity()->getID();
|
||||
|
|
|
@ -330,6 +330,7 @@ void ZoneEntityRenderer::updateKeySunFromEntity(const TypedEntityPointer& entity
|
|||
sunLight->setColor(ColorUtils::toVec3(_keyLightProperties.getColor()));
|
||||
sunLight->setIntensity(_keyLightProperties.getIntensity());
|
||||
sunLight->setDirection(entity->getTransform().getRotation() * _keyLightProperties.getDirection());
|
||||
sunLight->setCastShadows(_keyLightProperties.getCastShadows());
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::updateAmbientLightFromEntity(const TypedEntityPointer& entity) {
|
||||
|
|
|
@ -91,6 +91,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
|
|||
requestedProperties += PROP_REGISTRATION_POINT;
|
||||
requestedProperties += PROP_ANGULAR_DAMPING;
|
||||
requestedProperties += PROP_VISIBLE;
|
||||
requestedProperties += PROP_CAN_CAST_SHADOW;
|
||||
requestedProperties += PROP_COLLISIONLESS;
|
||||
requestedProperties += PROP_COLLISION_MASK;
|
||||
requestedProperties += PROP_DYNAMIC;
|
||||
|
@ -249,6 +250,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
|||
APPEND_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, getRegistrationPoint());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, getAngularDamping());
|
||||
APPEND_ENTITY_PROPERTY(PROP_VISIBLE, getVisible());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, getCanCastShadow());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLLISIONLESS, getCollisionless());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLLISION_MASK, getCollisionMask());
|
||||
APPEND_ENTITY_PROPERTY(PROP_DYNAMIC, getDynamic());
|
||||
|
@ -799,6 +801,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
|
||||
READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, setAngularDamping);
|
||||
READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, setVisible);
|
||||
READ_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow);
|
||||
READ_ENTITY_PROPERTY(PROP_COLLISIONLESS, bool, setCollisionless);
|
||||
READ_ENTITY_PROPERTY(PROP_COLLISION_MASK, uint8_t, setCollisionMask);
|
||||
READ_ENTITY_PROPERTY(PROP_DYNAMIC, bool, setDynamic);
|
||||
|
@ -1234,6 +1237,7 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper
|
|||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(angularDamping, getAngularDamping);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(localRenderAlpha, getLocalRenderAlpha);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(visible, getVisible);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(canCastShadow, getCanCastShadow);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionless, getCollisionless);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionMask, getCollisionMask);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dynamic, getDynamic);
|
||||
|
@ -1346,6 +1350,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionSoundURL, setCollisionSoundURL);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(localRenderAlpha, setLocalRenderAlpha);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(visible, setVisible);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(canCastShadow, setCanCastShadow);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(userData, setUserData);
|
||||
|
||||
// Certifiable Properties
|
||||
|
@ -2723,6 +2728,28 @@ void EntityItem::setVisible(bool value) {
|
|||
}
|
||||
}
|
||||
|
||||
bool EntityItem::getCanCastShadow() const {
|
||||
bool result;
|
||||
withReadLock([&] {
|
||||
result = _canCastShadow;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void EntityItem::setCanCastShadow(bool value) {
|
||||
bool changed = false;
|
||||
withWriteLock([&] {
|
||||
if (_canCastShadow != value) {
|
||||
changed = true;
|
||||
_canCastShadow = value;
|
||||
}
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
emit requestRenderUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
bool EntityItem::isChildOfMyAvatar() const {
|
||||
QUuid ancestorID = findAncestorOfType(NestableType::Avatar);
|
||||
return !ancestorID.isNull() && (ancestorID == Physics::getSessionUUID() || ancestorID == AVATAR_SELF_ID);
|
||||
|
@ -2957,4 +2984,4 @@ std::unordered_map<std::string, graphics::MultiMaterial> EntityItem::getMaterial
|
|||
toReturn = _materials;
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ public:
|
|||
|
||||
virtual bool supportsDetailedRayIntersection() const { return false; }
|
||||
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,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const { return true; }
|
||||
|
||||
|
@ -274,6 +274,10 @@ public:
|
|||
|
||||
bool getVisible() const;
|
||||
void setVisible(bool value);
|
||||
|
||||
bool getCanCastShadow() const;
|
||||
void setCanCastShadow(bool value);
|
||||
|
||||
inline bool isVisible() const { return getVisible(); }
|
||||
inline bool isInvisible() const { return !getVisible(); }
|
||||
|
||||
|
@ -551,6 +555,7 @@ protected:
|
|||
glm::vec3 _registrationPoint { ENTITY_ITEM_DEFAULT_REGISTRATION_POINT };
|
||||
float _angularDamping { ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING };
|
||||
bool _visible { ENTITY_ITEM_DEFAULT_VISIBLE };
|
||||
bool _canCastShadow{ ENTITY_ITEM_DEFAULT_CAN_CAST_SHADOW };
|
||||
bool _collisionless { ENTITY_ITEM_DEFAULT_COLLISIONLESS };
|
||||
uint8_t _collisionMask { ENTITY_COLLISION_MASK_DEFAULT };
|
||||
bool _dynamic { ENTITY_ITEM_DEFAULT_DYNAMIC };
|
||||
|
|
|
@ -316,6 +316,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL);
|
||||
CHECK_PROPERTY_CHANGE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
|
||||
CHECK_PROPERTY_CHANGE(PROP_VISIBLE, visible);
|
||||
CHECK_PROPERTY_CHANGE(PROP_CAN_CAST_SHADOW, canCastShadow);
|
||||
CHECK_PROPERTY_CHANGE(PROP_REGISTRATION_POINT, registrationPoint);
|
||||
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_VELOCITY, angularVelocity);
|
||||
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_DAMPING, angularDamping);
|
||||
|
@ -490,6 +491,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_VELOCITY, angularVelocity);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_DAMPING, angularDamping);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VISIBLE, visible);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CAN_CAST_SHADOW, canCastShadow);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISIONLESS, collisionless);
|
||||
COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_COLLISIONLESS, collisionless, ignoreForCollisions, getCollisionless()); // legacy support
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISION_MASK, collisionMask);
|
||||
|
@ -751,6 +753,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE(angularVelocity, glmVec3, setAngularVelocity);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(angularDamping, float, setAngularDamping);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(visible, bool, setVisible);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(canCastShadow, bool, setCanCastShadow);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(color, xColor, setColor);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(colorSpread, xColor, setColorSpread);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(colorStart, xColor, setColorStart);
|
||||
|
@ -922,6 +925,7 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
COPY_PROPERTY_IF_CHANGED(angularVelocity);
|
||||
COPY_PROPERTY_IF_CHANGED(angularDamping);
|
||||
COPY_PROPERTY_IF_CHANGED(visible);
|
||||
COPY_PROPERTY_IF_CHANGED(canCastShadow);
|
||||
COPY_PROPERTY_IF_CHANGED(color);
|
||||
COPY_PROPERTY_IF_CHANGED(colorSpread);
|
||||
COPY_PROPERTY_IF_CHANGED(colorStart);
|
||||
|
@ -1094,6 +1098,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
|||
|
||||
std::call_once(initMap, [](){
|
||||
ADD_PROPERTY_TO_MAP(PROP_VISIBLE, Visible, visible, bool);
|
||||
ADD_PROPERTY_TO_MAP(PROP_CAN_CAST_SHADOW, CanCastShadow, canCastShadow, bool);
|
||||
ADD_PROPERTY_TO_MAP(PROP_POSITION, Position, position, glm::vec3);
|
||||
ADD_PROPERTY_TO_MAP(PROP_DIMENSIONS, Dimensions, dimensions, glm::vec3);
|
||||
ADD_PROPERTY_TO_MAP(PROP_ROTATION, Rotation, rotation, glm::quat);
|
||||
|
@ -1187,6 +1192,8 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
|||
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor);
|
||||
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float);
|
||||
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_DIRECTION, KeyLightDirection, keyLightDirection, glm::vec3);
|
||||
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_CAST_SHADOW, KeyLightCastShadows, keyLightCastShadows, bool);
|
||||
|
||||
ADD_PROPERTY_TO_MAP(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, glm::vec3);
|
||||
ADD_PROPERTY_TO_MAP(PROP_VOXEL_DATA, VoxelData, voxelData, QByteArray);
|
||||
ADD_PROPERTY_TO_MAP(PROP_VOXEL_SURFACE_STYLE, VoxelSurfaceStyle, voxelSurfaceStyle, uint16_t);
|
||||
|
@ -1412,6 +1419,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy
|
|||
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, properties.getAngularVelocity());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, properties.getAngularDamping());
|
||||
APPEND_ENTITY_PROPERTY(PROP_VISIBLE, properties.getVisible());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, properties.getCanCastShadow());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLLISIONLESS, properties.getCollisionless());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLLISION_MASK, properties.getCollisionMask());
|
||||
APPEND_ENTITY_PROPERTY(PROP_DYNAMIC, properties.getDynamic());
|
||||
|
@ -1784,6 +1792,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_VELOCITY, glm::vec3, setAngularVelocity);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_DAMPING, float, setAngularDamping);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE, bool, setVisible);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISIONLESS, bool, setCollisionless);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_MASK, uint8_t, setCollisionMask);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DYNAMIC, bool, setDynamic);
|
||||
|
@ -2053,6 +2062,7 @@ void EntityItemProperties::markAllChanged() {
|
|||
_angularDampingChanged = true;
|
||||
_nameChanged = true;
|
||||
_visibleChanged = true;
|
||||
_canCastShadowChanged = true;
|
||||
_colorChanged = true;
|
||||
_alphaChanged = true;
|
||||
_modelURLChanged = true;
|
||||
|
@ -2250,6 +2260,9 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
if (visibleChanged()) {
|
||||
out += "visible";
|
||||
}
|
||||
if (canCastShadowChanged()) {
|
||||
out += "canCastShadow";
|
||||
}
|
||||
if (rotationChanged()) {
|
||||
out += "rotation";
|
||||
}
|
||||
|
|
|
@ -117,6 +117,7 @@ public:
|
|||
// bool _fooChanged { false };
|
||||
|
||||
DEFINE_PROPERTY(PROP_VISIBLE, Visible, visible, bool, ENTITY_ITEM_DEFAULT_VISIBLE);
|
||||
DEFINE_PROPERTY(PROP_CAN_CAST_SHADOW, CanCastShadow, canCastShadow, bool, ENTITY_ITEM_DEFAULT_CAN_CAST_SHADOW);
|
||||
DEFINE_PROPERTY_REF_WITH_SETTER(PROP_POSITION, Position, position, glm::vec3, ENTITY_ITEM_ZERO_VEC3);
|
||||
DEFINE_PROPERTY_REF(PROP_DIMENSIONS, Dimensions, dimensions, glm::vec3, ENTITY_ITEM_DEFAULT_DIMENSIONS);
|
||||
DEFINE_PROPERTY_REF(PROP_ROTATION, Rotation, rotation, glm::quat, ENTITY_ITEM_DEFAULT_ROTATION);
|
||||
|
@ -426,6 +427,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
|
|||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Velocity, velocity, "in meters");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Name, name, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Visible, visible, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, CanCastShadow, canCastShadow, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Rotation, rotation, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Density, density, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Gravity, gravity, "");
|
||||
|
|
|
@ -46,6 +46,7 @@ const quint32 ENTITY_ITEM_DEFAULT_STATIC_CERTIFICATE_VERSION = 0;
|
|||
const float ENTITY_ITEM_DEFAULT_ALPHA = 1.0f;
|
||||
const float ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA = 1.0f;
|
||||
const bool ENTITY_ITEM_DEFAULT_VISIBLE = true;
|
||||
const bool ENTITY_ITEM_DEFAULT_CAN_CAST_SHADOW { true };
|
||||
|
||||
const QString ENTITY_ITEM_DEFAULT_SCRIPT = QString("");
|
||||
const quint64 ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP = 0;
|
||||
|
|
|
@ -20,6 +20,7 @@ enum EntityPropertyList {
|
|||
|
||||
// these properties are supported by the EntityItem base class
|
||||
PROP_VISIBLE,
|
||||
PROP_CAN_CAST_SHADOW,
|
||||
PROP_POSITION,
|
||||
PROP_DIMENSIONS,
|
||||
PROP_ROTATION,
|
||||
|
@ -205,6 +206,11 @@ enum EntityPropertyList {
|
|||
|
||||
PROP_HAZE_MODE,
|
||||
|
||||
PROP_KEYLIGHT_COLOR,
|
||||
PROP_KEYLIGHT_INTENSITY,
|
||||
PROP_KEYLIGHT_DIRECTION,
|
||||
PROP_KEYLIGHT_CAST_SHADOW,
|
||||
|
||||
PROP_HAZE_RANGE,
|
||||
PROP_HAZE_COLOR,
|
||||
PROP_HAZE_GLARE_COLOR,
|
||||
|
@ -254,10 +260,6 @@ enum EntityPropertyList {
|
|||
// Aliases/Piggyback properties for Zones. These properties intentionally reuse the enum values for
|
||||
// other properties which will never overlap with each other. We do this so that we don't have to expand
|
||||
// the size of the properties bitflags mask
|
||||
PROP_KEYLIGHT_COLOR = PROP_COLOR,
|
||||
PROP_KEYLIGHT_INTENSITY = PROP_INTENSITY,
|
||||
PROP_KEYLIGHT_DIRECTION = PROP_EXPONENT,
|
||||
|
||||
PROP_SKYBOX_COLOR = PROP_ANIMATION_URL,
|
||||
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
|
||||
|
||||
|
|
|
@ -594,17 +594,15 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con
|
|||
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
|
||||
QVariantMap& extraInfo, bool precisionPicking) {
|
||||
|
||||
keepSearching = true; // assume that we will continue searching after this.
|
||||
|
||||
EntityItemID result;
|
||||
float distanceToElementCube = std::numeric_limits<float>::max();
|
||||
float distanceToElementDetails = distance;
|
||||
BoxFace localFace;
|
||||
glm::vec3 localSurfaceNormal;
|
||||
QVariantMap localExtraInfo;
|
||||
|
||||
// if the ray doesn't intersect with our cube, we can stop searching!
|
||||
if (!_cube.findRayIntersection(origin, direction, distanceToElementCube, localFace, localSurfaceNormal)) {
|
||||
// if the ray doesn't intersect with our cube OR the distance to element is less than current best distance
|
||||
// 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
|
||||
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
|
||||
// for any details inside the cube to be closer so we don't need to consider them.
|
||||
if (_cube.contains(origin) || distanceToElementCube < distance) {
|
||||
|
||||
EntityItemID entityID = findDetailedRayIntersection(origin, direction, keepSearching, element, distanceToElementDetails,
|
||||
face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly,
|
||||
localExtraInfo, precisionPicking, distanceToElementCube);
|
||||
if (!entityID.isNull()) {
|
||||
if (distanceToElementDetails < distance) {
|
||||
distance = distanceToElementDetails;
|
||||
face = localFace;
|
||||
surfaceNormal = localSurfaceNormal;
|
||||
extraInfo = localExtraInfo;
|
||||
result = entityID;
|
||||
}
|
||||
}
|
||||
QVariantMap localExtraInfo;
|
||||
float distanceToElementDetails = distance;
|
||||
EntityItemID entityID = findDetailedRayIntersection(origin, direction, element, distanceToElementDetails,
|
||||
face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly,
|
||||
localExtraInfo, precisionPicking);
|
||||
if (!entityID.isNull() && distanceToElementDetails < distance) {
|
||||
distance = distanceToElementDetails;
|
||||
face = localFace;
|
||||
surfaceNormal = localSurfaceNormal;
|
||||
extraInfo = localExtraInfo;
|
||||
result = entityID;
|
||||
}
|
||||
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,
|
||||
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...
|
||||
int entityNumber = 0;
|
||||
EntityItemID entityID;
|
||||
forEachEntity([&](EntityItemPointer entity) {
|
||||
if ( (visibleOnly && !entity->isVisible()) || (collidableOnly && (entity->getCollisionless() || entity->getShapeType() == SHAPE_TYPE_NONE))
|
||||
|| (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID()))
|
||||
|| (entityIDsToDiscard.size() > 0 && entityIDsToDiscard.contains(entity->getID())) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// use simple line-sphere for broadphase check
|
||||
// (this is faster and more likely to cull results than the filter check below so we do it first)
|
||||
bool success;
|
||||
AABox entityBox = entity->getAABox(success);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
if (!entityBox.rayHitsBoundingSphere(origin, direction)) {
|
||||
return;
|
||||
}
|
||||
|
||||
float localDistance;
|
||||
BoxFace localFace;
|
||||
glm::vec3 localSurfaceNormal;
|
||||
QVariantMap localExtraInfo;
|
||||
|
||||
// if the ray doesn't intersect with our cube, we can stop searching!
|
||||
if (!entityBox.findRayIntersection(origin, direction, localDistance, localFace, localSurfaceNormal)) {
|
||||
// check RayPick filter settings
|
||||
if ((visibleOnly && !entity->isVisible())
|
||||
|| (collidableOnly && (entity->getCollisionless() || entity->getShapeType() == SHAPE_TYPE_NONE))
|
||||
|| (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID()))
|
||||
|| (entityIDsToDiscard.size() > 0 && entityIDsToDiscard.contains(entity->getID())) ) {
|
||||
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
|
||||
// and testing intersection there.
|
||||
float localDistance;
|
||||
BoxFace localFace;
|
||||
glm::vec3 localSurfaceNormal;
|
||||
if (entityFrameBox.findRayIntersection(entityFrameOrigin, entityFrameDirection, localDistance,
|
||||
localFace, localSurfaceNormal)) {
|
||||
if (entityFrameBox.contains(entityFrameOrigin) || localDistance < distance) {
|
||||
// now ask the entity if we actually intersect
|
||||
if (entity->supportsDetailedRayIntersection()) {
|
||||
if (entity->findDetailedRayIntersection(origin, direction, keepSearching, element, localDistance,
|
||||
localFace, localSurfaceNormal, localExtraInfo, precisionPicking)) {
|
||||
|
||||
QVariantMap localExtraInfo;
|
||||
if (entity->findDetailedRayIntersection(origin, direction, element, localDistance,
|
||||
localFace, localSurfaceNormal, localExtraInfo, precisionPicking)) {
|
||||
if (localDistance < distance) {
|
||||
distance = localDistance;
|
||||
face = localFace;
|
||||
|
|
|
@ -152,10 +152,10 @@ public:
|
|||
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
|
||||
QVariantMap& extraInfo, bool precisionPicking = false);
|
||||
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,
|
||||
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,
|
||||
glm::vec3& penetration, void** penetratedObject) const override;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ const xColor KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR = { 255, 255, 255 };
|
|||
const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY = 1.0f;
|
||||
const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY = 0.5f;
|
||||
const glm::vec3 KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION = { 0.0f, -1.0f, 0.0f };
|
||||
const bool KeyLightPropertyGroup::DEFAULT_KEYLIGHT_CAST_SHADOWS { false };
|
||||
|
||||
void KeyLightPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties,
|
||||
QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||
|
@ -28,23 +29,27 @@ void KeyLightPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desired
|
|||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_COLOR, KeyLight, keyLight, Color, color);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_INTENSITY, KeyLight, keyLight, Intensity, intensity);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_DIRECTION, KeyLight, keyLight, Direction, direction);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_CAST_SHADOW, KeyLight, keyLight, CastShadows, castShadows);
|
||||
}
|
||||
|
||||
void KeyLightPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, color, xColor, setColor);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, intensity, float, setIntensity);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, direction, glmVec3, setDirection);
|
||||
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, castShadows, bool, setCastShadows);
|
||||
|
||||
// legacy property support
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightColor, xColor, setColor, getColor);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightIntensity, float, setIntensity, getIntensity);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightDirection, glmVec3, setDirection, getDirection);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightCastShadows, bool, setCastShadows, getCastShadows);
|
||||
}
|
||||
|
||||
void KeyLightPropertyGroup::merge(const KeyLightPropertyGroup& other) {
|
||||
COPY_PROPERTY_IF_CHANGED(color);
|
||||
COPY_PROPERTY_IF_CHANGED(intensity);
|
||||
COPY_PROPERTY_IF_CHANGED(direction);
|
||||
COPY_PROPERTY_IF_CHANGED(castShadows);
|
||||
}
|
||||
|
||||
void KeyLightPropertyGroup::debugDump() const {
|
||||
|
@ -52,6 +57,7 @@ void KeyLightPropertyGroup::debugDump() const {
|
|||
qCDebug(entities) << " color:" << getColor(); // << "," << getColor()[1] << "," << getColor()[2];
|
||||
qCDebug(entities) << " intensity:" << getIntensity();
|
||||
qCDebug(entities) << " direction:" << getDirection();
|
||||
qCDebug(entities) << " castShadows:" << getCastShadows();
|
||||
}
|
||||
|
||||
void KeyLightPropertyGroup::listChangedProperties(QList<QString>& out) {
|
||||
|
@ -64,6 +70,9 @@ void KeyLightPropertyGroup::listChangedProperties(QList<QString>& out) {
|
|||
if (directionChanged()) {
|
||||
out << "keyLight-direction";
|
||||
}
|
||||
if (castShadowsChanged()) {
|
||||
out << "keyLight-castShadows";
|
||||
}
|
||||
}
|
||||
|
||||
bool KeyLightPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
||||
|
@ -78,12 +87,13 @@ bool KeyLightPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
|||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, getColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, getIntensity());
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, getDirection());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, getCastShadows());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyLightPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt,
|
||||
int& processedBytes) {
|
||||
int& processedBytes) {
|
||||
|
||||
int bytesRead = 0;
|
||||
bool overwriteLocalData = true;
|
||||
|
@ -92,11 +102,13 @@ bool KeyLightPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFl
|
|||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, xColor, setColor);
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, setIntensity);
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setDirection);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, bool, setCastShadows);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_COLOR, Color);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_INTENSITY, Intensity);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_DIRECTION, Direction);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_CAST_SHADOW, CastShadows);
|
||||
|
||||
processedBytes += bytesRead;
|
||||
|
||||
Q_UNUSED(somethingChanged);
|
||||
|
@ -108,6 +120,7 @@ void KeyLightPropertyGroup::markAllChanged() {
|
|||
_colorChanged = true;
|
||||
_intensityChanged = true;
|
||||
_directionChanged = true;
|
||||
_castShadowsChanged = true;
|
||||
}
|
||||
|
||||
EntityPropertyFlags KeyLightPropertyGroup::getChangedProperties() const {
|
||||
|
@ -116,7 +129,8 @@ EntityPropertyFlags KeyLightPropertyGroup::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_COLOR, color);
|
||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_INTENSITY, intensity);
|
||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_DIRECTION, direction);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_CAST_SHADOW, castShadows);
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
||||
|
@ -124,6 +138,7 @@ void KeyLightPropertyGroup::getProperties(EntityItemProperties& properties) cons
|
|||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, Color, getColor);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, Intensity, getIntensity);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, Direction, getDirection);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, CastShadows, getCastShadows);
|
||||
}
|
||||
|
||||
bool KeyLightPropertyGroup::setProperties(const EntityItemProperties& properties) {
|
||||
|
@ -132,6 +147,7 @@ bool KeyLightPropertyGroup::setProperties(const EntityItemProperties& properties
|
|||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, Color, color, setColor);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, Intensity, intensity, setIntensity);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, Direction, direction, setDirection);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, CastShadows, castShadows, setCastShadows);
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
@ -142,6 +158,7 @@ EntityPropertyFlags KeyLightPropertyGroup::getEntityProperties(EncodeBitstreamPa
|
|||
requestedProperties += PROP_KEYLIGHT_COLOR;
|
||||
requestedProperties += PROP_KEYLIGHT_INTENSITY;
|
||||
requestedProperties += PROP_KEYLIGHT_DIRECTION;
|
||||
requestedProperties += PROP_KEYLIGHT_CAST_SHADOW;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
@ -159,6 +176,7 @@ void KeyLightPropertyGroup::appendSubclassData(OctreePacketData* packetData, Enc
|
|||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, getColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, getIntensity());
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, getDirection());
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, getCastShadows());
|
||||
}
|
||||
|
||||
int KeyLightPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
|
@ -172,6 +190,7 @@ int KeyLightPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char*
|
|||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, xColor, setColor);
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, setIntensity);
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setDirection);
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, bool, setCastShadows);
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
|
|
@ -78,10 +78,12 @@ public:
|
|||
static const float DEFAULT_KEYLIGHT_INTENSITY;
|
||||
static const float DEFAULT_KEYLIGHT_AMBIENT_INTENSITY;
|
||||
static const glm::vec3 DEFAULT_KEYLIGHT_DIRECTION;
|
||||
static const bool DEFAULT_KEYLIGHT_CAST_SHADOWS;
|
||||
|
||||
DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, Color, color, xColor, DEFAULT_KEYLIGHT_COLOR);
|
||||
DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, Intensity, intensity, float, DEFAULT_KEYLIGHT_INTENSITY);
|
||||
DEFINE_PROPERTY_REF(PROP_KEYLIGHT_DIRECTION, Direction, direction, glm::vec3, DEFAULT_KEYLIGHT_DIRECTION);
|
||||
DEFINE_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, CastShadows, castShadows, bool, DEFAULT_KEYLIGHT_CAST_SHADOWS);
|
||||
};
|
||||
|
||||
#endif // hifi_KeyLightPropertyGroup_h
|
||||
|
|
|
@ -298,7 +298,7 @@ void LightEntityItem::resetLightPropertiesChanged() {
|
|||
}
|
||||
|
||||
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,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
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,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class LineEntityItem : public EntityItem {
|
|||
// never have a ray intersection pick a LineEntityItem.
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
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,
|
||||
QVariantMap& extraInfo,
|
||||
bool precisionPicking) const override { return false; }
|
||||
|
|
|
@ -94,7 +94,7 @@ class PolyLineEntityItem : public EntityItem {
|
|||
// never have a ray intersection pick a PolyLineEntityItem.
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
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,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const override { return false; }
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ class PolyVoxEntityItem : public EntityItem {
|
|||
// never have a ray intersection pick a PolyVoxEntityItem.
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
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,
|
||||
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& keepSearching, OctreeElementPointer& element,
|
||||
OctreeElementPointer& element,
|
||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||
// determine the ray in the frame of the entity transformed from a unit sphere
|
||||
|
|
|
@ -92,7 +92,7 @@ public:
|
|||
|
||||
bool supportsDetailedRayIntersection() const override;
|
||||
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,
|
||||
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& keepSearching, OctreeElementPointer& element, float& distance,
|
||||
OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||
glm::vec3 dimensions = getScaledDimensions();
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
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,
|
||||
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& keepSearching, OctreeElementPointer& element, float& distance,
|
||||
OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||
glm::vec3 dimensions = getScaledDimensions();
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
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,
|
||||
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& keepSearching, OctreeElementPointer& element, float& distance,
|
||||
OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ public:
|
|||
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
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,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||
|
||||
|
|
|
@ -868,16 +868,6 @@ void SphericalHarmonics::evalFromTexture(const Texture& texture) {
|
|||
|
||||
|
||||
// TextureSource
|
||||
TextureSource::TextureSource() {
|
||||
}
|
||||
|
||||
TextureSource::~TextureSource() {
|
||||
}
|
||||
|
||||
void TextureSource::reset(const QUrl& url) {
|
||||
_imageUrl = url;
|
||||
}
|
||||
|
||||
void TextureSource::resetTexture(gpu::TexturePointer texture) {
|
||||
_gpuTexture = texture;
|
||||
}
|
||||
|
|
|
@ -647,13 +647,11 @@ typedef std::vector<TextureView> TextureViews;
|
|||
// It provides the mechanism to create a texture using a customizable TextureLoader
|
||||
class TextureSource {
|
||||
public:
|
||||
TextureSource();
|
||||
~TextureSource();
|
||||
TextureSource(const QUrl& url, int type = 0) : _imageUrl(url), _type(type) {}
|
||||
|
||||
const QUrl& getUrl() const { return _imageUrl; }
|
||||
const gpu::TexturePointer getGPUTexture() const { return _gpuTexture; }
|
||||
|
||||
void reset(const QUrl& url);
|
||||
int getType() const { return _type; }
|
||||
|
||||
void resetTexture(gpu::TexturePointer texture);
|
||||
|
||||
|
@ -662,6 +660,7 @@ public:
|
|||
protected:
|
||||
gpu::TexturePointer _gpuTexture;
|
||||
QUrl _imageUrl;
|
||||
int _type { 0 };
|
||||
};
|
||||
typedef std::shared_ptr< TextureSource > TextureSourcePointer;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
set(TARGET_NAME graphics-scripting)
|
||||
setup_hifi_library()
|
||||
link_hifi_libraries(shared networking graphics fbx model-networking script-engine)
|
||||
link_hifi_libraries(shared networking graphics fbx image model-networking script-engine)
|
||||
include_hifi_library_headers(gpu)
|
||||
|
|
|
@ -6,9 +6,14 @@
|
|||
#include <QtCore/QUuid>
|
||||
#include <QPointer>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <SpatiallyNestable.h>
|
||||
|
||||
#include "graphics/Material.h"
|
||||
#include "graphics/TextureMap.h"
|
||||
|
||||
namespace graphics {
|
||||
class Mesh;
|
||||
}
|
||||
|
@ -31,6 +36,53 @@ namespace scriptable {
|
|||
using ModelProviderPointer = std::shared_ptr<scriptable::ModelProvider>;
|
||||
using WeakModelProviderPointer = std::weak_ptr<scriptable::ModelProvider>;
|
||||
|
||||
class ScriptableMaterial {
|
||||
public:
|
||||
ScriptableMaterial() {}
|
||||
ScriptableMaterial(const graphics::MaterialPointer& material);
|
||||
ScriptableMaterial(const ScriptableMaterial& material) { *this = material; }
|
||||
ScriptableMaterial& operator=(const ScriptableMaterial& material);
|
||||
|
||||
QString name;
|
||||
QString model;
|
||||
float opacity;
|
||||
float roughness;
|
||||
float metallic;
|
||||
float scattering;
|
||||
bool unlit;
|
||||
glm::vec3 emissive;
|
||||
glm::vec3 albedo;
|
||||
QString emissiveMap;
|
||||
QString albedoMap;
|
||||
QString opacityMap;
|
||||
QString metallicMap;
|
||||
QString specularMap;
|
||||
QString roughnessMap;
|
||||
QString glossMap;
|
||||
QString normalMap;
|
||||
QString bumpMap;
|
||||
QString occlusionMap;
|
||||
QString lightmapMap;
|
||||
QString scatteringMap;
|
||||
};
|
||||
|
||||
/**jsdoc
|
||||
* @typedef {object} Graphics.MaterialLayer
|
||||
* @property {Material} material - This layer's material.
|
||||
* @property {number} priority - The priority of this layer. If multiple materials are applied to a mesh part, only the highest priority layer is used.
|
||||
*/
|
||||
class ScriptableMaterialLayer {
|
||||
public:
|
||||
ScriptableMaterialLayer() {}
|
||||
ScriptableMaterialLayer(const graphics::MaterialLayer& materialLayer) : material(materialLayer.material), priority(materialLayer.priority) {}
|
||||
ScriptableMaterialLayer(const ScriptableMaterialLayer& materialLayer) { *this = materialLayer; }
|
||||
ScriptableMaterialLayer& operator=(const ScriptableMaterialLayer& materialLayer);
|
||||
|
||||
ScriptableMaterial material;
|
||||
quint16 priority;
|
||||
};
|
||||
typedef QHash<QString, QVector<scriptable::ScriptableMaterialLayer>> MultiMaterialMap;
|
||||
|
||||
class ScriptableMeshBase : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -55,6 +107,8 @@ namespace scriptable {
|
|||
WeakModelProviderPointer provider;
|
||||
QUuid objectID; // spatially nestable ID
|
||||
QVector<scriptable::ScriptableMeshBase> meshes;
|
||||
MultiMaterialMap materialLayers;
|
||||
QVector<QString> materialNames;
|
||||
|
||||
ScriptableModelBase(QObject* parent = nullptr) : QObject(parent) {}
|
||||
ScriptableModelBase(const ScriptableModelBase& other) : QObject(other.parent()) { *this = other; }
|
||||
|
@ -63,9 +117,11 @@ namespace scriptable {
|
|||
|
||||
void append(const ScriptableMeshBase& mesh);
|
||||
void append(scriptable::WeakMeshPointer mesh);
|
||||
void appendMaterial(const graphics::MaterialLayer& materialLayer, int shapeID, std::string materialName);
|
||||
void appendMaterials(const std::unordered_map<std::string, graphics::MultiMaterial>& materialsToAppend);
|
||||
void appendMaterialNames(const std::vector<std::string>& names);
|
||||
// TODO: in future containers for these could go here
|
||||
// QVariantMap shapes;
|
||||
// QVariantMap materials;
|
||||
// QVariantMap armature;
|
||||
};
|
||||
|
||||
|
|
|
@ -297,6 +297,10 @@ namespace {
|
|||
qRegisterMetaType<scriptable::ScriptableMeshPointer>(),
|
||||
qRegisterMetaType<scriptable::ScriptableModelPointer>(),
|
||||
qRegisterMetaType<scriptable::ScriptableMeshPartPointer>(),
|
||||
qRegisterMetaType<scriptable::ScriptableMaterial>(),
|
||||
qRegisterMetaType<scriptable::ScriptableMaterialLayer>(),
|
||||
qRegisterMetaType<QVector<scriptable::ScriptableMaterialLayer>>(),
|
||||
qRegisterMetaType<scriptable::MultiMaterialMap>(),
|
||||
qRegisterMetaType<graphics::Mesh::Topology>(),
|
||||
};
|
||||
}
|
||||
|
@ -335,6 +339,67 @@ namespace scriptable {
|
|||
);
|
||||
}
|
||||
|
||||
QScriptValue qVectorScriptableMaterialLayerToScriptValue(QScriptEngine* engine, const QVector<scriptable::ScriptableMaterialLayer>& vector) {
|
||||
return qScriptValueFromSequence(engine, vector);
|
||||
}
|
||||
|
||||
void qVectorScriptableMaterialLayerFromScriptValue(const QScriptValue& array, QVector<scriptable::ScriptableMaterialLayer>& result) {
|
||||
qScriptValueToSequence(array, result);
|
||||
}
|
||||
|
||||
QScriptValue scriptableMaterialToScriptValue(QScriptEngine* engine, const scriptable::ScriptableMaterial &material) {
|
||||
QScriptValue obj = engine->newObject();
|
||||
obj.setProperty("name", material.name);
|
||||
obj.setProperty("model", material.model);
|
||||
obj.setProperty("opacity", material.opacity);
|
||||
obj.setProperty("roughness", material.roughness);
|
||||
obj.setProperty("metallic", material.metallic);
|
||||
obj.setProperty("scattering", material.scattering);
|
||||
obj.setProperty("unlit", material.unlit);
|
||||
obj.setProperty("emissive", vec3toScriptValue(engine, material.emissive));
|
||||
obj.setProperty("albedo", vec3toScriptValue(engine, material.albedo));
|
||||
obj.setProperty("emissiveMap", material.emissiveMap);
|
||||
obj.setProperty("albedoMap", material.albedoMap);
|
||||
obj.setProperty("opacityMap", material.opacityMap);
|
||||
obj.setProperty("metallicMap", material.metallicMap);
|
||||
obj.setProperty("specularMap", material.specularMap);
|
||||
obj.setProperty("roughnessMap", material.roughnessMap);
|
||||
obj.setProperty("glossMap", material.glossMap);
|
||||
obj.setProperty("normalMap", material.normalMap);
|
||||
obj.setProperty("bumpMap", material.bumpMap);
|
||||
obj.setProperty("occlusionMap", material.occlusionMap);
|
||||
obj.setProperty("lightmapMap", material.lightmapMap);
|
||||
obj.setProperty("scatteringMap", material.scatteringMap);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void scriptableMaterialFromScriptValue(const QScriptValue &object, scriptable::ScriptableMaterial& material) {
|
||||
// No need to convert from QScriptValue to ScriptableMaterial
|
||||
}
|
||||
|
||||
QScriptValue scriptableMaterialLayerToScriptValue(QScriptEngine* engine, const scriptable::ScriptableMaterialLayer &materialLayer) {
|
||||
QScriptValue obj = engine->newObject();
|
||||
obj.setProperty("material", scriptableMaterialToScriptValue(engine, materialLayer.material));
|
||||
obj.setProperty("priority", materialLayer.priority);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void scriptableMaterialLayerFromScriptValue(const QScriptValue &object, scriptable::ScriptableMaterialLayer& materialLayer) {
|
||||
// No need to convert from QScriptValue to ScriptableMaterialLayer
|
||||
}
|
||||
|
||||
QScriptValue multiMaterialMapToScriptValue(QScriptEngine* engine, const scriptable::MultiMaterialMap& map) {
|
||||
QScriptValue obj = engine->newObject();
|
||||
for (auto key : map.keys()) {
|
||||
obj.setProperty(key, qVectorScriptableMaterialLayerToScriptValue(engine, map[key]));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
void multiMaterialMapFromScriptValue(const QScriptValue& map, scriptable::MultiMaterialMap& result) {
|
||||
// No need to convert from QScriptValue to MultiMaterialMap
|
||||
}
|
||||
|
||||
template <typename T> int registerDebugEnum(QScriptEngine* engine, const DebugEnums<T>& debugEnums) {
|
||||
static const DebugEnums<T>& instance = debugEnums;
|
||||
return qScriptRegisterMetaType<T>(
|
||||
|
@ -351,6 +416,7 @@ namespace scriptable {
|
|||
|
||||
void GraphicsScriptingInterface::registerMetaTypes(QScriptEngine* engine) {
|
||||
qScriptRegisterSequenceMetaType<QVector<glm::uint32>>(engine);
|
||||
qScriptRegisterSequenceMetaType<QVector<scriptable::ScriptableMaterialLayer>>(engine);
|
||||
|
||||
scriptable::registerQPointerMetaType<scriptable::ScriptableModel>(engine);
|
||||
scriptable::registerQPointerMetaType<scriptable::ScriptableMesh>(engine);
|
||||
|
@ -361,6 +427,11 @@ void GraphicsScriptingInterface::registerMetaTypes(QScriptEngine* engine) {
|
|||
scriptable::registerDebugEnum<gpu::Semantic>(engine, gpu::SEMANTICS);
|
||||
scriptable::registerDebugEnum<gpu::Dimension>(engine, gpu::DIMENSIONS);
|
||||
|
||||
qScriptRegisterMetaType(engine, scriptable::scriptableMaterialToScriptValue, scriptable::scriptableMaterialFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, scriptable::scriptableMaterialLayerToScriptValue, scriptable::scriptableMaterialLayerFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, scriptable::qVectorScriptableMaterialLayerToScriptValue, scriptable::qVectorScriptableMaterialLayerFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, scriptable::multiMaterialMapToScriptValue, scriptable::multiMaterialMapFromScriptValue);
|
||||
|
||||
Q_UNUSED(metaTypeIds);
|
||||
}
|
||||
|
||||
|
|
|
@ -400,6 +400,5 @@ scriptable::ScriptableMesh::~ScriptableMesh() {
|
|||
strongMesh.reset();
|
||||
}
|
||||
|
||||
|
||||
#include "ScriptableMesh.moc"
|
||||
|
||||
|
|
|
@ -14,14 +14,120 @@
|
|||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include "graphics/Material.h"
|
||||
|
||||
#include "image/Image.h"
|
||||
|
||||
// #define SCRIPTABLE_MESH_DEBUG 1
|
||||
|
||||
scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const scriptable::ScriptableMaterial& material) {
|
||||
name = material.name;
|
||||
model = material.model;
|
||||
opacity = material.opacity;
|
||||
roughness = material.roughness;
|
||||
metallic = material.metallic;
|
||||
scattering = material.scattering;
|
||||
unlit = material.unlit;
|
||||
emissive = material.emissive;
|
||||
albedo = material.albedo;
|
||||
emissiveMap = material.emissiveMap;
|
||||
albedoMap = material.albedoMap;
|
||||
opacityMap = material.opacityMap;
|
||||
metallicMap = material.metallicMap;
|
||||
specularMap = material.specularMap;
|
||||
roughnessMap = material.roughnessMap;
|
||||
glossMap = material.glossMap;
|
||||
normalMap = material.normalMap;
|
||||
bumpMap = material.bumpMap;
|
||||
occlusionMap = material.occlusionMap;
|
||||
lightmapMap = material.lightmapMap;
|
||||
scatteringMap = material.scatteringMap;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPointer& material) :
|
||||
name(material->getName().c_str()),
|
||||
model(material->getModel().c_str()),
|
||||
opacity(material->getOpacity()),
|
||||
roughness(material->getRoughness()),
|
||||
metallic(material->getMetallic()),
|
||||
scattering(material->getScattering()),
|
||||
unlit(material->isUnlit()),
|
||||
emissive(material->getEmissive()),
|
||||
albedo(material->getAlbedo())
|
||||
{
|
||||
auto map = material->getTextureMap(graphics::Material::MapChannel::EMISSIVE_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
emissiveMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::ALBEDO_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
albedoMap = map->getTextureSource()->getUrl().toString();
|
||||
if (map->useAlphaChannel()) {
|
||||
opacityMap = albedoMap;
|
||||
}
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::METALLIC_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
if (map->getTextureSource()->getType() == image::TextureUsage::Type::METALLIC_TEXTURE) {
|
||||
metallicMap = map->getTextureSource()->getUrl().toString();
|
||||
} else if (map->getTextureSource()->getType() == image::TextureUsage::Type::SPECULAR_TEXTURE) {
|
||||
specularMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::ROUGHNESS_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
if (map->getTextureSource()->getType() == image::TextureUsage::Type::ROUGHNESS_TEXTURE) {
|
||||
roughnessMap = map->getTextureSource()->getUrl().toString();
|
||||
} else if (map->getTextureSource()->getType() == image::TextureUsage::Type::GLOSS_TEXTURE) {
|
||||
glossMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::NORMAL_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
if (map->getTextureSource()->getType() == image::TextureUsage::Type::NORMAL_TEXTURE) {
|
||||
normalMap = map->getTextureSource()->getUrl().toString();
|
||||
} else if (map->getTextureSource()->getType() == image::TextureUsage::Type::BUMP_TEXTURE) {
|
||||
bumpMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::OCCLUSION_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
occlusionMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::LIGHTMAP_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
lightmapMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
|
||||
map = material->getTextureMap(graphics::Material::MapChannel::SCATTERING_MAP);
|
||||
if (map && map->getTextureSource()) {
|
||||
scatteringMap = map->getTextureSource()->getUrl().toString();
|
||||
}
|
||||
}
|
||||
|
||||
scriptable::ScriptableMaterialLayer& scriptable::ScriptableMaterialLayer::operator=(const scriptable::ScriptableMaterialLayer& materialLayer) {
|
||||
material = materialLayer.material;
|
||||
priority = materialLayer.priority;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
scriptable::ScriptableModelBase& scriptable::ScriptableModelBase::operator=(const scriptable::ScriptableModelBase& other) {
|
||||
provider = other.provider;
|
||||
objectID = other.objectID;
|
||||
for (const auto& mesh : other.meshes) {
|
||||
append(mesh);
|
||||
}
|
||||
materialLayers = other.materialLayers;
|
||||
materialNames = other.materialNames;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -34,6 +140,8 @@ scriptable::ScriptableModelBase::~ScriptableModelBase() {
|
|||
m.strongMesh.reset();
|
||||
}
|
||||
meshes.clear();
|
||||
materialLayers.clear();
|
||||
materialNames.clear();
|
||||
}
|
||||
|
||||
void scriptable::ScriptableModelBase::append(scriptable::WeakMeshPointer mesh) {
|
||||
|
@ -47,6 +155,27 @@ void scriptable::ScriptableModelBase::append(const ScriptableMeshBase& mesh) {
|
|||
meshes << mesh;
|
||||
}
|
||||
|
||||
void scriptable::ScriptableModelBase::appendMaterial(const graphics::MaterialLayer& materialLayer, int shapeID, std::string materialName) {
|
||||
materialLayers[QString::number(shapeID)].push_back(ScriptableMaterialLayer(materialLayer));
|
||||
materialLayers["mat::" + QString::fromStdString(materialName)].push_back(ScriptableMaterialLayer(materialLayer));
|
||||
}
|
||||
|
||||
void scriptable::ScriptableModelBase::appendMaterials(const std::unordered_map<std::string, graphics::MultiMaterial>& materialsToAppend) {
|
||||
auto materialsToAppendCopy = materialsToAppend;
|
||||
for (auto& multiMaterial : materialsToAppendCopy) {
|
||||
while (!multiMaterial.second.empty()) {
|
||||
materialLayers[QString(multiMaterial.first.c_str())].push_back(ScriptableMaterialLayer(multiMaterial.second.top()));
|
||||
multiMaterial.second.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scriptable::ScriptableModelBase::appendMaterialNames(const std::vector<std::string>& names) {
|
||||
for (auto& name : names) {
|
||||
materialNames.append(QString::fromStdString(name));
|
||||
}
|
||||
}
|
||||
|
||||
QString scriptable::ScriptableModel::toString() const {
|
||||
return QString("[ScriptableModel%1%2 numMeshes=%3]")
|
||||
.arg(objectID.isNull() ? "" : " objectID="+objectID.toString())
|
||||
|
|
|
@ -21,6 +21,8 @@ namespace scriptable {
|
|||
* @property {Uuid} objectID - UUID of corresponding inworld object (if model is associated)
|
||||
* @property {number} numMeshes - The number of submeshes contained in the model.
|
||||
* @property {Graphics.Mesh[]} meshes - Array of submesh references.
|
||||
* @property {Object.<string, Graphics.MaterialLayer[]>} materialLayers - Map of materials layer lists. You can look up a material layer list by mesh part number or by material name.
|
||||
* @property {string[]} materialNames - Array of all the material names used by the mesh parts of this model, in order (e.g. materialNames[0] is the name of the first mesh part's material).
|
||||
*/
|
||||
|
||||
class ScriptableModel : public ScriptableModelBase {
|
||||
|
@ -28,18 +30,24 @@ namespace scriptable {
|
|||
Q_PROPERTY(QUuid objectID MEMBER objectID CONSTANT)
|
||||
Q_PROPERTY(glm::uint32 numMeshes READ getNumMeshes)
|
||||
Q_PROPERTY(ScriptableMeshes meshes READ getMeshes)
|
||||
Q_PROPERTY(scriptable::MultiMaterialMap materialLayers READ getMaterialLayers)
|
||||
Q_PROPERTY(QVector<QString> materialNames READ getMaterialNames)
|
||||
|
||||
public:
|
||||
ScriptableModel(QObject* parent = nullptr) : ScriptableModelBase(parent) {}
|
||||
ScriptableModel(const ScriptableModel& other) : ScriptableModelBase(other) {}
|
||||
ScriptableModel(const ScriptableModelBase& other) : ScriptableModelBase(other) {}
|
||||
ScriptableModel& operator=(const ScriptableModelBase& view) { ScriptableModelBase::operator=(view); return *this; }
|
||||
|
||||
operator scriptable::ScriptableModelBasePointer() {
|
||||
return QPointer<scriptable::ScriptableModelBase>(qobject_cast<scriptable::ScriptableModelBase*>(this));
|
||||
}
|
||||
ScriptableMeshes getMeshes();
|
||||
const ScriptableMeshes getConstMeshes() const;
|
||||
|
||||
scriptable::MultiMaterialMap getMaterialLayers() { return materialLayers; }
|
||||
QVector<QString> getMaterialNames() { return materialNames; }
|
||||
|
||||
public slots:
|
||||
scriptable::ScriptableModelPointer cloneModel(const QVariantMap& options = QVariantMap());
|
||||
QString toString() const;
|
||||
|
@ -53,3 +61,6 @@ namespace scriptable {
|
|||
|
||||
Q_DECLARE_METATYPE(scriptable::ScriptableModelPointer)
|
||||
Q_DECLARE_METATYPE(QVector<scriptable::ScriptableModelPointer>)
|
||||
Q_DECLARE_METATYPE(scriptable::ScriptableMaterial)
|
||||
Q_DECLARE_METATYPE(scriptable::ScriptableMaterialLayer)
|
||||
Q_DECLARE_METATYPE(scriptable::MultiMaterialMap)
|
||||
|
|
|
@ -65,6 +65,14 @@ const Vec3& Light::getDirection() const {
|
|||
return _lightSchemaBuffer->volume.direction;
|
||||
}
|
||||
|
||||
void Light::setCastShadows(const bool castShadows) {
|
||||
_castShadows = castShadows;
|
||||
}
|
||||
|
||||
bool Light::getCastShadows() const {
|
||||
return _castShadows;
|
||||
}
|
||||
|
||||
void Light::setColor(const Color& color) {
|
||||
_lightSchemaBuffer.edit().irradiance.color = color;
|
||||
updateLightRadius();
|
||||
|
@ -132,7 +140,6 @@ void Light::setSpotExponent(float exponent) {
|
|||
_lightSchemaBuffer.edit().irradiance.falloffSpot = exponent;
|
||||
}
|
||||
|
||||
|
||||
void Light::setAmbientIntensity(float intensity) {
|
||||
_ambientSchemaBuffer.edit().intensity = intensity;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,9 @@ public:
|
|||
void setDirection(const Vec3& direction);
|
||||
const Vec3& getDirection() const;
|
||||
|
||||
void setCastShadows(const bool castShadows);
|
||||
bool getCastShadows() const;
|
||||
|
||||
void setOrientation(const Quat& orientation);
|
||||
const glm::quat& getOrientation() const { return _transform.getRotation(); }
|
||||
|
||||
|
@ -191,6 +194,8 @@ protected:
|
|||
|
||||
void updateLightRadius();
|
||||
|
||||
bool _castShadows{ false };
|
||||
|
||||
};
|
||||
typedef std::shared_ptr< Light > LightPointer;
|
||||
|
||||
|
|
|
@ -356,8 +356,9 @@ public:
|
|||
|
||||
void setTextureTransforms(const Transform& transform);
|
||||
|
||||
const std::string& getName() { return _name; }
|
||||
const std::string& getName() const { return _name; }
|
||||
|
||||
const std::string& getModel() const { return _model; }
|
||||
void setModel(const std::string& model) { _model = model; }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "QJsonDocument"
|
||||
#include "QJsonArray"
|
||||
|
||||
#include "RegisteredMetaTypes.h"
|
||||
|
||||
NetworkMaterialResource::NetworkMaterialResource(const QUrl& url) :
|
||||
Resource(url) {}
|
||||
|
||||
|
@ -39,6 +41,11 @@ bool NetworkMaterialResource::parseJSONColor(const QJsonValue& array, glm::vec3&
|
|||
color = glm::vec3(colorArray[0].toDouble(), colorArray[1].toDouble(), colorArray[2].toDouble());
|
||||
return true;
|
||||
}
|
||||
} else if (array.isObject()) {
|
||||
bool toReturn;
|
||||
isSRGB = true;
|
||||
color = vec3FromVariant(array.toObject(), toReturn);
|
||||
return toReturn;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue