Merge remote-tracking branch 'upstream/master' into HEAD
2
BUILD.md
|
@ -25,7 +25,7 @@ The above dependencies will be downloaded, built, linked and included automatica
|
|||
|
||||
These are not placed in your normal build tree when doing an out of source build so that they do not need to be re-downloaded and re-compiled every time the CMake build folder is cleared. Should you want to force a re-download and re-compile of a specific external, you can simply remove that directory from the appropriate subfolder in `build/ext`. Should you want to force a re-download and re-compile of all externals, just remove the `build/ext` folder.
|
||||
|
||||
If you would like to use a specific install of a dependency instead of the version that would be grabbed as a CMake ExternalProject, you can pass -DUSE_LOCAL_$NAME=0 (where $NAME is the name of the subfolder in [cmake/externals](cmake/externals)) when you run CMake to tell it not to get that dependency as an external project.
|
||||
If you would like to use a specific install of a dependency instead of the version that would be grabbed as a CMake ExternalProject, you can pass -DUSE\_LOCAL\_$NAME=0 (where $NAME is the name of the subfolder in [cmake/externals](cmake/externals)) when you run CMake to tell it not to get that dependency as an external project.
|
||||
|
||||
### OS Specific Build Guides
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
|||
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
|
||||
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
|
||||
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
|
||||
packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket");
|
||||
|
||||
static const int LOG_INTERVAL = MSECS_PER_SECOND / 10;
|
||||
auto timer = new QTimer(this);
|
||||
|
@ -231,6 +232,27 @@ void EntityScriptServer::pushLogs() {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode) {
|
||||
|
||||
if (_entitiesScriptEngine && _entityViewer.getTree() && !_shuttingDown) {
|
||||
auto entityID = QUuid::fromRfc4122(receivedMessage->read(NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
auto method = receivedMessage->readString();
|
||||
|
||||
quint16 paramCount;
|
||||
receivedMessage->readPrimitive(¶mCount);
|
||||
|
||||
QStringList params;
|
||||
for (int param = 0; param < paramCount; param++) {
|
||||
auto paramString = receivedMessage->readString();
|
||||
params << paramString;
|
||||
}
|
||||
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EntityScriptServer::run() {
|
||||
// make sure we request our script once the agent connects to the domain
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
|
|
@ -54,6 +54,9 @@ private slots:
|
|||
|
||||
void pushLogs();
|
||||
|
||||
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
|
||||
|
||||
private:
|
||||
void negotiateAudioFormat();
|
||||
void selectAudioFormat(const QString& selectedCodecName);
|
||||
|
|
20
cmake/macros/GenerateQrc.cmake
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
function(GENERATE_QRC)
|
||||
set(oneValueArgs OUTPUT PREFIX PATH)
|
||||
set(multiValueArgs GLOBS)
|
||||
cmake_parse_arguments(GENERATE_QRC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
|
||||
if ("${GENERATE_QRC_PREFIX}" STREQUAL "")
|
||||
set(QRC_PREFIX_PATH /)
|
||||
else()
|
||||
set(QRC_PREFIX_PATH ${GENERATE_QRC_PREFIX})
|
||||
endif()
|
||||
|
||||
foreach(GLOB ${GENERATE_QRC_GLOBS})
|
||||
file(GLOB_RECURSE FOUND_FILES RELATIVE ${GENERATE_QRC_PATH} ${GLOB})
|
||||
foreach(FILENAME ${FOUND_FILES})
|
||||
set(QRC_CONTENTS "${QRC_CONTENTS}<file alias=\"${FILENAME}\">${GENERATE_QRC_PATH}/${FILENAME}</file>\n")
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
configure_file("${HF_CMAKE_DIR}/templates/resources.qrc.in" ${GENERATE_QRC_OUTPUT})
|
||||
endfunction()
|
5
cmake/templates/resources.qrc.in
Normal file
|
@ -0,0 +1,5 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="@QRC_PREFIX_PATH@">
|
||||
@QRC_CONTENTS@
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -1,6 +1,20 @@
|
|||
set(TARGET_NAME interface)
|
||||
project(${TARGET_NAME})
|
||||
|
||||
file(GLOB_RECURSE QML_SRC resources/qml/*.qml resources/qml/*.js)
|
||||
add_custom_target(qml SOURCES ${QML_SRC})
|
||||
GroupSources("resources/qml")
|
||||
|
||||
function(JOIN VALUES GLUE OUTPUT)
|
||||
string (REGEX REPLACE "([^\\]|^);" "\\1${GLUE}" _TMP_STR "${VALUES}")
|
||||
string (REGEX REPLACE "[\\](.)" "\\1" _TMP_STR "${_TMP_STR}") #fixes escaping
|
||||
set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
set(INTERFACE_QML_QRC ${CMAKE_CURRENT_BINARY_DIR}/qml.qrc)
|
||||
generate_qrc(OUTPUT ${INTERFACE_QML_QRC} PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources GLOBS *.qml *.qss *.js *.html *.ttf *.gif *.svg *.png *.jpg)
|
||||
|
||||
# set a default root dir for each of our optional externals if it was not passed
|
||||
set(OPTIONAL_EXTERNALS "LeapMotion")
|
||||
|
||||
|
@ -66,9 +80,7 @@ qt5_wrap_ui(QT_UI_HEADERS "${QT_UI_FILES}")
|
|||
# add them to the interface source files
|
||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${QT_UI_HEADERS}" "${QT_RESOURCES}")
|
||||
|
||||
file(GLOB_RECURSE QML_SRC resources/qml/*.qml resources/qml/*.js)
|
||||
add_custom_target(qml SOURCES ${QML_SRC})
|
||||
GroupSources("resources/qml")
|
||||
list(APPEND INTERFACE_SRCS ${INTERFACE_QML_QRC})
|
||||
|
||||
if (UNIX)
|
||||
install(
|
||||
|
@ -131,10 +143,10 @@ if (APPLE)
|
|||
|
||||
# append the discovered resources to our list of interface sources
|
||||
list(APPEND INTERFACE_SRCS ${DISCOVERED_RESOURCES})
|
||||
|
||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME}")
|
||||
list(APPEND INTERFACE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME})
|
||||
endif()
|
||||
|
||||
|
||||
# create the executable, make it a bundle on OS X
|
||||
if (APPLE)
|
||||
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM})
|
||||
|
|
Before Width: | Height: | Size: 312 KiB After Width: | Height: | Size: 604 KiB |
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 503 KiB |
Before Width: | Height: | Size: 307 KiB After Width: | Height: | Size: 585 KiB |
Before Width: | Height: | Size: 268 KiB After Width: | Height: | Size: 547 KiB |
|
@ -11,6 +11,7 @@
|
|||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4 as Original
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
import "../styles-uit"
|
||||
|
||||
|
@ -26,6 +27,16 @@ Original.Button {
|
|||
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
onHoveredChanged: {
|
||||
if (hovered) {
|
||||
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
}
|
||||
|
||||
style: ButtonStyle {
|
||||
|
||||
background: Rectangle {
|
||||
|
|
|
@ -14,6 +14,8 @@ import QtQuick.Controls.Styles 1.4
|
|||
|
||||
import "../styles-uit"
|
||||
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
Original.CheckBox {
|
||||
id: checkBox
|
||||
|
||||
|
@ -28,6 +30,15 @@ Original.CheckBox {
|
|||
readonly property int checkRadius: 2
|
||||
activeFocusOnPress: true
|
||||
|
||||
onClicked: {
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
}
|
||||
|
||||
// TODO: doesnt works for QQC1. check with QQC2
|
||||
// onHovered: {
|
||||
// tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
// }
|
||||
|
||||
style: CheckBoxStyle {
|
||||
indicator: Rectangle {
|
||||
id: box
|
||||
|
|
|
@ -13,6 +13,7 @@ import QtQuick.Controls 2.2
|
|||
|
||||
import "../styles-uit"
|
||||
import "../controls-uit" as HiFiControls
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
CheckBox {
|
||||
id: checkBox
|
||||
|
@ -32,6 +33,17 @@ CheckBox {
|
|||
readonly property int checkSize: Math.max(boxSize - 8, 10)
|
||||
readonly property int checkRadius: isRound ? checkSize / 2 : 2
|
||||
focusPolicy: Qt.ClickFocus
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: {
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
}
|
||||
|
||||
onHoveredChanged: {
|
||||
if (hovered) {
|
||||
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
}
|
||||
}
|
||||
|
||||
indicator: Rectangle {
|
||||
id: box
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4 as Original
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
import "../styles-uit"
|
||||
|
||||
|
@ -24,6 +25,16 @@ Original.Button {
|
|||
width: 120
|
||||
height: 28
|
||||
|
||||
onHoveredChanged: {
|
||||
if (hovered) {
|
||||
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
}
|
||||
|
||||
style: ButtonStyle {
|
||||
|
||||
background: Rectangle {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import QtQuick 2.0
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
Item {
|
||||
id: keyItem
|
||||
|
@ -32,8 +33,15 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
onContainsMouseChanged: {
|
||||
if (containsMouse) {
|
||||
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
mouse.accepted = true;
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
|
||||
webEntity.synthesizeKeyPress(glyph);
|
||||
webEntity.synthesizeKeyPress(glyph, mirrorText);
|
||||
|
|
|
@ -15,6 +15,8 @@ import QtQuick.Controls.Styles 1.4
|
|||
import "../styles-uit"
|
||||
import "../controls-uit" as HifiControls
|
||||
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
Original.RadioButton {
|
||||
id: radioButton
|
||||
HifiConstants { id: hifi }
|
||||
|
@ -27,6 +29,15 @@ Original.RadioButton {
|
|||
readonly property int checkSize: 10
|
||||
readonly property int checkRadius: 2
|
||||
|
||||
onClicked: {
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
}
|
||||
|
||||
// TODO: doesnt works for QQC1. check with QQC2
|
||||
// onHovered: {
|
||||
// tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
// }
|
||||
|
||||
style: RadioButtonStyle {
|
||||
indicator: Rectangle {
|
||||
id: box
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
import "../../controls-uit"
|
||||
|
||||
|
@ -22,7 +23,16 @@ Preference {
|
|||
|
||||
Button {
|
||||
id: button
|
||||
onClicked: preference.trigger()
|
||||
onHoveredChanged: {
|
||||
if (hovered) {
|
||||
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
preference.trigger();
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
}
|
||||
width: 180
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
import "../../controls-uit"
|
||||
|
||||
|
@ -38,6 +39,16 @@ Preference {
|
|||
|
||||
CheckBox {
|
||||
id: checkBox
|
||||
onHoveredChanged: {
|
||||
if (hovered) {
|
||||
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
}
|
||||
|
||||
anchors {
|
||||
top: spacer.bottom
|
||||
left: parent.left
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
import Hifi 1.0
|
||||
import QtQuick 2.5
|
||||
import QtGraphicalEffects 1.0
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
import "toolbars"
|
||||
import "../styles-uit"
|
||||
|
||||
|
@ -243,9 +245,15 @@ Item {
|
|||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
acceptedButtons: Qt.LeftButton;
|
||||
onClicked: goFunction("hifi://" + hifiUrl);
|
||||
onClicked: {
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
goFunction("hifi://" + hifiUrl);
|
||||
}
|
||||
hoverEnabled: true;
|
||||
onEntered: hoverThunk();
|
||||
onEntered: {
|
||||
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
hoverThunk();
|
||||
}
|
||||
onExited: unhoverThunk();
|
||||
}
|
||||
StateImage {
|
||||
|
@ -261,6 +269,7 @@ Item {
|
|||
}
|
||||
}
|
||||
function go() {
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
goFunction(drillDownToPlace ? ("/places/" + placeName) : ("/user_stories/" + storyId));
|
||||
}
|
||||
MouseArea {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// skyboxchanger.qml
|
||||
//
|
||||
// SkyboxChanger.qml
|
||||
// qml/hifi
|
||||
//
|
||||
// Created by Cain Kilgore on 9th August 2017
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
|
@ -9,33 +9,73 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick 2.5
|
||||
import "../styles-uit"
|
||||
import "../controls-uit" as HifiControls
|
||||
import QtQuick.Controls 2.2
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
id: root;
|
||||
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
property var defaultThumbnails: [];
|
||||
property var defaultFulls: [];
|
||||
|
||||
ListModel {
|
||||
id: skyboxModel;
|
||||
}
|
||||
|
||||
function getSkyboxes() {
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
var url = "http://mpassets.highfidelity.com/5fbdbeef-1cf8-4954-811d-3d4acbba4dc9-v1/skyboxes.json";
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState === XMLHttpRequest.DONE && xmlhttp.status === 200) {
|
||||
sortSkyboxes(xmlhttp.responseText);
|
||||
}
|
||||
}
|
||||
xmlhttp.open("GET", url, true);
|
||||
xmlhttp.send();
|
||||
}
|
||||
|
||||
function sortSkyboxes(response) {
|
||||
var arr = JSON.parse(response);
|
||||
var arrLength = arr.length;
|
||||
for (var i = 0; i < arrLength; i++) {
|
||||
defaultThumbnails.push(arr[i].thumb);
|
||||
defaultFulls.push(arr[i].full);
|
||||
skyboxModel.append({});
|
||||
}
|
||||
setSkyboxes();
|
||||
}
|
||||
|
||||
function setSkyboxes() {
|
||||
for (var i = 0; i < skyboxModel.count; i++) {
|
||||
skyboxModel.setProperty(i, "thumbnailPath", defaultThumbnails[i]);
|
||||
skyboxModel.setProperty(i, "fullSkyboxPath", defaultFulls[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
getSkyboxes();
|
||||
}
|
||||
|
||||
Item {
|
||||
id: titleBarContainer;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors
|
||||
height: childrenRect.height;
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
RalewaySemiBold {
|
||||
anchors.right: parent.right;
|
||||
anchors.topMargin: 20;
|
||||
RalewayBold {
|
||||
id: titleBarText;
|
||||
text: "Skybox Changer";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
anchors.leftMargin: 16;
|
||||
// Style
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 40
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.lightGrayText;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
@ -43,131 +83,61 @@ Rectangle {
|
|||
id: titleBarDesc;
|
||||
text: "Click an image to choose a new Skybox.";
|
||||
wrapMode: Text.Wrap
|
||||
// Text size
|
||||
size: 14;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
anchors.top: titleBarText.bottom
|
||||
anchors.leftMargin: 16;
|
||||
anchors.rightMargin: 16;
|
||||
// Style
|
||||
anchors.top: titleBarText.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 40
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.lightGrayText;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This RowLayout could be a GridLayout instead for further expandability.
|
||||
// As this SkyboxChanger task only required 6 images, implementing GridLayout wasn't necessary.
|
||||
// In the future if this is to be expanded to add more Skyboxes, it might be worth changing this.
|
||||
RowLayout {
|
||||
id: row1
|
||||
GridView {
|
||||
id: gridView
|
||||
interactive: true
|
||||
clip: true
|
||||
anchors.top: titleBarContainer.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 30
|
||||
Layout.fillWidth: true
|
||||
anchors.topMargin: 30
|
||||
spacing: 10
|
||||
Image {
|
||||
width: 200; height: 200
|
||||
fillMode: Image.Stretch
|
||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_1.jpg"
|
||||
clip: true
|
||||
id: preview1
|
||||
MouseArea {
|
||||
anchors.topMargin: 20
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 400
|
||||
anchors.bottom: parent.bottom
|
||||
currentIndex: -1
|
||||
cellWidth: 200
|
||||
cellHeight: 200
|
||||
model: skyboxModel
|
||||
delegate: Item {
|
||||
width: gridView.cellWidth
|
||||
height: gridView.cellHeight
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/1.jpg'});
|
||||
Image {
|
||||
source: thumbnailPath
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
fillMode: Image.Stretch
|
||||
sourceSize.width: parent.width
|
||||
sourceSize.height: parent.height
|
||||
mipmap: true
|
||||
}
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Image {
|
||||
width: 200; height: 200
|
||||
fillMode: Image.Stretch
|
||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_2.jpg"
|
||||
clip: true
|
||||
id: preview2
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/2.png'});
|
||||
sendToScript({method: 'changeSkybox', url: fullSkyboxPath});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
id: row2
|
||||
anchors.top: row1.bottom
|
||||
anchors.topMargin: 10
|
||||
anchors.left: parent.left
|
||||
Layout.fillWidth: true
|
||||
anchors.leftMargin: 30
|
||||
spacing: 10
|
||||
Image {
|
||||
width: 200; height: 200
|
||||
fillMode: Image.Stretch
|
||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_3.jpg"
|
||||
clip: true
|
||||
id: preview3
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/3.jpg'});
|
||||
}
|
||||
}
|
||||
}
|
||||
Image {
|
||||
width: 200; height: 200
|
||||
fillMode: Image.Stretch
|
||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_4.jpg"
|
||||
clip: true
|
||||
id: preview4
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/4.jpg'});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
id: row3
|
||||
anchors.top: row2.bottom
|
||||
anchors.topMargin: 10
|
||||
anchors.left: parent.left
|
||||
Layout.fillWidth: true
|
||||
anchors.leftMargin: 30
|
||||
spacing: 10
|
||||
Image {
|
||||
width: 200; height: 200
|
||||
fillMode: Image.Stretch
|
||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_5.jpg"
|
||||
clip: true
|
||||
id: preview5
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/5.png'});
|
||||
}
|
||||
}
|
||||
}
|
||||
Image {
|
||||
width: 200; height: 200
|
||||
fillMode: Image.Stretch
|
||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_6.jpg"
|
||||
clip: true
|
||||
id: preview6
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/6.jpg'});
|
||||
}
|
||||
}
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
parent: gridView.parent
|
||||
anchors.top: gridView.top
|
||||
anchors.left: gridView.right
|
||||
anchors.bottom: gridView.bottom
|
||||
anchors.leftMargin: 10
|
||||
width: 19
|
||||
}
|
||||
}
|
||||
|
||||
signal sendToScript(var message);
|
||||
|
||||
}
|
||||
}
|
|
@ -14,6 +14,8 @@ import QtQuick.Controls 1.4
|
|||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
Rectangle {
|
||||
readonly property var level: Audio.inputLevel;
|
||||
|
||||
|
@ -57,8 +59,16 @@ Rectangle {
|
|||
|
||||
hoverEnabled: true;
|
||||
scrollGestureEnabled: false;
|
||||
onClicked: { Audio.muted = !Audio.muted; }
|
||||
onClicked: {
|
||||
Audio.muted = !Audio.muted;
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
}
|
||||
drag.target: dragTarget;
|
||||
onContainsMouseChanged: {
|
||||
if (containsMouse) {
|
||||
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
|
|
|
@ -239,6 +239,25 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiCommerceCommon.FirstUseTutorial {
|
||||
id: firstUseTutorial;
|
||||
z: 999;
|
||||
visible: root.activeView === "firstUseTutorial";
|
||||
anchors.fill: parent;
|
||||
|
||||
Connections {
|
||||
onSendSignalToParent: {
|
||||
switch (message.method) {
|
||||
case 'tutorial_skipClicked':
|
||||
case 'tutorial_finished':
|
||||
Settings.setValue("isFirstUseOfPurchases", false);
|
||||
root.activeView = "checkoutSuccess";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -611,6 +630,28 @@ Rectangle {
|
|||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
RalewaySemiBold {
|
||||
id: explainRezText;
|
||||
//visible: !root.isWearable;
|
||||
text: '<font color="' + hifi.colors.redAccent + '"><a href="#">What does "Rez" mean?</a></font>'
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom;
|
||||
anchors.topMargin: 6;
|
||||
height: paintedHeight;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
// Style
|
||||
color: hifi.colors.redAccent;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
onLinkActivated: {
|
||||
root.activeView = "firstUseTutorial";
|
||||
}
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: myPurchasesLink;
|
||||
|
@ -618,7 +659,7 @@ Rectangle {
|
|||
// Text size
|
||||
size: 20;
|
||||
// Anchors
|
||||
anchors.top: noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom;
|
||||
anchors.top: explainRezText.visible ? explainRezText.bottom : (noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom);
|
||||
anchors.topMargin: 40;
|
||||
height: paintedHeight;
|
||||
anchors.left: parent.left;
|
||||
|
|
|
@ -25,7 +25,13 @@ Rectangle {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property int activeView: 1;
|
||||
property int activeView: 1;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
root.activeView = 1;
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.fill: parent;
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
@ -200,12 +200,6 @@ Rectangle {
|
|||
// Style
|
||||
color: hifi.colors.lightGray;
|
||||
}
|
||||
FontLoader { id: ralewayRegular; source: "../../../../fonts/Raleway-Regular.ttf"; }
|
||||
TextMetrics {
|
||||
id: textMetrics;
|
||||
font.family: ralewayRegular.name
|
||||
text: root.itemOwner;
|
||||
}
|
||||
RalewayRegular {
|
||||
id: ownedBy;
|
||||
text: root.itemOwner;
|
||||
|
@ -215,8 +209,7 @@ Rectangle {
|
|||
anchors.top: ownedByHeader.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: ownedByHeader.left;
|
||||
height: textMetrics.height;
|
||||
width: root.isMyCert ? textMetrics.width + 25 : ownedByHeader.width;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.darkGray;
|
||||
elide: Text.ElideRight;
|
||||
|
@ -231,7 +224,7 @@ Rectangle {
|
|||
anchors.topMargin: 4;
|
||||
anchors.bottom: ownedBy.bottom;
|
||||
anchors.left: ownedBy.right;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.leftMargin: 6;
|
||||
anchors.right: ownedByHeader.right;
|
||||
// Style
|
||||
color: hifi.colors.lightGray;
|
||||
|
|
|
@ -241,7 +241,7 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
FirstUseTutorial {
|
||||
HifiCommerceCommon.FirstUseTutorial {
|
||||
id: firstUseTutorial;
|
||||
z: 999;
|
||||
visible: root.activeView === "firstUseTutorial";
|
||||
|
|
|
@ -25,6 +25,7 @@ Item {
|
|||
|
||||
id: root;
|
||||
property string keyFilePath;
|
||||
property bool showDebugButtons: true;
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
@ -56,6 +57,7 @@ Item {
|
|||
}
|
||||
HifiControlsUit.Button {
|
||||
id: clearCachedPassphraseButton;
|
||||
visible: root.showDebugButtons;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
|
@ -71,6 +73,7 @@ Item {
|
|||
}
|
||||
HifiControlsUit.Button {
|
||||
id: resetButton;
|
||||
visible: root.showDebugButtons;
|
||||
color: hifi.buttons.red;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: clearCachedPassphraseButton.top;
|
||||
|
@ -90,17 +93,22 @@ Item {
|
|||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "What are private keys?"
|
||||
answer: qsTr("A private key is a secret piece of text that is used to decrypt code.<br><br>In High Fidelity, <b>your private keys are used to decrypt the contents of your Wallet and Purchases.</b>");
|
||||
answer: qsTr("A private key is a secret piece of text that is used to prove ownership, unlock confidential information, and sign transactions.<br><br>In High Fidelity, <b>your private keys are used to securely access the contents of your Wallet and Purchases.</b>");
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "Where are my private keys stored?"
|
||||
answer: qsTr('Your private keys are <b>only stored on your hard drive</b> in High Fidelity Interface\'s AppData directory.<br><br><b><font color="#0093C5"><a href="#privateKeyPath">Tap here to open the file path of your hifikey in your file explorer.</a></font></b><br><br> You may backup this file by copying it to a USB flash drive, or to a service like Dropbox or Google Drive. Restore your backup by replacing the file in Interface\'s AppData directory with your backed-up copy.');
|
||||
answer: qsTr('By default, your private keys are <b>only stored on your hard drive</b> in High Fidelity Interface\'s AppData directory.<br><br><b><font color="#0093C5"><a href="#privateKeyPath">Tap here to open the folder where your HifiKeys are stored on your main display.</a></font></b>');
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "How can I backup my private keys?"
|
||||
answer: qsTr('You may backup the file containing your private keys by copying it to a USB flash drive, or to a service like Dropbox or Google Drive.<br><br>Restore your backup by replacing the file in Interface\'s AppData directory with your backed-up copy.<br><br><b><font color="#0093C5"><a href="#privateKeyPath">Tap here to open the folder where your HifiKeys are stored on your main display.</a></font></b>');
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "What happens if I lose my passphrase?"
|
||||
answer: qsTr("If you lose your passphrase, you will no longer have access to the contents of your Wallet or My Purchases.<br><br><b>Nobody can help you recover your passphrase, including High Fidelity.</b> Please write it down and store it securely.");
|
||||
answer: qsTr("Your passphrase is used to encrypt your private keys. If you lose your passphrase, you will no longer be able to decrypt your private key file. You will also no longer have access to the contents of your Wallet or My Purchases.<br><br><b>Nobody can help you recover your passphrase, including High Fidelity.</b> Please write it down and store it securely.");
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
|
|
|
@ -25,7 +25,7 @@ Item {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
z: 998;
|
||||
z: 997;
|
||||
property bool keyboardRaised: false;
|
||||
property string titleBarIcon: "";
|
||||
property string titleBarText: "";
|
||||
|
@ -350,7 +350,7 @@ Item {
|
|||
|
||||
Item {
|
||||
id: keyboardContainer;
|
||||
z: 999;
|
||||
z: 998;
|
||||
visible: keyboard.raised;
|
||||
property bool punctuationMode: false;
|
||||
anchors {
|
||||
|
@ -361,11 +361,13 @@ Item {
|
|||
|
||||
Image {
|
||||
id: lowerKeyboardButton;
|
||||
z: 999;
|
||||
source: "images/lowerKeyboard.png";
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.bottom: keyboard.top;
|
||||
height: 30;
|
||||
width: 120;
|
||||
anchors.right: keyboard.right;
|
||||
anchors.top: keyboard.showMirrorText ? keyboard.top : undefined;
|
||||
anchors.bottom: keyboard.showMirrorText ? undefined : keyboard.bottom;
|
||||
height: 50;
|
||||
width: 60;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
|
|
|
@ -290,7 +290,17 @@ Item {
|
|||
id: removeHmdContainer;
|
||||
z: 998;
|
||||
visible: false;
|
||||
color: hifi.colors.blueHighlight;
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.2;
|
||||
color: hifi.colors.baseGrayHighlight;
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0;
|
||||
color: hifi.colors.baseGrayShadow;
|
||||
}
|
||||
}
|
||||
anchors.fill: backupInstructionsButton;
|
||||
radius: 5;
|
||||
MouseArea {
|
||||
|
|
|
@ -165,7 +165,7 @@ Rectangle {
|
|||
WalletSetup {
|
||||
id: walletSetup;
|
||||
visible: root.activeView === "walletSetup";
|
||||
z: 998;
|
||||
z: 997;
|
||||
anchors.fill: parent;
|
||||
|
||||
Connections {
|
||||
|
@ -192,7 +192,7 @@ Rectangle {
|
|||
PassphraseChange {
|
||||
id: passphraseChange;
|
||||
visible: root.activeView === "passphraseChange";
|
||||
z: 998;
|
||||
z: 997;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
@ -217,7 +217,7 @@ Rectangle {
|
|||
SecurityImageChange {
|
||||
id: securityImageChange;
|
||||
visible: root.activeView === "securityImageChange";
|
||||
z: 998;
|
||||
z: 997;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
@ -653,7 +653,7 @@ Rectangle {
|
|||
|
||||
Item {
|
||||
id: keyboardContainer;
|
||||
z: 999;
|
||||
z: 998;
|
||||
visible: keyboard.raised;
|
||||
property bool punctuationMode: false;
|
||||
anchors {
|
||||
|
@ -664,11 +664,13 @@ Rectangle {
|
|||
|
||||
Image {
|
||||
id: lowerKeyboardButton;
|
||||
z: 999;
|
||||
source: "images/lowerKeyboard.png";
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.bottom: keyboard.top;
|
||||
height: 30;
|
||||
width: 120;
|
||||
anchors.right: keyboard.right;
|
||||
anchors.top: keyboard.showMirrorText ? keyboard.top : undefined;
|
||||
anchors.bottom: keyboard.showMirrorText ? undefined : keyboard.bottom;
|
||||
height: 50;
|
||||
width: 60;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
|
|
|
@ -164,7 +164,7 @@ Item {
|
|||
anchors.top: parent.top;
|
||||
anchors.topMargin: 26;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: 30;
|
||||
|
|
|
@ -679,7 +679,7 @@ Item {
|
|||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: 40;
|
||||
text: "Open Instructions for Later";
|
||||
text: "Open Backup Instructions for Later";
|
||||
onClicked: {
|
||||
instructions01Container.visible = false;
|
||||
instructions02Container.visible = true;
|
||||
|
|
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 1.2 KiB |
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.0
|
||||
import QtGraphicalEffects 1.0
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
Item {
|
||||
id: newEntityButton
|
||||
|
@ -122,9 +123,11 @@ Item {
|
|||
hoverEnabled: true
|
||||
enabled: true
|
||||
onClicked: {
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
newEntityButton.clicked();
|
||||
}
|
||||
onEntered: {
|
||||
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
newEntityButton.state = "hover state";
|
||||
}
|
||||
onExited: {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.0
|
||||
import QtGraphicalEffects 1.0
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
Item {
|
||||
id: tabletButton
|
||||
|
@ -130,11 +131,13 @@ Item {
|
|||
}
|
||||
tabletButton.clicked();
|
||||
if (tabletRoot) {
|
||||
tabletRoot.playButtonClickSound();
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
}
|
||||
}
|
||||
onEntered: {
|
||||
tabletButton.isEntered = true;
|
||||
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
|
||||
if (tabletButton.isActive) {
|
||||
tabletButton.state = "hover active state";
|
||||
} else {
|
||||
|
|
|
@ -9,9 +9,13 @@
|
|||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
import "../../styles-uit"
|
||||
import "."
|
||||
|
||||
FocusScope {
|
||||
id: root
|
||||
implicitHeight: background.height
|
||||
|
@ -69,12 +73,17 @@ FocusScope {
|
|||
onImplicitWidthChanged: listView !== null ? listView.recalcSize() : 0
|
||||
|
||||
MouseArea {
|
||||
enabled: name !== "" && item.enabled
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: listView.currentIndex = index
|
||||
onEntered: {
|
||||
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||
listView.currentIndex = index
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
root.selected(item)
|
||||
tabletRoot.playButtonClickSound();
|
||||
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||
root.selected(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import QtQuick 2.0
|
||||
import Hifi 1.0
|
||||
import QtQuick.Controls 1.4
|
||||
|
||||
import "../../dialogs"
|
||||
import "../../controls"
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ Window {
|
|||
|
||||
sortButtons();
|
||||
|
||||
shown = true;
|
||||
fadeIn(null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ Window {
|
|||
buttons.splice(index, 1);
|
||||
|
||||
if (buttons.length === 0) {
|
||||
shown = false;
|
||||
fadeOut(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ FocusScope {
|
|||
property var completionCallback;
|
||||
// The target property to animate, usually scale or opacity
|
||||
property alias fadeTargetProperty: root.opacity
|
||||
property bool disableFade: false
|
||||
// always start the property at 0 to enable fade in on creation
|
||||
fadeTargetProperty: 0
|
||||
// DO NOT set visible to false or when derived types override it it
|
||||
|
|
BIN
interface/resources/sounds/Button01.wav
Normal file
BIN
interface/resources/sounds/Button02.wav
Normal file
BIN
interface/resources/sounds/Button03.wav
Normal file
BIN
interface/resources/sounds/Button04.wav
Normal file
BIN
interface/resources/sounds/Button05.wav
Normal file
BIN
interface/resources/sounds/Button06.wav
Normal file
BIN
interface/resources/sounds/Button07.wav
Normal file
BIN
interface/resources/sounds/Collapse.wav
Normal file
BIN
interface/resources/sounds/Expand.wav
Normal file
BIN
interface/resources/sounds/Tab01.wav
Normal file
BIN
interface/resources/sounds/Tab02.wav
Normal file
BIN
interface/resources/sounds/Tab03.wav
Normal file
|
@ -1860,6 +1860,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
DependencyManager::get<PickManager>()->setPrecisionPicking(rayPickID, value);
|
||||
});
|
||||
|
||||
// Preload Tablet sounds
|
||||
DependencyManager::get<TabletScriptingInterface>()->preloadSounds();
|
||||
|
||||
qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID());
|
||||
}
|
||||
|
||||
|
@ -2268,7 +2271,7 @@ void Application::initializeUi() {
|
|||
offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
|
||||
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
|
||||
// support the window management and scripting proxies for VR use
|
||||
offscreenUi->createDesktop(QString("hifi/Desktop.qml"));
|
||||
offscreenUi->createDesktop(QString("qrc:///qml/hifi/Desktop.qml"));
|
||||
|
||||
// FIXME either expose so that dialogs can set this themselves or
|
||||
// do better detection in the offscreen UI of what has focus
|
||||
|
@ -2337,6 +2340,8 @@ void Application::initializeUi() {
|
|||
|
||||
surfaceContext->setContextProperty("Account", AccountScriptingInterface::getInstance());
|
||||
surfaceContext->setContextProperty("Tablet", DependencyManager::get<TabletScriptingInterface>().data());
|
||||
// Tablet inteference with Tablet.qml. Need to avoid this in QML space
|
||||
surfaceContext->setContextProperty("tabletInterface", DependencyManager::get<TabletScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface);
|
||||
surfaceContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance());
|
||||
surfaceContext->setContextProperty("FaceTracker", DependencyManager::get<DdeFaceTracker>().data());
|
||||
|
@ -2405,8 +2410,8 @@ void Application::initializeUi() {
|
|||
}
|
||||
|
||||
void Application::updateCamera(RenderArgs& renderArgs) {
|
||||
PROFILE_RANGE(render, "/updateCamera");
|
||||
PerformanceTimer perfTimer("CameraUpdates");
|
||||
PROFILE_RANGE(render, __FUNCTION__);
|
||||
PerformanceTimer perfTimer("updateCamera");
|
||||
|
||||
glm::vec3 boomOffset;
|
||||
auto myAvatar = getMyAvatar();
|
||||
|
@ -2622,7 +2627,7 @@ void Application::resizeGL() {
|
|||
}
|
||||
|
||||
void Application::handleSandboxStatus(QNetworkReply* reply) {
|
||||
PROFILE_RANGE(render, "HandleSandboxStatus");
|
||||
PROFILE_RANGE(render, __FUNCTION__);
|
||||
|
||||
bool sandboxIsRunning = SandboxUtils::readStatus(reply->readAll());
|
||||
qDebug() << "HandleSandboxStatus" << sandboxIsRunning;
|
||||
|
@ -4651,7 +4656,6 @@ void Application::updateDialogs(float deltaTime) const {
|
|||
static bool domainLoadingInProgress = false;
|
||||
|
||||
void Application::update(float deltaTime) {
|
||||
|
||||
PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_renderFrameCount + 1);
|
||||
|
||||
if (!_physicsEnabled) {
|
||||
|
@ -4846,11 +4850,11 @@ void Application::update(float deltaTime) {
|
|||
QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>();
|
||||
|
||||
{
|
||||
PROFILE_RANGE_EX(simulation_physics, "Physics", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||
PROFILE_RANGE(simulation_physics, "Physics");
|
||||
PerformanceTimer perfTimer("physics");
|
||||
if (_physicsEnabled) {
|
||||
{
|
||||
PROFILE_RANGE_EX(simulation_physics, "UpdateStates", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||
PROFILE_RANGE(simulation_physics, "PreStep");
|
||||
|
||||
PerformanceTimer perfTimer("updateStates)");
|
||||
static VectorOfMotionStates motionStates;
|
||||
|
@ -4884,14 +4888,14 @@ void Application::update(float deltaTime) {
|
|||
});
|
||||
}
|
||||
{
|
||||
PROFILE_RANGE_EX(simulation_physics, "StepSimulation", 0xffff8000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||
PROFILE_RANGE(simulation_physics, "Step");
|
||||
PerformanceTimer perfTimer("stepSimulation");
|
||||
getEntities()->getTree()->withWriteLock([&] {
|
||||
_physicsEngine->stepSimulation();
|
||||
});
|
||||
}
|
||||
{
|
||||
PROFILE_RANGE_EX(simulation_physics, "HarvestChanges", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||
PROFILE_RANGE(simulation_physics, "PostStep");
|
||||
PerformanceTimer perfTimer("harvestChanges");
|
||||
if (_physicsEngine->hasOutgoingChanges()) {
|
||||
// grab the collision events BEFORE handleOutgoingChanges() because at this point
|
||||
|
@ -4899,6 +4903,7 @@ void Application::update(float deltaTime) {
|
|||
auto& collisionEvents = _physicsEngine->getCollisionEvents();
|
||||
|
||||
getEntities()->getTree()->withWriteLock([&] {
|
||||
PROFILE_RANGE(simulation_physics, "Harvest");
|
||||
PerformanceTimer perfTimer("handleOutgoingChanges");
|
||||
|
||||
const VectorOfMotionStates& outgoingChanges = _physicsEngine->getChangedMotionStates();
|
||||
|
@ -4911,18 +4916,25 @@ void Application::update(float deltaTime) {
|
|||
|
||||
if (!_aboutToQuit) {
|
||||
// handleCollisionEvents() AFTER handleOutgoinChanges()
|
||||
PerformanceTimer perfTimer("entities");
|
||||
avatarManager->handleCollisionEvents(collisionEvents);
|
||||
// Collision events (and their scripts) must not be handled when we're locked, above. (That would risk
|
||||
// deadlock.)
|
||||
_entitySimulation->handleCollisionEvents(collisionEvents);
|
||||
{
|
||||
PROFILE_RANGE(simulation_physics, "CollisionEvents");
|
||||
PerformanceTimer perfTimer("entities");
|
||||
avatarManager->handleCollisionEvents(collisionEvents);
|
||||
// Collision events (and their scripts) must not be handled when we're locked, above. (That would risk
|
||||
// deadlock.)
|
||||
_entitySimulation->handleCollisionEvents(collisionEvents);
|
||||
}
|
||||
|
||||
PROFILE_RANGE(simulation_physics, "UpdateEntities");
|
||||
// NOTE: the getEntities()->update() call below will wait for lock
|
||||
// and will simulate entity motion (the EntityTree has been given an EntitySimulation).
|
||||
getEntities()->update(true); // update the models...
|
||||
}
|
||||
|
||||
myAvatar->harvestResultsFromPhysicsSimulation(deltaTime);
|
||||
{
|
||||
PROFILE_RANGE(simulation_physics, "MyAvatar");
|
||||
myAvatar->harvestResultsFromPhysicsSimulation(deltaTime);
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails) &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::ExpandPhysicsSimulationTiming)) {
|
||||
|
@ -4941,13 +4953,13 @@ void Application::update(float deltaTime) {
|
|||
// AvatarManager update
|
||||
{
|
||||
{
|
||||
PROFILE_RANGE(simulation, "OtherAvatars");
|
||||
PerformanceTimer perfTimer("otherAvatars");
|
||||
PROFILE_RANGE_EX(simulation, "OtherAvatars", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||
avatarManager->updateOtherAvatars(deltaTime);
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE_EX(simulation, "MyAvatar", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||
PROFILE_RANGE(simulation, "MyAvatar");
|
||||
PerformanceTimer perfTimer("MyAvatar");
|
||||
qApp->updateMyAvatarLookAtPosition();
|
||||
avatarManager->updateMyAvatar(deltaTime);
|
||||
|
@ -5091,6 +5103,7 @@ void Application::update(float deltaTime) {
|
|||
}
|
||||
|
||||
this->updateCamera(appRenderArgs._renderArgs);
|
||||
appRenderArgs._eyeToWorld = _myCamera.getTransform();
|
||||
appRenderArgs._isStereo = false;
|
||||
|
||||
{
|
||||
|
@ -5818,6 +5831,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
|||
qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue<TabletProxy>, wrapperFromScriptValue<TabletProxy>);
|
||||
qScriptRegisterMetaType(scriptEngine.data(),
|
||||
wrapperToScriptValue<TabletButtonProxy>, wrapperFromScriptValue<TabletButtonProxy>);
|
||||
// Tablet inteference with Tablet.qml. Need to avoid this in QML space
|
||||
scriptEngine->registerGlobalObject("tabletInterface", DependencyManager::get<TabletScriptingInterface>().data());
|
||||
scriptEngine->registerGlobalObject("Tablet", DependencyManager::get<TabletScriptingInterface>().data());
|
||||
|
||||
auto toolbarScriptingInterface = DependencyManager::get<ToolbarScriptingInterface>().data();
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <QUuid>
|
||||
|
||||
#include <SettingHandle.h>
|
||||
#include <Rig.h>
|
||||
#include <Sound.h>
|
||||
|
@ -106,6 +108,8 @@ class MyAvatar : public Avatar {
|
|||
* "scripts/system/controllers/toggleAdvancedMovementForHandControllers.js".
|
||||
* @property userHeight {number} The height of the user in sensor space. (meters).
|
||||
* @property userEyeHeight {number} Estimated height of the users eyes in sensor space. (meters)
|
||||
* @property SELF_ID {string} READ-ONLY. UUID representing "my avatar". Only use for local-only entities and overlays in situations where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain).
|
||||
* Note: Likely to be deprecated.
|
||||
*/
|
||||
|
||||
// FIXME: `glm::vec3 position` is not accessible from QML, so this exposes position in a QML-native type
|
||||
|
@ -152,6 +156,8 @@ class MyAvatar : public Avatar {
|
|||
|
||||
Q_PROPERTY(float userHeight READ getUserHeight WRITE setUserHeight)
|
||||
Q_PROPERTY(float userEyeHeight READ getUserEyeHeight)
|
||||
|
||||
Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT)
|
||||
|
||||
const QString DOMINANT_LEFT_HAND = "left";
|
||||
const QString DOMINANT_RIGHT_HAND = "right";
|
||||
|
@ -546,6 +552,8 @@ public:
|
|||
|
||||
virtual SpatialParentTree* getParentTree() const override;
|
||||
|
||||
const QUuid& getSelfID() const { return AVATAR_SELF_ID; }
|
||||
|
||||
public slots:
|
||||
void increaseSize();
|
||||
void decreaseSize();
|
||||
|
@ -648,8 +656,6 @@ private:
|
|||
|
||||
void setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visiblity);
|
||||
|
||||
private:
|
||||
|
||||
virtual void updatePalms() override {}
|
||||
void lateUpdatePalms();
|
||||
|
||||
|
|
|
@ -105,19 +105,19 @@ RSA* readKeys(const char* filename) {
|
|||
return key;
|
||||
}
|
||||
|
||||
bool writeBackupInstructions() {
|
||||
bool Wallet::writeBackupInstructions() {
|
||||
QString inputFilename(PathUtils::resourcesPath() + "html/commerce/backup_instructions.html");
|
||||
QString filename = PathUtils::getAppDataFilePath(INSTRUCTIONS_FILE);
|
||||
QFile outputFile(filename);
|
||||
QString outputFilename = PathUtils::getAppDataFilePath(INSTRUCTIONS_FILE);
|
||||
QFile outputFile(outputFilename);
|
||||
bool retval = false;
|
||||
|
||||
if (QFile::exists(filename))
|
||||
if (QFile::exists(outputFilename) || getKeyFilePath() == "")
|
||||
{
|
||||
QFile::remove(filename);
|
||||
return false;
|
||||
}
|
||||
QFile::copy(inputFilename, filename);
|
||||
QFile::copy(inputFilename, outputFilename);
|
||||
|
||||
if (QFile::exists(filename) && outputFile.open(QIODevice::ReadWrite)) {
|
||||
if (QFile::exists(outputFilename) && outputFile.open(QIODevice::ReadWrite)) {
|
||||
|
||||
QByteArray fileData = outputFile.readAll();
|
||||
QString text(fileData);
|
||||
|
@ -132,7 +132,7 @@ bool writeBackupInstructions() {
|
|||
retval = true;
|
||||
qCDebug(commerce) << "wrote html file successfully";
|
||||
} else {
|
||||
qCDebug(commerce) << "failed to open output html file" << filename;
|
||||
qCDebug(commerce) << "failed to open output html file" << outputFilename;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
@ -154,8 +154,6 @@ bool writeKeys(const char* filename, RSA* keys) {
|
|||
QFile(QString(filename)).remove();
|
||||
return retval;
|
||||
}
|
||||
|
||||
writeBackupInstructions();
|
||||
|
||||
retval = true;
|
||||
qCDebug(commerce) << "wrote keys successfully";
|
||||
|
@ -359,6 +357,8 @@ bool Wallet::setPassphrase(const QString& passphrase) {
|
|||
|
||||
_publicKeys.clear();
|
||||
|
||||
writeBackupInstructions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -526,6 +526,8 @@ bool Wallet::generateKeyPair() {
|
|||
qCInfo(commerce) << "Generating keypair.";
|
||||
auto keyPair = generateRSAKeypair();
|
||||
|
||||
writeBackupInstructions();
|
||||
|
||||
// TODO: redo this soon -- need error checking and so on
|
||||
writeSecurityImage(_securityImage, keyFilePath());
|
||||
QString oldKey = _publicKeys.count() == 0 ? "" : _publicKeys.last();
|
||||
|
|
|
@ -80,6 +80,7 @@ private:
|
|||
void updateImageProvider();
|
||||
bool writeSecurityImage(const QPixmap* pixmap, const QString& outputFilePath);
|
||||
bool readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen);
|
||||
bool writeBackupInstructions();
|
||||
|
||||
bool verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// interface/src/ui/overlays
|
||||
//
|
||||
// Created by Zander Otavka on 8/7/15.
|
||||
// Modified by Daniela Fontes on 24/10/17.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
|
@ -13,6 +14,7 @@
|
|||
|
||||
#include <Application.h>
|
||||
#include <Transform.h>
|
||||
#include "avatar/AvatarManager.h"
|
||||
|
||||
void Billboardable::setProperties(const QVariantMap& properties) {
|
||||
auto isFacingAvatar = properties["isFacingAvatar"];
|
||||
|
@ -32,10 +34,11 @@ bool Billboardable::pointTransformAtCamera(Transform& transform, glm::quat offse
|
|||
if (isFacingAvatar()) {
|
||||
glm::vec3 billboardPos = transform.getTranslation();
|
||||
glm::vec3 cameraPos = qApp->getCamera().getPosition();
|
||||
glm::vec3 look = cameraPos - billboardPos;
|
||||
float elevation = -asinf(look.y / glm::length(look));
|
||||
float azimuth = atan2f(look.x, look.z);
|
||||
glm::quat rotation(glm::vec3(elevation, azimuth, 0));
|
||||
// use the referencial from the avatar, y isn't always up
|
||||
glm::vec3 avatarUP = DependencyManager::get<AvatarManager>()->getMyAvatar()->getOrientation()*Vectors::UP;
|
||||
|
||||
glm::quat rotation(conjugate(toQuat(glm::lookAt(billboardPos, cameraPos, avatarUP))));
|
||||
|
||||
transform.setRotation(rotation);
|
||||
transform.postRotate(offsetRotation);
|
||||
return true;
|
||||
|
|
|
@ -51,13 +51,11 @@ void Image3DOverlay::update(float deltatime) {
|
|||
_texture = DependencyManager::get<TextureCache>()->getTexture(_url);
|
||||
_textureIsLoaded = false;
|
||||
}
|
||||
#if OVERLAY_PANELS
|
||||
if (usecTimestampNow() > _transformExpiry) {
|
||||
Transform transform = getTransform();
|
||||
applyTransformTo(transform);
|
||||
setTransform(transform);
|
||||
}
|
||||
#endif
|
||||
Parent::update(deltatime);
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ void Line3DOverlay::setEnd(const glm::vec3& end) {
|
|||
} else {
|
||||
_direction = glm::vec3(0.0f);
|
||||
}
|
||||
notifyRenderTransformChange();
|
||||
}
|
||||
|
||||
void Line3DOverlay::setLocalEnd(const glm::vec3& localEnd) {
|
||||
|
|
|
@ -257,7 +257,3 @@ bool Text3DOverlay::findRayIntersection(const glm::vec3 &origin, const glm::vec3
|
|||
return Billboard3DOverlay::findRayIntersection(origin, direction, distance, face, surfaceNormal);
|
||||
}
|
||||
|
||||
Transform Text3DOverlay::evalRenderTransform() {
|
||||
return Parent::evalRenderTransform();
|
||||
}
|
||||
|
||||
|
|
|
@ -65,9 +65,6 @@ public:
|
|||
|
||||
virtual Text3DOverlay* createClone() const override;
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
|
||||
private:
|
||||
TextRenderer3D* _textRenderer = nullptr;
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ static const float OPAQUE_ALPHA_THRESHOLD = 0.99f;
|
|||
|
||||
const QString Web3DOverlay::TYPE = "web3d";
|
||||
const QString Web3DOverlay::QML = "Web3DOverlay.qml";
|
||||
|
||||
Web3DOverlay::Web3DOverlay() : _dpi(DPI) {
|
||||
_touchDevice.setCapabilities(QTouchDevice::Position);
|
||||
_touchDevice.setType(QTouchDevice::TouchScreen);
|
||||
|
@ -248,6 +247,9 @@ void Web3DOverlay::setupQmlSurface() {
|
|||
|
||||
_webSurface->getSurfaceContext()->setContextProperty("pathToFonts", "../../");
|
||||
|
||||
// Tablet inteference with Tablet.qml. Need to avoid this in QML space
|
||||
_webSurface->getSurfaceContext()->setContextProperty("tabletInterface", DependencyManager::get<TabletScriptingInterface>().data());
|
||||
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface.data());
|
||||
// mark the TabletProxy object as cpp ownership.
|
||||
QObject* tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system");
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "AnimUtil.h"
|
||||
#include "IKTarget.h"
|
||||
|
||||
|
||||
static int nextRigId = 1;
|
||||
static std::map<int, Rig*> rigRegistry;
|
||||
static std::mutex rigRegistryMutex;
|
||||
|
@ -999,14 +1000,13 @@ void Rig::updateAnimationStateHandlers() { // called on avatar update thread (wh
|
|||
}
|
||||
|
||||
void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, const glm::mat4& rigToWorldTransform) {
|
||||
|
||||
PROFILE_RANGE_EX(simulation_animation_detail, __FUNCTION__, 0xffff00ff, 0);
|
||||
PerformanceTimer perfTimer("updateAnimations");
|
||||
DETAILED_PROFILE_RANGE_EX(simulation_animation_detail, __FUNCTION__, 0xffff00ff, 0);
|
||||
DETAILED_PERFORMANCE_TIMER("updateAnimations");
|
||||
|
||||
setModelOffset(rootTransform);
|
||||
|
||||
if (_animNode && _enabledAnimations) {
|
||||
PerformanceTimer perfTimer("handleTriggers");
|
||||
DETAILED_PERFORMANCE_TIMER("handleTriggers");
|
||||
|
||||
updateAnimationStateHandlers();
|
||||
_animVars.setRigToGeometryTransform(_rigToGeometryTransform);
|
||||
|
@ -1658,7 +1658,7 @@ bool Rig::getModelRegistrationPoint(glm::vec3& modelRegistrationPointOut) const
|
|||
}
|
||||
|
||||
void Rig::applyOverridePoses() {
|
||||
PerformanceTimer perfTimer("override");
|
||||
DETAILED_PERFORMANCE_TIMER("override");
|
||||
if (_numOverrides == 0 || !_animSkeleton) {
|
||||
return;
|
||||
}
|
||||
|
@ -1675,7 +1675,7 @@ void Rig::applyOverridePoses() {
|
|||
}
|
||||
|
||||
void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) {
|
||||
PerformanceTimer perfTimer("buildAbsolute");
|
||||
DETAILED_PERFORMANCE_TIMER("buildAbsolute");
|
||||
if (!_animSkeleton) {
|
||||
return;
|
||||
}
|
||||
|
@ -1730,8 +1730,9 @@ void Rig::copyJointsIntoJointData(QVector<JointData>& jointDataVec) const {
|
|||
}
|
||||
|
||||
void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
|
||||
PerformanceTimer perfTimer("copyJoints");
|
||||
PROFILE_RANGE(simulation_animation_detail, "copyJoints");
|
||||
DETAILED_PROFILE_RANGE(simulation_animation_detail, "copyJoints");
|
||||
DETAILED_PERFORMANCE_TIMER("copyJoints");
|
||||
|
||||
if (!_animSkeleton) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -994,10 +994,12 @@ glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const {
|
|||
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
|
||||
return glmExtractRotation(finalMat);
|
||||
}
|
||||
case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX:
|
||||
case CONTROLLER_LEFTHAND_INDEX: {
|
||||
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
|
||||
return controllerLeftHandTransform.getRotation();
|
||||
}
|
||||
case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX:
|
||||
case CONTROLLER_RIGHTHAND_INDEX: {
|
||||
Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix());
|
||||
return controllerRightHandTransform.getRotation();
|
||||
|
@ -1032,10 +1034,12 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const {
|
|||
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
|
||||
return extractTranslation(finalMat);
|
||||
}
|
||||
case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX:
|
||||
case CONTROLLER_LEFTHAND_INDEX: {
|
||||
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
|
||||
return controllerLeftHandTransform.getTranslation();
|
||||
}
|
||||
case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX:
|
||||
case CONTROLLER_RIGHTHAND_INDEX: {
|
||||
Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix());
|
||||
return controllerRightHandTransform.getTranslation();
|
||||
|
|
|
@ -377,7 +377,8 @@ void FBXBaker::rewriteAndBakeSceneModels() {
|
|||
bool hasColors { mesh.colors.size() > 0 };
|
||||
bool hasTexCoords { mesh.texCoords.size() > 0 };
|
||||
bool hasTexCoords1 { mesh.texCoords1.size() > 0 };
|
||||
bool hasPerFaceMaterials { mesh.parts.size() > 1 };
|
||||
bool hasPerFaceMaterials { mesh.parts.size() > 1
|
||||
|| extractedMesh.partMaterialTextures[0].first != 0 };
|
||||
bool needsOriginalIndices { hasDeformers };
|
||||
|
||||
int normalsAttributeID { -1 };
|
||||
|
@ -594,6 +595,10 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
|
|||
QString fbxTextureFileName { textureChild.properties.at(0).toByteArray() };
|
||||
QFileInfo textureFileInfo { fbxTextureFileName.replace("\\", "/") };
|
||||
|
||||
if (hasErrors()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (textureFileInfo.suffix() == BAKED_TEXTURE_EXT.mid(1)) {
|
||||
// re-baking an FBX that already references baked textures is a fail
|
||||
// so we add an error and return from here
|
||||
|
@ -602,6 +607,11 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!TextureBaker::getSupportedFormats().contains(textureFileInfo.suffix())) {
|
||||
// this is a texture format we don't bake, skip it
|
||||
handleWarning(fbxTextureFileName + " is not a bakeable texture format");
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure this texture points to something and isn't one we've already re-mapped
|
||||
if (!textureFileInfo.filePath().isEmpty()) {
|
||||
|
|
|
@ -160,6 +160,8 @@ void EntityTreeRenderer::shutdown() {
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||
PROFILE_RANGE_EX(simulation_physics, "Add", 0xffff00ff, (uint64_t)_entitiesToAdd.size());
|
||||
PerformanceTimer pt("add");
|
||||
// Clear any expired entities
|
||||
// FIXME should be able to use std::remove_if, but it fails due to some
|
||||
// weird compilation error related to EntityItemID assignment operators
|
||||
|
@ -203,6 +205,8 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||
PROFILE_RANGE_EX(simulation_physics, "Change", 0xffff00ff, (uint64_t)_changedEntities.size());
|
||||
PerformanceTimer pt("change");
|
||||
std::unordered_set<EntityItemID> changedEntities;
|
||||
_changedEntitiesGuard.withWriteLock([&] {
|
||||
#if 0
|
||||
|
@ -223,6 +227,7 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
|
|||
}
|
||||
|
||||
if (!_renderablesToUpdate.empty()) {
|
||||
PROFILE_RANGE_EX(simulation_physics, "UpdateRenderables", 0xffff00ff, (uint64_t)_renderablesToUpdate.size());
|
||||
for (const auto& entry : _renderablesToUpdate) {
|
||||
const auto& renderable = entry.second;
|
||||
renderable->updateInScene(scene, transaction);
|
||||
|
@ -232,6 +237,7 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::update(bool simulate) {
|
||||
PROFILE_RANGE(simulation_physics, "ETR::update");
|
||||
PerformanceTimer perfTimer("ETRupdate");
|
||||
if (_tree && !_shuttingDown) {
|
||||
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
||||
|
@ -239,22 +245,14 @@ void EntityTreeRenderer::update(bool simulate) {
|
|||
|
||||
// Update the rendereable entities as needed
|
||||
{
|
||||
PROFILE_RANGE(simulation_physics, "Scene");
|
||||
PerformanceTimer sceneTimer("scene");
|
||||
auto scene = _viewState->getMain3DScene();
|
||||
if (scene) {
|
||||
render::Transaction transaction;
|
||||
{
|
||||
PerformanceTimer pt("add");
|
||||
addPendingEntities(scene, transaction);
|
||||
}
|
||||
{
|
||||
PerformanceTimer pt("change");
|
||||
updateChangedEntities(scene, transaction);
|
||||
}
|
||||
{
|
||||
PerformanceTimer pt("enqueue");
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
addPendingEntities(scene, transaction);
|
||||
updateChangedEntities(scene, transaction);
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,7 +334,8 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityIt
|
|||
}
|
||||
|
||||
bool EntityTreeRenderer::checkEnterLeaveEntities() {
|
||||
PerformanceTimer perfTimer("checkEnterLeaveEntities");
|
||||
PROFILE_RANGE(simulation_physics, "EnterLeave");
|
||||
PerformanceTimer perfTimer("enterLeave");
|
||||
auto now = usecTimestampNow();
|
||||
bool didUpdate = false;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "RenderableWebEntityItem.h"
|
||||
#include "RenderableZoneEntityItem.h"
|
||||
|
||||
|
||||
using namespace render;
|
||||
using namespace render::entities;
|
||||
|
||||
|
@ -49,7 +50,9 @@ void EntityRenderer::initEntityRenderers() {
|
|||
REGISTER_ENTITY_TYPE_WITH_FACTORY(PolyVox, RenderablePolyVoxEntityItem::factory)
|
||||
}
|
||||
|
||||
|
||||
const Transform& EntityRenderer::getModelTransform() const {
|
||||
return _modelTransform;
|
||||
}
|
||||
|
||||
void EntityRenderer::makeStatusGetters(const EntityItemPointer& entity, Item::Status::Getters& statusGetters) {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
@ -271,6 +274,7 @@ void EntityRenderer::removeFromScene(const ScenePointer& scene, Transaction& tra
|
|||
}
|
||||
|
||||
void EntityRenderer::updateInScene(const ScenePointer& scene, Transaction& transaction) {
|
||||
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
|
||||
if (!isValidRenderItem()) {
|
||||
return;
|
||||
}
|
||||
|
@ -330,6 +334,7 @@ bool EntityRenderer::needsRenderUpdateFromEntity(const EntityItemPointer& entity
|
|||
}
|
||||
|
||||
void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) {
|
||||
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
|
||||
withWriteLock([&] {
|
||||
auto transparent = isTransparent();
|
||||
if (_prevIsTransparent && !transparent) {
|
||||
|
|
|
@ -105,8 +105,10 @@ protected:
|
|||
template<typename T>
|
||||
std::shared_ptr<T> asTypedEntity() { return std::static_pointer_cast<T>(_entity); }
|
||||
|
||||
|
||||
static void makeStatusGetters(const EntityItemPointer& entity, Item::Status::Getters& statusGetters);
|
||||
static std::function<bool()> _entitiesShouldFadeFunction;
|
||||
const Transform& getModelTransform() const;
|
||||
|
||||
SharedSoundPointer _collisionSound;
|
||||
QUuid _changeHandlerId;
|
||||
|
@ -114,7 +116,6 @@ protected:
|
|||
quint64 _fadeStartTime{ usecTimestampNow() };
|
||||
bool _isFading{ _entitiesShouldFadeFunction() };
|
||||
bool _prevIsTransparent { false };
|
||||
Transform _modelTransform;
|
||||
Item::Bound _bound;
|
||||
bool _visible { false };
|
||||
bool _moving { false };
|
||||
|
@ -123,6 +124,10 @@ protected:
|
|||
|
||||
|
||||
private:
|
||||
// The base class relies on comparing the model transform to the entity transform in order
|
||||
// to trigger an update, so the member must not be visible to derived classes as a modifiable
|
||||
// transform
|
||||
Transform _modelTransform;
|
||||
// The rendering code only gets access to the entity in very specific circumstances
|
||||
// i.e. to see if the rendering code needs to update because of a change in state of the
|
||||
// entity. This forces all the rendering code itself to be independent of the entity
|
||||
|
|
|
@ -49,9 +49,10 @@ void LineEntityRenderer::doRender(RenderArgs* args) {
|
|||
PerformanceTimer perfTimer("RenderableLineEntityItem::render");
|
||||
Q_ASSERT(args->_batch);
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
const auto& modelTransform = getModelTransform();
|
||||
Transform transform = Transform();
|
||||
transform.setTranslation(_modelTransform.getTranslation());
|
||||
transform.setRotation(_modelTransform.getRotation());
|
||||
transform.setTranslation(modelTransform.getTranslation());
|
||||
transform.setRotation(modelTransform.getRotation());
|
||||
batch.setModelTransform(transform);
|
||||
if (_linePoints.size() > 1) {
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "EntityTreeRenderer.h"
|
||||
#include "EntitiesRendererLogging.h"
|
||||
|
||||
|
||||
static CollisionRenderMeshCache collisionMeshCache;
|
||||
|
||||
void ModelEntityWrapper::setModel(const ModelPointer& model) {
|
||||
|
@ -107,6 +108,7 @@ QVariantMap parseTexturesToMap(QString textures, const QVariantMap& defaultTextu
|
|||
}
|
||||
|
||||
void RenderableModelEntityItem::doInitialModelSimulation() {
|
||||
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
|
||||
ModelPointer model = getModel();
|
||||
if (!model) {
|
||||
return;
|
||||
|
@ -123,11 +125,11 @@ void RenderableModelEntityItem::doInitialModelSimulation() {
|
|||
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
|
||||
model->setRotation(getRotation());
|
||||
model->setTranslation(getPosition());
|
||||
{
|
||||
PerformanceTimer perfTimer("model->simulate");
|
||||
|
||||
if (_needsInitialSimulation) {
|
||||
model->simulate(0.0f);
|
||||
_needsInitialSimulation = false;
|
||||
}
|
||||
_needsInitialSimulation = false;
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::autoResizeJointArrays() {
|
||||
|
@ -138,6 +140,7 @@ void RenderableModelEntityItem::autoResizeJointArrays() {
|
|||
}
|
||||
|
||||
bool RenderableModelEntityItem::needsUpdateModelBounds() const {
|
||||
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
|
||||
ModelPointer model = getModel();
|
||||
if (!hasModel() || !model) {
|
||||
return false;
|
||||
|
@ -151,7 +154,7 @@ bool RenderableModelEntityItem::needsUpdateModelBounds() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (isMovingRelativeToParent() || isAnimatingSomething()) {
|
||||
if (isAnimatingSomething()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -178,13 +181,61 @@ bool RenderableModelEntityItem::needsUpdateModelBounds() const {
|
|||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return model->needsReload();
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::updateModelBounds() {
|
||||
if (needsUpdateModelBounds()) {
|
||||
doInitialModelSimulation();
|
||||
DETAILED_PROFILE_RANGE(simulation_physics, "updateModelBounds");
|
||||
|
||||
if (!_dimensionsInitialized || !hasModel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ModelPointer model = getModel();
|
||||
if (!model || !model->isLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool updateRenderItems = false;
|
||||
if (model->needsReload()) {
|
||||
model->updateGeometry();
|
||||
updateRenderItems = true;
|
||||
}
|
||||
|
||||
if (model->getScaleToFitDimensions() != getDimensions() ||
|
||||
model->getRegistrationPoint() != getRegistrationPoint()) {
|
||||
// The machinery for updateModelBounds will give existing models the opportunity to fix their
|
||||
// translation/rotation/scale/registration. The first two are straightforward, but the latter two
|
||||
// have guards to make sure they don't happen after they've already been set. Here we reset those guards.
|
||||
// This doesn't cause the entity values to change -- it just allows the model to match once it comes in.
|
||||
model->setScaleToFit(false, getDimensions());
|
||||
model->setSnapModelToRegistrationPoint(false, getRegistrationPoint());
|
||||
|
||||
// now recalculate the bounds and registration
|
||||
model->setScaleToFit(true, getDimensions());
|
||||
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
|
||||
updateRenderItems = true;
|
||||
}
|
||||
|
||||
bool success;
|
||||
auto transform = getTransform(success);
|
||||
if (success && (model->getTranslation() != transform.getTranslation() ||
|
||||
model->getRotation() != transform.getRotation())) {
|
||||
model->setTransformNoUpdateRenderItems(transform);
|
||||
updateRenderItems = true;
|
||||
}
|
||||
|
||||
if (_needsInitialSimulation || _needsJointSimulation || isAnimatingSomething()) {
|
||||
// NOTE: on isAnimatingSomething() we need to call Model::simulate() which calls Rig::updateRig()
|
||||
// TODO: there is opportunity to further optimize the isAnimatingSomething() case.
|
||||
model->simulate(0.0f);
|
||||
_needsInitialSimulation = false;
|
||||
_needsJointSimulation = false;
|
||||
updateRenderItems = true;
|
||||
}
|
||||
|
||||
if (updateRenderItems) {
|
||||
model->updateRenderItems();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,7 +344,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() const {
|
|||
// we have both URLs AND both geometries AND they are both fully loaded.
|
||||
if (_needsInitialSimulation) {
|
||||
// the _model's offset will be wrong until _needsInitialSimulation is false
|
||||
PerformanceTimer perfTimer("_model->simulate");
|
||||
DETAILED_PERFORMANCE_TIMER("_model->simulate");
|
||||
const_cast<RenderableModelEntityItem*>(this)->doInitialModelSimulation();
|
||||
}
|
||||
return true;
|
||||
|
@ -839,7 +890,7 @@ void RenderableModelEntityItem::setJointTranslationsSet(const QVector<bool>& tra
|
|||
}
|
||||
|
||||
void RenderableModelEntityItem::locationChanged(bool tellPhysics) {
|
||||
PerformanceTimer pertTimer("locationChanged");
|
||||
DETAILED_PERFORMANCE_TIMER("locationChanged");
|
||||
EntityItem::locationChanged(tellPhysics);
|
||||
auto model = getModel();
|
||||
if (model && model->isLoaded()) {
|
||||
|
@ -880,7 +931,6 @@ void RenderableModelEntityItem::copyAnimationJointDataToModel() {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
// relay any inbound joint changes from scripts/animation/network to the model/rig
|
||||
_jointDataLock.withWriteLock([&] {
|
||||
for (int index = 0; index < _localJointData.size(); ++index) {
|
||||
|
@ -897,15 +947,11 @@ void RenderableModelEntityItem::copyAnimationJointDataToModel() {
|
|||
});
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::isAnimatingSomething() const {
|
||||
return !getAnimationURL().isEmpty() && getAnimationIsPlaying() && getAnimationFPS() != 0.0f;
|
||||
}
|
||||
|
||||
using namespace render;
|
||||
using namespace render::entities;
|
||||
|
||||
ItemKey ModelEntityRenderer::getKey() {
|
||||
return ItemKey::Builder().withTypeMeta();
|
||||
return ItemKey::Builder().withTypeMeta().withTypeShape();
|
||||
}
|
||||
|
||||
uint32_t ModelEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) {
|
||||
|
@ -1124,6 +1170,7 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
|
|||
}
|
||||
|
||||
void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
|
||||
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
|
||||
if (_hasModel != entity->hasModel()) {
|
||||
_hasModel = entity->hasModel();
|
||||
}
|
||||
|
@ -1202,9 +1249,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
}
|
||||
}
|
||||
|
||||
if (entity->needsUpdateModelBounds()) {
|
||||
entity->updateModelBounds();
|
||||
}
|
||||
entity->updateModelBounds();
|
||||
|
||||
if (model->isVisible() != _visible) {
|
||||
// FIXME: this seems like it could be optimized if we tracked our last known visible state in
|
||||
|
@ -1212,13 +1257,16 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
// so most of the time we don't do anything in this function.
|
||||
model->setVisibleInScene(_visible, scene);
|
||||
}
|
||||
// TODO? early exit here when not visible?
|
||||
|
||||
//entity->doInitialModelSimulation();
|
||||
if (model->needsFixupInScene()) {
|
||||
model->removeFromScene(scene, transaction);
|
||||
render::Item::Status::Getters statusGetters;
|
||||
makeStatusGetters(entity, statusGetters);
|
||||
model->addToScene(scene, transaction, statusGetters);
|
||||
{
|
||||
DETAILED_PROFILE_RANGE(simulation_physics, "Fixup");
|
||||
if (model->needsFixupInScene()) {
|
||||
model->removeFromScene(scene, transaction);
|
||||
render::Item::Status::Getters statusGetters;
|
||||
makeStatusGetters(entity, statusGetters);
|
||||
model->addToScene(scene, transaction, statusGetters);
|
||||
}
|
||||
}
|
||||
|
||||
// When the individual mesh parts of a model finish fading, they will mark their Model as needing updating
|
||||
|
@ -1227,16 +1275,20 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
model->updateRenderItems();
|
||||
}
|
||||
|
||||
// make a copy of the animation properites
|
||||
auto newAnimationProperties = entity->getAnimationProperties();
|
||||
if (newAnimationProperties != _renderAnimationProperties) {
|
||||
withWriteLock([&] {
|
||||
_renderAnimationProperties = newAnimationProperties;
|
||||
_currentFrame = _renderAnimationProperties.getCurrentFrame();
|
||||
});
|
||||
{
|
||||
DETAILED_PROFILE_RANGE(simulation_physics, "CheckAnimation");
|
||||
// make a copy of the animation properites
|
||||
auto newAnimationProperties = entity->getAnimationProperties();
|
||||
if (newAnimationProperties != _renderAnimationProperties) {
|
||||
withWriteLock([&] {
|
||||
_renderAnimationProperties = newAnimationProperties;
|
||||
_currentFrame = _renderAnimationProperties.getCurrentFrame();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (_animating) {
|
||||
DETAILED_PROFILE_RANGE(simulation_physics, "Animate");
|
||||
if (!jointsMapped()) {
|
||||
mapJoints(entity, model->getJointNames());
|
||||
}
|
||||
|
@ -1247,18 +1299,19 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
|
||||
// NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items
|
||||
void ModelEntityRenderer::doRender(RenderArgs* args) {
|
||||
PROFILE_RANGE(render_detail, "MetaModelRender");
|
||||
PerformanceTimer perfTimer("RMEIrender");
|
||||
DETAILED_PROFILE_RANGE(render_detail, "MetaModelRender");
|
||||
DETAILED_PERFORMANCE_TIMER("RMEIrender");
|
||||
|
||||
ModelPointer model;
|
||||
withReadLock([&]{
|
||||
model = _model;
|
||||
});
|
||||
|
||||
if (_model && _model->didVisualGeometryRequestFail()) {
|
||||
// If we don't have a model, or the model doesn't have visual geometry, render our bounding box as green wireframe
|
||||
if (!model || (model && model->didVisualGeometryRequestFail())) {
|
||||
static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
batch.setModelTransform(_modelTransform); // we want to include the scale as well
|
||||
batch.setModelTransform(getModelTransform()); // we want to include the scale as well
|
||||
DependencyManager::get<GeometryCache>()->renderWireCubeInstance(args, batch, greenColor);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -108,7 +108,6 @@ public:
|
|||
|
||||
private:
|
||||
bool needsUpdateModelBounds() const;
|
||||
bool isAnimatingSomething() const;
|
||||
void autoResizeJointArrays();
|
||||
void copyAnimationJointDataToModel();
|
||||
|
||||
|
|
|
@ -251,12 +251,13 @@ void ParticleEffectEntityRenderer::stepSimulation() {
|
|||
});
|
||||
|
||||
if (_emitting && particleProperties.emitting()) {
|
||||
const auto& modelTransform = getModelTransform();
|
||||
uint64_t emitInterval = particleProperties.emitIntervalUsecs();
|
||||
if (emitInterval > 0 && interval >= _timeUntilNextEmit) {
|
||||
auto timeRemaining = interval;
|
||||
while (timeRemaining > _timeUntilNextEmit) {
|
||||
// emit particle
|
||||
_cpuParticles.push_back(createParticle(now, _modelTransform, particleProperties));
|
||||
_cpuParticles.push_back(createParticle(now, modelTransform, particleProperties));
|
||||
_timeUntilNextEmit = emitInterval;
|
||||
if (emitInterval < timeRemaining) {
|
||||
timeRemaining -= emitInterval;
|
||||
|
@ -315,7 +316,7 @@ void ParticleEffectEntityRenderer::doRender(RenderArgs* args) {
|
|||
// In trail mode, the particles are created in world space.
|
||||
// so we only set a transform if they're not in trail mode
|
||||
if (!_particleProperties.emission.shouldTrail) {
|
||||
transform = _modelTransform;
|
||||
transform = getModelTransform();
|
||||
transform.setScale(vec3(1));
|
||||
}
|
||||
batch.setModelTransform(transform);
|
||||
|
|
|
@ -96,6 +96,7 @@ PolyLineEntityRenderer::PolyLineEntityRenderer(const EntityItemPointer& entity)
|
|||
polylineFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, position));
|
||||
polylineFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, normal));
|
||||
polylineFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), offsetof(Vertex, uv));
|
||||
polylineFormat->setAttribute(gpu::Stream::COLOR, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB), offsetof(Vertex, color));
|
||||
});
|
||||
|
||||
PolyLineUniforms uniforms;
|
||||
|
@ -116,7 +117,8 @@ bool PolyLineEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP
|
|||
entity->pointsChanged() ||
|
||||
entity->strokeWidthsChanged() ||
|
||||
entity->normalsChanged() ||
|
||||
entity->texturesChanged()
|
||||
entity->texturesChanged() ||
|
||||
entity->strokeColorsChanged()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -129,9 +131,11 @@ void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer&
|
|||
if (!textures.isEmpty()) {
|
||||
entityTextures = QUrl(textures);
|
||||
}
|
||||
_texture = DependencyManager::get<TextureCache>()->getTexture(entityTextures);
|
||||
}
|
||||
|
||||
if (!_texture || _texture->getURL() != entityTextures) {
|
||||
|
||||
|
||||
if (!_texture) {
|
||||
_texture = DependencyManager::get<TextureCache>()->getTexture(entityTextures);
|
||||
}
|
||||
}
|
||||
|
@ -143,6 +147,10 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
|
|||
auto pointsChanged = entity->pointsChanged();
|
||||
auto strokeWidthsChanged = entity->strokeWidthsChanged();
|
||||
auto normalsChanged = entity->normalsChanged();
|
||||
auto strokeColorsChanged = entity->strokeColorsChanged();
|
||||
|
||||
|
||||
bool isUVModeStretch = entity->getIsUVModeStretch();
|
||||
entity->resetPolyLineChanged();
|
||||
|
||||
_polylineTransform = Transform();
|
||||
|
@ -158,10 +166,14 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
|
|||
if (normalsChanged) {
|
||||
_lastNormals = entity->getNormals();
|
||||
}
|
||||
if (pointsChanged || strokeWidthsChanged || normalsChanged) {
|
||||
if (strokeColorsChanged) {
|
||||
_lastStrokeColors = entity->getStrokeColors();
|
||||
_lastStrokeColors = _lastNormals.size() == _lastStrokeColors.size() ? _lastStrokeColors : QVector<glm::vec3>({ toGlm(entity->getXColor()) });
|
||||
}
|
||||
if (pointsChanged || strokeWidthsChanged || normalsChanged || strokeColorsChanged) {
|
||||
_empty = std::min(_lastPoints.size(), std::min(_lastNormals.size(), _lastStrokeWidths.size())) < 2;
|
||||
if (!_empty) {
|
||||
updateGeometry(updateVertices(_lastPoints, _lastNormals, _lastStrokeWidths));
|
||||
updateGeometry(updateVertices(_lastPoints, _lastNormals, _lastStrokeWidths, _lastStrokeColors, isUVModeStretch, _textureAspectRatio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +187,12 @@ void PolyLineEntityRenderer::updateGeometry(const std::vector<Vertex>& vertices)
|
|||
_verticesBuffer->setSubData(0, vertices);
|
||||
}
|
||||
|
||||
std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertices(const QVector<glm::vec3>& points, const QVector<glm::vec3>& normals, const QVector<float>& strokeWidths) {
|
||||
std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertices(const QVector<glm::vec3>& points,
|
||||
const QVector<glm::vec3>& normals,
|
||||
const QVector<float>& strokeWidths,
|
||||
const QVector<glm::vec3>& strokeColors,
|
||||
const bool isUVModeStretch,
|
||||
const float textureAspectRatio) {
|
||||
// Calculate the minimum vector size out of normals, points, and stroke widths
|
||||
int size = std::min(points.size(), std::min(normals.size(), strokeWidths.size()));
|
||||
|
||||
|
@ -190,10 +207,52 @@ std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertic
|
|||
float uCoord = 0.0f;
|
||||
int finalIndex = size - 1;
|
||||
glm::vec3 binormal;
|
||||
float accumulatedDistance = 0.0f;
|
||||
float distanceToLastPoint = 0.0f;
|
||||
float accumulatedStrokeWidth = 0.0f;
|
||||
float strokeWidth = 0.0f;
|
||||
bool doesStrokeWidthVary = false;
|
||||
|
||||
|
||||
for (int i = 1; i < strokeWidths.size(); i++) {
|
||||
if (strokeWidths[i] != strokeWidths[i - 1]) {
|
||||
doesStrokeWidthVary = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i <= finalIndex; i++) {
|
||||
const float& width = strokeWidths.at(i);
|
||||
const auto& point = points.at(i);
|
||||
const auto& normal = normals.at(i);
|
||||
const auto& color = strokeColors.size() == normals.size() ? strokeColors.at(i) : strokeColors.at(0);
|
||||
int vertexIndex = i * 2;
|
||||
|
||||
|
||||
if (!isUVModeStretch && i >= 1) {
|
||||
distanceToLastPoint = glm::distance(points.at(i), points.at(i - 1));
|
||||
accumulatedDistance += distanceToLastPoint;
|
||||
strokeWidth = 2 * strokeWidths[i];
|
||||
|
||||
if (doesStrokeWidthVary) {
|
||||
//If the stroke varies along the line the texture will stretch more or less depending on the speed
|
||||
//because it looks better than using the same method as below
|
||||
accumulatedStrokeWidth += strokeWidth;
|
||||
float increaseValue = 1;
|
||||
if (accumulatedStrokeWidth != 0) {
|
||||
float newUcoord = glm::ceil(((1.0f / textureAspectRatio) * accumulatedDistance) / (accumulatedStrokeWidth / i));
|
||||
increaseValue = newUcoord - uCoord;
|
||||
}
|
||||
|
||||
increaseValue = increaseValue > 0 ? increaseValue : 1;
|
||||
uCoord += increaseValue;
|
||||
} else {
|
||||
//If the stroke width is constant then the textures should keep the aspect ratio along the line
|
||||
uCoord = ((1.0f / textureAspectRatio) * accumulatedDistance) / strokeWidth;
|
||||
}
|
||||
} else if (vertexIndex >= 2) {
|
||||
uCoord += uCoordInc;
|
||||
}
|
||||
|
||||
// For last point we can assume binormals are the same since it represents the last two vertices of quad
|
||||
if (i < finalIndex) {
|
||||
|
@ -206,11 +265,10 @@ std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertic
|
|||
}
|
||||
}
|
||||
|
||||
const auto v1 = point + binormal;
|
||||
const auto v2 = point - binormal;
|
||||
vertices.emplace_back(v1, normal, vec2(uCoord, 0.0f));
|
||||
vertices.emplace_back(v2, normal, vec2(uCoord, 1.0f));
|
||||
uCoord += uCoordInc;
|
||||
const auto v1 = points.at(i) + binormal;
|
||||
const auto v2 = points.at(i) - binormal;
|
||||
vertices.emplace_back(v1, normal, vec2(uCoord, 0.0f), color);
|
||||
vertices.emplace_back(v2, normal, vec2(uCoord, 1.0f), color);
|
||||
}
|
||||
|
||||
return vertices;
|
||||
|
@ -235,6 +293,12 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
|
|||
batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
}
|
||||
|
||||
float textureWidth = (float)_texture->getOriginalWidth();
|
||||
float textureHeight = (float)_texture->getOriginalHeight();
|
||||
if (textureWidth != 0 && textureHeight != 0) {
|
||||
_textureAspectRatio = textureWidth / textureHeight;
|
||||
}
|
||||
|
||||
batch.setInputFormat(polylineFormat);
|
||||
batch.setInputBuffer(0, _verticesBuffer, 0, sizeof(Vertex));
|
||||
|
||||
|
@ -247,4 +311,4 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
|
|||
#endif
|
||||
|
||||
batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0);
|
||||
}
|
||||
}
|
|
@ -27,7 +27,9 @@ public:
|
|||
|
||||
protected:
|
||||
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
|
||||
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
|
||||
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene,
|
||||
Transaction& transaction,
|
||||
const TypedEntityPointer& entity) override;
|
||||
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
|
||||
|
||||
virtual ItemKey getKey() override;
|
||||
|
@ -38,24 +40,37 @@ protected:
|
|||
|
||||
struct Vertex {
|
||||
Vertex() {}
|
||||
Vertex(const vec3& position, const vec3& normal, const vec2& uv) : position(position), normal(normal), uv(uv) {}
|
||||
Vertex(const vec3& position, const vec3& normal, const vec2& uv, const vec3& color) : position(position),
|
||||
normal(normal),
|
||||
uv(uv),
|
||||
color(color) {}
|
||||
vec3 position;
|
||||
vec3 normal;
|
||||
vec2 uv;
|
||||
vec3 color;
|
||||
};
|
||||
|
||||
void updateGeometry(const std::vector<Vertex>& vertices);
|
||||
static std::vector<Vertex> updateVertices(const QVector<glm::vec3>& points, const QVector<glm::vec3>& normals, const QVector<float>& strokeWidths);
|
||||
static std::vector<Vertex> updateVertices(const QVector<glm::vec3>& points,
|
||||
const QVector<glm::vec3>& normals,
|
||||
const QVector<float>& strokeWidths,
|
||||
const QVector<glm::vec3>& strokeColors,
|
||||
const bool isUVModeStretch,
|
||||
const float textureAspectRatio);
|
||||
|
||||
Transform _polylineTransform;
|
||||
QVector<glm::vec3> _lastPoints;
|
||||
QVector<glm::vec3> _lastNormals;
|
||||
QVector<glm::vec3> _lastStrokeColors;
|
||||
QVector<float> _lastStrokeWidths;
|
||||
gpu::BufferPointer _verticesBuffer;
|
||||
gpu::BufferView _uniformBuffer;
|
||||
|
||||
uint32_t _numVertices { 0 };
|
||||
bool _empty{ true };
|
||||
NetworkTexturePointer _texture;
|
||||
float _textureAspectRatio { 1.0f };
|
||||
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
|
|
@ -76,6 +76,14 @@ bool ShapeEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
|
|||
return true;
|
||||
}
|
||||
|
||||
if (_shape != entity->getShape()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_dimensions != entity->getDimensions()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -93,12 +101,13 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
_position = entity->getPosition();
|
||||
_dimensions = entity->getDimensions();
|
||||
_orientation = entity->getOrientation();
|
||||
_renderTransform = getModelTransform();
|
||||
|
||||
if (_shape == entity::Sphere) {
|
||||
_modelTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||
_renderTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||
}
|
||||
|
||||
_modelTransform.postScale(_dimensions);
|
||||
_renderTransform.postScale(_dimensions);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -133,7 +142,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
|||
glm::vec4 outColor;
|
||||
withReadLock([&] {
|
||||
geometryShape = MAPPING[_shape];
|
||||
batch.setModelTransform(_modelTransform); // use a transform with scale, rotation, registration point and translation
|
||||
batch.setModelTransform(_renderTransform); // use a transform with scale, rotation, registration point and translation
|
||||
outColor = _color;
|
||||
if (_procedural.isReady()) {
|
||||
_procedural.prepare(batch, _position, _dimensions, _orientation);
|
||||
|
|
|
@ -32,6 +32,7 @@ private:
|
|||
|
||||
Procedural _procedural;
|
||||
QString _lastUserData;
|
||||
Transform _renderTransform;
|
||||
entity::Shape _shape { entity::Sphere };
|
||||
glm::vec4 _color;
|
||||
glm::vec3 _position;
|
||||
|
|
|
@ -93,10 +93,11 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
|||
Q_ASSERT(args->_batch);
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
|
||||
auto transformToTopLeft = _modelTransform;
|
||||
const auto& modelTransform = getModelTransform();
|
||||
auto transformToTopLeft = modelTransform;
|
||||
if (_faceCamera) {
|
||||
//rotate about vertical to face the camera
|
||||
glm::vec3 dPosition = args->getViewFrustum().getPosition() - _modelTransform.getTranslation();
|
||||
glm::vec3 dPosition = args->getViewFrustum().getPosition() - modelTransform.getTranslation();
|
||||
// If x and z are 0, atan(x, z) is undefined, so default to 0 degrees
|
||||
float yawRotation = dPosition.x == 0.0f && dPosition.z == 0.0f ? 0.0f : glm::atan(dPosition.x, dPosition.z);
|
||||
glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f));
|
||||
|
|
|
@ -139,8 +139,8 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
|||
|
||||
glm::vec2 windowSize = getWindowSize(entity);
|
||||
_webSurface->resize(QSize(windowSize.x, windowSize.y));
|
||||
|
||||
_modelTransform.postScale(entity->getDimensions());
|
||||
_renderTransform = getModelTransform();
|
||||
_renderTransform.postScale(entity->getDimensions());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
|
|||
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
withReadLock([&] {
|
||||
batch.setModelTransform(_modelTransform);
|
||||
batch.setModelTransform(_renderTransform);
|
||||
});
|
||||
batch.setResourceTexture(0, _texture);
|
||||
float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||
|
|
|
@ -62,6 +62,7 @@ private:
|
|||
uint16_t _lastDPI;
|
||||
QTimer _timer;
|
||||
uint64_t _lastRenderTime { 0 };
|
||||
Transform _renderTransform;
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
|
|
@ -52,6 +52,12 @@ void ZoneEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entity
|
|||
_backgroundStage->removeBackground(_backgroundIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (_hazeStage) {
|
||||
if (!HazeStage::isIndexInvalid(_hazeIndex)) {
|
||||
_hazeStage->removeHaze(_hazeIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
||||
|
@ -95,6 +101,11 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
|||
assert(_backgroundStage);
|
||||
}
|
||||
|
||||
if (!_hazeStage) {
|
||||
_hazeStage = args->_scene->getStage<HazeStage>();
|
||||
assert(_hazeStage);
|
||||
}
|
||||
|
||||
{ // Sun
|
||||
// Need an update ?
|
||||
if (_needSunUpdate) {
|
||||
|
@ -136,6 +147,15 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (_needHazeUpdate) {
|
||||
if (HazeStage::isIndexInvalid(_hazeIndex)) {
|
||||
_hazeIndex = _hazeStage->addHaze(_haze);
|
||||
}
|
||||
_needHazeUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_visible) {
|
||||
// FInally, push the light visible in the frame
|
||||
// THe directional key light for sure
|
||||
|
@ -150,6 +170,11 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
|||
if (_backgroundMode != BACKGROUND_MODE_INHERIT) {
|
||||
_backgroundStage->_currentFrame.pushBackground(_backgroundIndex);
|
||||
}
|
||||
|
||||
// Haze only if the mode is not inherit
|
||||
if (_hazeMode != COMPONENT_MODE_INHERIT) {
|
||||
_hazeStage->_currentFrame.pushHaze(_hazeIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,15 +196,17 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
|
|||
bool sunChanged = entity->keyLightPropertiesChanged();
|
||||
bool backgroundChanged = entity->backgroundPropertiesChanged();
|
||||
bool skyboxChanged = entity->skyboxPropertiesChanged();
|
||||
bool hazeChanged = entity->hazePropertiesChanged();
|
||||
|
||||
entity->resetRenderingPropertiesChanged();
|
||||
_lastPosition = entity->getPosition();
|
||||
_lastRotation = entity->getRotation();
|
||||
_lastDimensions = entity->getDimensions();
|
||||
|
||||
_keyLightProperties = entity->getKeyLightProperties();
|
||||
_stageProperties = entity->getStageProperties();
|
||||
_skyboxProperties = entity->getSkyboxProperties();
|
||||
|
||||
_hazeProperties = entity->getHazeProperties();
|
||||
_stageProperties = entity->getStageProperties();
|
||||
|
||||
#if 0
|
||||
if (_lastShapeURL != _typedEntity->getCompoundShapeURL()) {
|
||||
|
@ -209,14 +236,20 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
|
|||
if (sunChanged || skyboxChanged) {
|
||||
updateKeyAmbientFromEntity();
|
||||
}
|
||||
|
||||
if (backgroundChanged || skyboxChanged) {
|
||||
updateKeyBackgroundFromEntity(entity);
|
||||
}
|
||||
|
||||
if (hazeChanged) {
|
||||
updateHazeFromEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
||||
if (entity->getShapeType() == SHAPE_TYPE_SPHERE) {
|
||||
_modelTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||
_renderTransform = getModelTransform();
|
||||
_renderTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,6 +261,7 @@ ItemKey ZoneEntityRenderer::getKey() {
|
|||
bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
||||
if (entity->keyLightPropertiesChanged() ||
|
||||
entity->backgroundPropertiesChanged() ||
|
||||
entity->hazePropertiesChanged() ||
|
||||
entity->skyboxPropertiesChanged()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -298,6 +332,36 @@ void ZoneEntityRenderer::updateKeyAmbientFromEntity() {
|
|||
}
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::updateHazeFromEntity(const TypedEntityPointer& entity) {
|
||||
setHazeMode((ComponentMode)entity->getHazeMode());
|
||||
|
||||
const auto& haze = editHaze();
|
||||
|
||||
const uint32_t hazeMode = entity->getHazeMode();
|
||||
haze->setHazeActive(hazeMode == COMPONENT_MODE_ENABLED);
|
||||
haze->setAltitudeBased(_hazeProperties.getHazeAltitudeEffect());
|
||||
|
||||
haze->setHazeRangeFactor(model::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeRange()));
|
||||
xColor hazeColor = _hazeProperties.getHazeColor();
|
||||
haze->setHazeColor(glm::vec3(hazeColor.red / 255.0, hazeColor.green / 255.0, hazeColor.blue / 255.0));
|
||||
xColor hazeGlareColor = _hazeProperties.getHazeGlareColor();
|
||||
haze->setDirectionalLightColor(glm::vec3(hazeGlareColor.red / 255.0, hazeGlareColor.green / 255.0, hazeGlareColor.blue / 255.0));
|
||||
haze->setHazeEnableGlare(_hazeProperties.getHazeEnableGlare());
|
||||
haze->setDirectionalLightBlend(model::convertDirectionalLightAngleToPower(_hazeProperties.getHazeGlareAngle()));
|
||||
|
||||
float hazeAltitude = _hazeProperties.getHazeCeiling() - _hazeProperties.getHazeBaseRef();
|
||||
haze->setHazeAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(hazeAltitude));
|
||||
haze->setHazeBaseReference(_hazeProperties.getHazeBaseRef());
|
||||
|
||||
haze->setHazeBackgroundBlendValue(_hazeProperties.getHazeBackgroundBlend());
|
||||
|
||||
haze->setHazeAttenuateKeyLight(_hazeProperties.getHazeAttenuateKeyLight());
|
||||
haze->setHazeKeyLightRangeFactor(model::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeKeyLightRange()));
|
||||
haze->setHazeKeyLightAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(_hazeProperties.getHazeKeyLightAltitude()));
|
||||
|
||||
haze->setZoneTransform(entity->getTransform().getMatrix());
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::updateKeyBackgroundFromEntity(const TypedEntityPointer& entity) {
|
||||
editBackground();
|
||||
setBackgroundMode(entity->getBackgroundMode());
|
||||
|
@ -408,6 +472,10 @@ void ZoneEntityRenderer::setBackgroundMode(BackgroundMode mode) {
|
|||
_backgroundMode = mode;
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::setHazeMode(ComponentMode mode) {
|
||||
_hazeMode = mode;
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::setSkyboxColor(const glm::vec3& color) {
|
||||
editSkybox()->setColor(color);
|
||||
}
|
||||
|
|
|
@ -14,11 +14,15 @@
|
|||
|
||||
#include <ZoneEntityItem.h>
|
||||
#include <model/Skybox.h>
|
||||
#include <model/Haze.h>
|
||||
#include <model/Stage.h>
|
||||
#include <LightStage.h>
|
||||
#include <BackgroundStage.h>
|
||||
#include <HazeStage.h>
|
||||
#include <TextureCache.h>
|
||||
#include "RenderableEntityItem.h"
|
||||
#include <ComponentMode.h>
|
||||
|
||||
#if 0
|
||||
#include <Model.h>
|
||||
#endif
|
||||
|
@ -44,12 +48,14 @@ private:
|
|||
void updateKeyZoneItemFromEntity();
|
||||
void updateKeySunFromEntity();
|
||||
void updateKeyAmbientFromEntity();
|
||||
void updateHazeFromEntity(const TypedEntityPointer& entity);
|
||||
void updateKeyBackgroundFromEntity(const TypedEntityPointer& entity);
|
||||
void updateAmbientMap();
|
||||
void updateSkyboxMap();
|
||||
void setAmbientURL(const QString& ambientUrl);
|
||||
void setSkyboxURL(const QString& skyboxUrl);
|
||||
void setBackgroundMode(BackgroundMode mode);
|
||||
void setHazeMode(ComponentMode mode);
|
||||
void setSkyboxColor(const glm::vec3& color);
|
||||
void setProceduralUserData(const QString& userData);
|
||||
|
||||
|
@ -57,7 +63,7 @@ private:
|
|||
model::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; }
|
||||
model::SunSkyStagePointer editBackground() { _needBackgroundUpdate = true; return _background; }
|
||||
model::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); }
|
||||
|
||||
model::HazePointer editHaze() { _needHazeUpdate = true; return _haze; }
|
||||
|
||||
bool _needsInitialSimulation{ true };
|
||||
glm::vec3 _lastPosition;
|
||||
|
@ -76,7 +82,10 @@ private:
|
|||
const model::LightPointer _sunLight{ std::make_shared<model::Light>() };
|
||||
const model::LightPointer _ambientLight{ std::make_shared<model::Light>() };
|
||||
const model::SunSkyStagePointer _background{ std::make_shared<model::SunSkyStage>() };
|
||||
const model::HazePointer _haze{ std::make_shared<model::Haze>() };
|
||||
|
||||
BackgroundMode _backgroundMode{ BACKGROUND_MODE_INHERIT };
|
||||
ComponentMode _hazeMode{ COMPONENT_MODE_INHERIT };
|
||||
|
||||
indexed_container::Index _sunIndex{ LightStage::INVALID_INDEX };
|
||||
indexed_container::Index _ambientIndex{ LightStage::INVALID_INDEX };
|
||||
|
@ -84,12 +93,17 @@ private:
|
|||
BackgroundStagePointer _backgroundStage;
|
||||
BackgroundStage::Index _backgroundIndex{ BackgroundStage::INVALID_INDEX };
|
||||
|
||||
HazeStagePointer _hazeStage;
|
||||
HazeStage::Index _hazeIndex{ HazeStage::INVALID_INDEX };
|
||||
|
||||
bool _needUpdate{ true };
|
||||
bool _needSunUpdate{ true };
|
||||
bool _needAmbientUpdate{ true };
|
||||
bool _needBackgroundUpdate{ true };
|
||||
bool _needHazeUpdate{ true };
|
||||
|
||||
KeyLightPropertyGroup _keyLightProperties;
|
||||
HazePropertyGroup _hazeProperties;
|
||||
StagePropertyGroup _stageProperties;
|
||||
SkyboxPropertyGroup _skyboxProperties;
|
||||
|
||||
|
@ -105,6 +119,7 @@ private:
|
|||
bool _validSkyboxTexture{ false };
|
||||
|
||||
QString _proceduralUserData;
|
||||
Transform _renderTransform;
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
|
|
@ -40,7 +40,7 @@ void main(void) {
|
|||
packDeferredFragmentTranslucent(
|
||||
float(frontCondition) * interpolatedNormal,
|
||||
texel.a * varColor.a,
|
||||
polyline.color * texel.rgb,
|
||||
color * texel.rgb,
|
||||
vec3(0.01, 0.01, 0.01),
|
||||
10.0);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
|
||||
class EntitiesScriptEngineProvider {
|
||||
public:
|
||||
virtual void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params = QStringList()) = 0;
|
||||
virtual void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
|
||||
const QStringList& params = QStringList(), const QUuid& remoteCallerID = QUuid()) = 0;
|
||||
virtual QFuture<QVariant> getLocalEntityScriptDetails(const EntityItemID& entityID) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
AnimationPropertyGroup EntityItemProperties::_staticAnimation;
|
||||
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
|
||||
HazePropertyGroup EntityItemProperties::_staticHaze;
|
||||
StagePropertyGroup EntityItemProperties::_staticStage;
|
||||
KeyLightPropertyGroup EntityItemProperties::_staticKeyLight;
|
||||
|
||||
|
@ -71,6 +72,7 @@ void EntityItemProperties::debugDump() const {
|
|||
|
||||
getAnimation().debugDump();
|
||||
getSkybox().debugDump();
|
||||
getHaze().debugDump();
|
||||
getKeyLight().debugDump();
|
||||
|
||||
qCDebug(entities) << " changed properties...";
|
||||
|
@ -218,6 +220,42 @@ void EntityItemProperties::setBackgroundModeFromString(const QString& background
|
|||
}
|
||||
}
|
||||
|
||||
using ComponentPair = std::pair<const ComponentMode, const QString>;
|
||||
const std::array<ComponentPair, COMPONENT_MODE_ITEM_COUNT> COMPONENT_MODES = { {
|
||||
ComponentPair{ COMPONENT_MODE_INHERIT,{ "inherit" } },
|
||||
ComponentPair{ COMPONENT_MODE_DISABLED,{ "disabled" } },
|
||||
ComponentPair{ COMPONENT_MODE_ENABLED,{ "enabled" } }
|
||||
} };
|
||||
|
||||
QString EntityItemProperties::getHazeModeAsString() const {
|
||||
// return "inherit" if _hazeMode is not valid
|
||||
if (_hazeMode < COMPONENT_MODE_ITEM_COUNT) {
|
||||
return COMPONENT_MODES[_hazeMode].second;
|
||||
} else {
|
||||
return COMPONENT_MODES[COMPONENT_MODE_INHERIT].second;
|
||||
}
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getHazeModeString(uint32_t mode) {
|
||||
// return "inherit" if mode is not valid
|
||||
if (mode < COMPONENT_MODE_ITEM_COUNT) {
|
||||
return COMPONENT_MODES[mode].second;
|
||||
} else {
|
||||
return COMPONENT_MODES[COMPONENT_MODE_INHERIT].second;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityItemProperties::setHazeModeFromString(const QString& hazeMode) {
|
||||
auto result = std::find_if(COMPONENT_MODES.begin(), COMPONENT_MODES.end(), [&](const ComponentPair& pair) {
|
||||
return (pair.second == hazeMode);
|
||||
});
|
||||
|
||||
if (result != COMPONENT_MODES.end()) {
|
||||
_hazeMode = result->first;
|
||||
_hazeModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||
EntityPropertyFlags changedProperties;
|
||||
|
||||
|
@ -303,6 +341,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
|
||||
CHECK_PROPERTY_CHANGE(PROP_NAME, name);
|
||||
CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_MODE, backgroundMode);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_MODE, hazeMode);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_SOURCE_URL, sourceUrl);
|
||||
CHECK_PROPERTY_CHANGE(PROP_VOXEL_VOLUME_SIZE, voxelVolumeSize);
|
||||
CHECK_PROPERTY_CHANGE(PROP_VOXEL_DATA, voxelData);
|
||||
|
@ -314,7 +355,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_FACE_CAMERA, faceCamera);
|
||||
CHECK_PROPERTY_CHANGE(PROP_ACTION_DATA, actionData);
|
||||
CHECK_PROPERTY_CHANGE(PROP_NORMALS, normals);
|
||||
CHECK_PROPERTY_CHANGE(PROP_STROKE_COLORS, strokeColors);
|
||||
CHECK_PROPERTY_CHANGE(PROP_STROKE_WIDTHS, strokeWidths);
|
||||
CHECK_PROPERTY_CHANGE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch);
|
||||
CHECK_PROPERTY_CHANGE(PROP_X_TEXTURE_URL, xTextureURL);
|
||||
CHECK_PROPERTY_CHANGE(PROP_Y_TEXTURE_URL, yTextureURL);
|
||||
CHECK_PROPERTY_CHANGE(PROP_Z_TEXTURE_URL, zTextureURL);
|
||||
|
@ -350,6 +393,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
changedProperties += _keyLight.getChangedProperties();
|
||||
changedProperties += _skybox.getChangedProperties();
|
||||
changedProperties += _stage.getChangedProperties();
|
||||
changedProperties += _haze.getChangedProperties();
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
@ -529,6 +573,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FLYING_ALLOWED, flyingAllowed);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FILTER_URL, filterURL);
|
||||
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_HAZE_MODE, hazeMode, getHazeModeAsString());
|
||||
_haze.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||
}
|
||||
|
||||
// Web only
|
||||
|
@ -560,8 +607,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_WIDTH, lineWidth);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NORMALS, normals);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_COLORS, strokeColors);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch);
|
||||
}
|
||||
|
||||
if (!skipDefaults && !strictSemantics) {
|
||||
|
@ -712,6 +761,9 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL);
|
||||
|
||||
COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(backgroundMode, BackgroundMode);
|
||||
|
||||
COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(hazeMode, HazeMode);
|
||||
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(sourceUrl, QString, setSourceUrl);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelVolumeSize, glmVec3, setVoxelVolumeSize);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelData, QByteArray, setVoxelData);
|
||||
|
@ -723,7 +775,10 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE(faceCamera, bool, setFaceCamera);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(actionData, QByteArray, setActionData);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(normals, qVectorVec3, setNormals);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeColors, qVectorVec3, setStrokeColors);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeWidths,qVectorFloat, setStrokeWidths);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(isUVModeStretch, bool, setIsUVModeStretch);
|
||||
|
||||
|
||||
if (!honorReadOnly) {
|
||||
// this is used by the json reader to set things that we don't want javascript to able to affect.
|
||||
|
@ -739,6 +794,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
_keyLight.copyFromScriptValue(object, _defaultSettings);
|
||||
_skybox.copyFromScriptValue(object, _defaultSettings);
|
||||
_stage.copyFromScriptValue(object, _defaultSettings);
|
||||
_haze.copyFromScriptValue(object, _defaultSettings);
|
||||
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(xTextureURL, QString, setXTextureURL);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(yTextureURL, QString, setYTextureURL);
|
||||
|
@ -862,6 +918,9 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
COPY_PROPERTY_IF_CHANGED(collisionSoundURL);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(backgroundMode);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(hazeMode);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(sourceUrl);
|
||||
COPY_PROPERTY_IF_CHANGED(voxelVolumeSize);
|
||||
COPY_PROPERTY_IF_CHANGED(voxelData);
|
||||
|
@ -873,13 +932,16 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
COPY_PROPERTY_IF_CHANGED(faceCamera);
|
||||
COPY_PROPERTY_IF_CHANGED(actionData);
|
||||
COPY_PROPERTY_IF_CHANGED(normals);
|
||||
COPY_PROPERTY_IF_CHANGED(strokeColors);
|
||||
COPY_PROPERTY_IF_CHANGED(strokeWidths);
|
||||
COPY_PROPERTY_IF_CHANGED(isUVModeStretch);
|
||||
COPY_PROPERTY_IF_CHANGED(created);
|
||||
|
||||
_animation.merge(other._animation);
|
||||
_keyLight.merge(other._keyLight);
|
||||
_skybox.merge(other._skybox);
|
||||
_stage.merge(other._stage);
|
||||
_haze.merge(other._haze);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(xTextureURL);
|
||||
COPY_PROPERTY_IF_CHANGED(yTextureURL);
|
||||
|
@ -1059,7 +1121,9 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
|||
ADD_PROPERTY_TO_MAP(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
|
||||
ADD_PROPERTY_TO_MAP(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
|
||||
ADD_PROPERTY_TO_MAP(PROP_NORMALS, Normals, normals, QVector<glm::vec3>);
|
||||
ADD_PROPERTY_TO_MAP(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector<glm::vec3>);
|
||||
ADD_PROPERTY_TO_MAP(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>);
|
||||
ADD_PROPERTY_TO_MAP(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, QVector<float>);
|
||||
ADD_PROPERTY_TO_MAP(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
|
||||
ADD_PROPERTY_TO_MAP(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
|
||||
ADD_PROPERTY_TO_MAP(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString);
|
||||
|
@ -1110,6 +1174,24 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
|||
ADD_PROPERTY_TO_MAP(PROP_GHOSTING_ALLOWED, GhostingAllowed, ghostingAllowed, bool);
|
||||
ADD_PROPERTY_TO_MAP(PROP_FILTER_URL, FilterURL, filterURL, QString);
|
||||
|
||||
ADD_PROPERTY_TO_MAP(PROP_HAZE_MODE, HazeMode, hazeMode, uint32_t);
|
||||
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_RANGE, Haze, haze, HazeRange, hazeRange);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_COLOR, Haze, haze, HazeColor, hazeColor);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_GLARE_COLOR, Haze, haze, HazeGlareColor, hazeGlareColor);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_ENABLE_GLARE, Haze, haze, HazeEnableGlare, hazeEnableGlare);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_GLARE_ANGLE, Haze, haze, HazeGlareAngle, hazeGlareAngle);
|
||||
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_ALTITUDE_EFFECT, Haze, haze, HazeAltitudeEffect, hazeAltitudeEfect);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_CEILING, Haze, haze, HazeCeiling, hazeCeiling);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_BASE_REF, Haze, haze, HazeBaseRef, hazeBaseRef);
|
||||
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_BACKGROUND_BLEND, Haze, haze, HazeBackgroundBlend, hazeBackgroundBlend);
|
||||
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_ATTENUATE_KEYLIGHT, Haze, haze, HazeAttenuateKeyLight, hazeAttenuateKeyLight);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_KEYLIGHT_RANGE, Haze, haze, HazeKeyLightRange, hazeKeyLightRange);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_KEYLIGHT_ALTITUDE, Haze, haze, HazeKeyLightAltitude, hazeKeyLightAltitude);
|
||||
|
||||
ADD_PROPERTY_TO_MAP(PROP_DPI, DPI, dpi, uint16_t);
|
||||
|
||||
// FIXME - these are not yet handled
|
||||
|
@ -1358,6 +1440,10 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
|||
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, properties.getFlyingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, properties.getGhostingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_FILTER_URL, properties.getFilterURL());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_MODE, (uint32_t)properties.getHazeMode());
|
||||
_staticHaze.setProperties(properties);
|
||||
_staticHaze.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
}
|
||||
|
||||
if (properties.getType() == EntityTypes::PolyVox) {
|
||||
|
@ -1383,9 +1469,11 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
|||
if (properties.getType() == EntityTypes::PolyLine) {
|
||||
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth());
|
||||
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
||||
APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getNormals());
|
||||
APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getPackedNormals());
|
||||
APPEND_ENTITY_PROPERTY(PROP_STROKE_COLORS, properties.getPackedStrokeColors());
|
||||
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths());
|
||||
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures());
|
||||
APPEND_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, properties.getIsUVModeStretch());
|
||||
}
|
||||
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
|
||||
// when encoding/decoding edits because otherwise they can't polymorph to other shape types
|
||||
|
@ -1472,6 +1560,44 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
|||
return success;
|
||||
}
|
||||
|
||||
QByteArray EntityItemProperties::getPackedNormals() const {
|
||||
return packNormals(getNormals());
|
||||
}
|
||||
|
||||
QByteArray EntityItemProperties::packNormals(const QVector<glm::vec3>& normals) const {
|
||||
int normalsSize = normals.size();
|
||||
QByteArray packedNormals = QByteArray(normalsSize * 6 + 1, '0');
|
||||
// add size of the array
|
||||
packedNormals[0] = ((uint8_t)normalsSize);
|
||||
|
||||
int index = 1;
|
||||
for (int i = 0; i < normalsSize; i++) {
|
||||
int numBytes = packFloatVec3ToSignedTwoByteFixed((unsigned char*)packedNormals.data() + index, normals[i], 15);
|
||||
index += numBytes;
|
||||
}
|
||||
return packedNormals;
|
||||
}
|
||||
|
||||
QByteArray EntityItemProperties::getPackedStrokeColors() const {
|
||||
return packStrokeColors(getStrokeColors());
|
||||
}
|
||||
QByteArray EntityItemProperties::packStrokeColors(const QVector<glm::vec3>& strokeColors) const {
|
||||
int strokeColorsSize = strokeColors.size();
|
||||
QByteArray packedStrokeColors = QByteArray(strokeColorsSize * 3 + 1, '0');
|
||||
|
||||
// add size of the array
|
||||
packedStrokeColors[0] = ((uint8_t)strokeColorsSize);
|
||||
|
||||
|
||||
for (int i = 0; i < strokeColorsSize; i++) {
|
||||
// add the color to the QByteArray
|
||||
packedStrokeColors[i * 3 + 1] = strokeColors[i].r * 255;
|
||||
packedStrokeColors[i * 3 + 2] = strokeColors[i].g * 255;
|
||||
packedStrokeColors[i * 3 + 3] = strokeColors[i].b * 255;
|
||||
}
|
||||
return packedStrokeColors;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// how to handle lastEdited?
|
||||
// how to handle lastUpdated?
|
||||
|
@ -1664,7 +1790,10 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FLYING_ALLOWED, bool, setFlyingAllowed);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FILTER_URL, QString, setFilterURL);
|
||||
}
|
||||
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_HAZE_MODE, uint32_t, setHazeMode);
|
||||
properties.getHaze().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
}
|
||||
|
||||
if (properties.getType() == EntityTypes::PolyVox) {
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_VOLUME_SIZE, glm::vec3, setVoxelVolumeSize);
|
||||
|
@ -1690,9 +1819,11 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
if (properties.getType() == EntityTypes::PolyLine) {
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QByteArray, setPackedNormals);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_COLORS, QByteArray, setPackedStrokeColors);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IS_UV_MODE_STRETCH, bool, setIsUVModeStretch);
|
||||
}
|
||||
|
||||
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
|
||||
|
@ -1723,6 +1854,53 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
return valid;
|
||||
}
|
||||
|
||||
void EntityItemProperties::setPackedNormals(const QByteArray& value) {
|
||||
setNormals(unpackNormals(value));
|
||||
}
|
||||
|
||||
QVector<glm::vec3> EntityItemProperties::unpackNormals(const QByteArray& normals) {
|
||||
// the size of the vector is packed first
|
||||
QVector<glm::vec3> unpackedNormals = QVector<glm::vec3>((int)normals[0]);
|
||||
|
||||
if ((int)normals[0] == normals.size() / 6) {
|
||||
int j = 0;
|
||||
for (int i = 1; i < normals.size();) {
|
||||
glm::vec3 aux = glm::vec3();
|
||||
i += unpackFloatVec3FromSignedTwoByteFixed((unsigned char*)normals.data() + i, aux, 15);
|
||||
unpackedNormals[j] = aux;
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
qCDebug(entities) << "WARNING - Expected received size for normals does not match. Expected: " << (int)normals[0]
|
||||
<< " Received: " << (normals.size() / 6);
|
||||
}
|
||||
return unpackedNormals;
|
||||
}
|
||||
|
||||
void EntityItemProperties::setPackedStrokeColors(const QByteArray& value) {
|
||||
setStrokeColors(unpackStrokeColors(value));
|
||||
}
|
||||
|
||||
QVector<glm::vec3> EntityItemProperties::unpackStrokeColors(const QByteArray& strokeColors) {
|
||||
// the size of the vector is packed first
|
||||
QVector<glm::vec3> unpackedStrokeColors = QVector<glm::vec3>((int)strokeColors[0]);
|
||||
|
||||
if ((int)strokeColors[0] == strokeColors.size() / 3) {
|
||||
int j = 0;
|
||||
for (int i = 1; i < strokeColors.size();) {
|
||||
|
||||
float r = (uint8_t)strokeColors[i++] / 255.0f;
|
||||
float g = (uint8_t)strokeColors[i++] / 255.0f;
|
||||
float b = (uint8_t)strokeColors[i++] / 255.0f;
|
||||
unpackedStrokeColors[j++] = glmVec3(r, g, b);
|
||||
}
|
||||
} else {
|
||||
qCDebug(entities) << "WARNING - Expected received size for stroke colors does not match. Expected: "
|
||||
<< (int)strokeColors[0] << " Received: " << (strokeColors.size() / 3);
|
||||
}
|
||||
|
||||
return unpackedStrokeColors;
|
||||
}
|
||||
|
||||
// NOTE: This version will only encode the portion of the edit message immediately following the
|
||||
// header it does not include the send times and sequence number because that is handled by the
|
||||
|
@ -1843,10 +2021,12 @@ void EntityItemProperties::markAllChanged() {
|
|||
_keyLight.markAllChanged();
|
||||
|
||||
_backgroundModeChanged = true;
|
||||
_hazeModeChanged = true;
|
||||
|
||||
_animation.markAllChanged();
|
||||
_skybox.markAllChanged();
|
||||
_stage.markAllChanged();
|
||||
_haze.markAllChanged();
|
||||
|
||||
_sourceUrlChanged = true;
|
||||
_voxelVolumeSizeChanged = true;
|
||||
|
@ -1862,7 +2042,9 @@ void EntityItemProperties::markAllChanged() {
|
|||
_actionDataChanged = true;
|
||||
|
||||
_normalsChanged = true;
|
||||
_strokeColorsChanged = true;
|
||||
_strokeWidthsChanged = true;
|
||||
_isUVModeStretchChanged = true;
|
||||
|
||||
_xTextureURLChanged = true;
|
||||
_yTextureURLChanged = true;
|
||||
|
@ -2181,6 +2363,11 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
if (backgroundModeChanged()) {
|
||||
out += "backgroundMode";
|
||||
}
|
||||
|
||||
if (hazeModeChanged()) {
|
||||
out += "hazeMode";
|
||||
}
|
||||
|
||||
if (voxelVolumeSizeChanged()) {
|
||||
out += "voxelVolumeSize";
|
||||
}
|
||||
|
@ -2272,10 +2459,19 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
out += "shape";
|
||||
}
|
||||
|
||||
if (strokeColorsChanged()) {
|
||||
out += "strokeColors";
|
||||
}
|
||||
|
||||
if (isUVModeStretchChanged()) {
|
||||
out += "isUVModeStretch";
|
||||
}
|
||||
|
||||
getAnimation().listChangedProperties(out);
|
||||
getKeyLight().listChangedProperties(out);
|
||||
getSkybox().listChangedProperties(out);
|
||||
getStage().listChangedProperties(out);
|
||||
getHaze().listChangedProperties(out);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "PolyVoxEntityItem.h"
|
||||
#include "SimulationOwner.h"
|
||||
#include "SkyboxPropertyGroup.h"
|
||||
#include "HazePropertyGroup.h"
|
||||
#include "StagePropertyGroup.h"
|
||||
#include "TextEntityItem.h"
|
||||
#include "ZoneEntityItem.h"
|
||||
|
@ -177,7 +178,11 @@ public:
|
|||
DEFINE_PROPERTY_REF(PROP_NAME, Name, name, QString, ENTITY_ITEM_DEFAULT_NAME);
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_BACKGROUND_MODE, BackgroundMode, backgroundMode, BackgroundMode, BACKGROUND_MODE_INHERIT);
|
||||
DEFINE_PROPERTY_GROUP(Stage, stage, StagePropertyGroup);
|
||||
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_HAZE_MODE, HazeMode, hazeMode, uint32_t, (uint32_t)COMPONENT_MODE_INHERIT);
|
||||
|
||||
DEFINE_PROPERTY_GROUP(Skybox, skybox, SkyboxPropertyGroup);
|
||||
DEFINE_PROPERTY_GROUP(Haze, haze, HazePropertyGroup);
|
||||
DEFINE_PROPERTY_GROUP(Animation, animation, AnimationPropertyGroup);
|
||||
DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString, "");
|
||||
DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float, LineEntityItem::DEFAULT_LINE_WIDTH);
|
||||
|
@ -186,8 +191,10 @@ public:
|
|||
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString, "");
|
||||
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool, TextEntityItem::DEFAULT_FACE_CAMERA);
|
||||
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray, QByteArray());
|
||||
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>, QVector<glm::vec3>());
|
||||
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
|
||||
DEFINE_PROPERTY(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
|
||||
DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>, QVector<float>());
|
||||
DEFINE_PROPERTY(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, bool, true);
|
||||
DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString, "");
|
||||
DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString, "");
|
||||
DEFINE_PROPERTY_REF(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString, "");
|
||||
|
@ -239,6 +246,7 @@ public:
|
|||
DEFINE_PROPERTY_REF(PROP_SERVER_SCRIPTS, ServerScripts, serverScripts, QString, ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS);
|
||||
|
||||
static QString getBackgroundModeString(BackgroundMode mode);
|
||||
static QString getHazeModeString(uint32_t mode);
|
||||
|
||||
|
||||
public:
|
||||
|
@ -316,6 +324,17 @@ public:
|
|||
bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; }
|
||||
void setRenderInfoHasTransparent(bool value) { _renderInfoHasTransparent = value; }
|
||||
|
||||
void setPackedNormals(const QByteArray& value);
|
||||
QVector<glm::vec3> unpackNormals(const QByteArray& normals);
|
||||
|
||||
void setPackedStrokeColors(const QByteArray& value);
|
||||
QVector<glm::vec3> unpackStrokeColors(const QByteArray& strokeColors);
|
||||
|
||||
QByteArray getPackedNormals() const;
|
||||
QByteArray packNormals(const QVector<glm::vec3>& normals) const;
|
||||
|
||||
QByteArray getPackedStrokeColors() const;
|
||||
QByteArray packStrokeColors(const QVector<glm::vec3>& strokeColors) const;
|
||||
|
||||
protected:
|
||||
QString getCollisionMaskAsString() const;
|
||||
|
@ -451,6 +470,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
|
|||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, CertificateID, certificateID, "");
|
||||
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundMode, backgroundMode, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, HazeMode, hazeMode, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelVolumeSize, voxelVolumeSize, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelData, voxelData, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelSurfaceStyle, voxelSurfaceStyle, "");
|
||||
|
|
|
@ -24,6 +24,8 @@ const glm::vec3 ENTITY_ITEM_ZERO_VEC3 = glm::vec3(0.0f);
|
|||
const glm::vec3 ENTITY_ITEM_ONE_VEC3 = glm::vec3(1.0f);
|
||||
const glm::vec3 ENTITY_ITEM_HALF_VEC3 = glm::vec3(0.5f);
|
||||
|
||||
const QVector<glm::vec3> ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC = QVector<glm::vec3>();
|
||||
|
||||
const bool ENTITY_ITEM_DEFAULT_LOCKED = false;
|
||||
const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString("");
|
||||
const QUuid ENTITY_ITEM_DEFAULT_SIMULATOR_ID = QUuid();
|
||||
|
|
|
@ -109,7 +109,9 @@ enum EntityPropertyList {
|
|||
|
||||
// Used by PolyLine entity
|
||||
PROP_NORMALS,
|
||||
PROP_STROKE_COLORS,
|
||||
PROP_STROKE_WIDTHS,
|
||||
PROP_IS_UV_MODE_STRETCH,
|
||||
|
||||
// used by particles
|
||||
PROP_SPEED_SPREAD,
|
||||
|
@ -231,6 +233,25 @@ enum EntityPropertyList {
|
|||
PROP_STAGE_HOUR = PROP_QUADRATIC_ATTENUATION_UNUSED,
|
||||
PROP_STAGE_AUTOMATIC_HOURDAY = PROP_ANIMATION_FRAME_INDEX,
|
||||
PROP_BACKGROUND_MODE = PROP_MODEL_URL,
|
||||
|
||||
PROP_HAZE_MODE = PROP_COLOR,
|
||||
|
||||
PROP_HAZE_RANGE = PROP_INTENSITY,
|
||||
PROP_HAZE_COLOR = PROP_CUTOFF,
|
||||
PROP_HAZE_GLARE_COLOR = PROP_EXPONENT,
|
||||
PROP_HAZE_ENABLE_GLARE = PROP_IS_SPOTLIGHT,
|
||||
PROP_HAZE_GLARE_ANGLE = PROP_DIFFUSE_COLOR,
|
||||
|
||||
PROP_HAZE_ALTITUDE_EFFECT = PROP_AMBIENT_COLOR_UNUSED,
|
||||
PROP_HAZE_CEILING = PROP_SPECULAR_COLOR_UNUSED,
|
||||
PROP_HAZE_BASE_REF = PROP_LINEAR_ATTENUATION_UNUSED,
|
||||
|
||||
PROP_HAZE_BACKGROUND_BLEND = PROP_QUADRATIC_ATTENUATION_UNUSED,
|
||||
|
||||
PROP_HAZE_ATTENUATE_KEYLIGHT = PROP_ANIMATION_FRAME_INDEX,
|
||||
PROP_HAZE_KEYLIGHT_RANGE = PROP_MODEL_URL,
|
||||
PROP_HAZE_KEYLIGHT_ALTITUDE = PROP_ANIMATION_URL,
|
||||
|
||||
PROP_SKYBOX_COLOR = PROP_ANIMATION_URL,
|
||||
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
|
||||
PROP_KEYLIGHT_AMBIENT_URL = PROP_ANIMATION_PLAYING,
|
||||
|
|
|
@ -566,6 +566,11 @@ void EntityScriptingInterface::callEntityMethod(QUuid id, const QString& method,
|
|||
}
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::callEntityServerMethod(QUuid id, const QString& method, const QStringList& params) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
DependencyManager::get<EntityScriptClient>()->callEntityServerMethod(id, method, params);
|
||||
}
|
||||
|
||||
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
|
|
|
@ -188,11 +188,11 @@ public slots:
|
|||
*/
|
||||
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
||||
|
||||
/// Allows a script to call a method on an entity's script. The method will execute in the entity script
|
||||
/// engine. If the entity does not have an entity script or the method does not exist, this call will have
|
||||
/// no effect.
|
||||
/**jsdoc
|
||||
* Call a method on an entity. If it is running an entity script (specified by the `script` property)
|
||||
* Call a method on an entity. Allows a script to call a method on an entity's script.
|
||||
* The method will execute in the entity script engine. If the entity does not have an
|
||||
* entity script or the method does not exist, this call will have no effect.
|
||||
* If it is running an entity script (specified by the `script` property)
|
||||
* and it exposes a property with the specified name `method`, it will be called
|
||||
* using `params` as the list of arguments.
|
||||
*
|
||||
|
@ -203,10 +203,29 @@ public slots:
|
|||
*/
|
||||
Q_INVOKABLE void callEntityMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
||||
|
||||
/// finds the closest model to the center point, within the radius
|
||||
/// will return a EntityItemID.isKnownID = false if no models are in the radius
|
||||
/// this function will not find any models in script engine contexts which don't have access to models
|
||||
/**jsdoc
|
||||
* Call a server method on an entity. Allows a client entity script to call a method on an
|
||||
* entity's server script. The method will execute in the entity server script engine. If
|
||||
* the entity does not have an entity server script or the method does not exist, this call will
|
||||
* have no effect. If the entity is running an entity script (specified by the `serverScripts` property)
|
||||
* and it exposes a property with the specified name `method`, it will be called using `params` as
|
||||
* the list of arguments.
|
||||
*
|
||||
* @function Entities.callEntityServerMethod
|
||||
* @param {EntityID} entityID The ID of the entity to call the method on.
|
||||
* @param {string} method The name of the method to call.
|
||||
* @param {string[]} params The list of parameters to call the specified method with.
|
||||
*/
|
||||
Q_INVOKABLE void callEntityServerMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
||||
|
||||
/**jsdoc
|
||||
* finds the closest model to the center point, within the radius
|
||||
* will return a EntityItemID.isKnownID = false if no models are in the radius
|
||||
* this function will not find any models in script engine contexts which don't have access to models
|
||||
* @function Entities.findClosestEntity
|
||||
* @param {vec3} center point
|
||||
* @param {float} radius to search
|
||||
* @return {EntityID} The EntityID of the entity that is closest and in the radius.
|
||||
*/
|
||||
Q_INVOKABLE QUuid findClosestEntity(const glm::vec3& center, float radius) const;
|
||||
|
||||
|
|
|
@ -9,9 +9,11 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <AACube.h>
|
||||
|
||||
#include "EntitySimulation.h"
|
||||
|
||||
#include <AACube.h>
|
||||
#include <Profile.h>
|
||||
|
||||
#include "EntitiesLogging.h"
|
||||
#include "MovingEntitiesOperator.h"
|
||||
|
||||
|
@ -27,6 +29,7 @@ void EntitySimulation::setEntityTree(EntityTreePointer tree) {
|
|||
}
|
||||
|
||||
void EntitySimulation::updateEntities() {
|
||||
PROFILE_RANGE(simulation_physics, "ES::updateEntities");
|
||||
QMutexLocker lock(&_mutex);
|
||||
quint64 now = usecTimestampNow();
|
||||
|
||||
|
@ -35,8 +38,12 @@ void EntitySimulation::updateEntities() {
|
|||
callUpdateOnEntitiesThatNeedIt(now);
|
||||
moveSimpleKinematics(now);
|
||||
updateEntitiesInternal(now);
|
||||
PerformanceTimer perfTimer("sortingEntities");
|
||||
sortEntitiesThatMoved();
|
||||
|
||||
{
|
||||
PROFILE_RANGE(simulation_physics, "Sort");
|
||||
PerformanceTimer perfTimer("sortingEntities");
|
||||
sortEntitiesThatMoved();
|
||||
}
|
||||
}
|
||||
|
||||
void EntitySimulation::takeEntitiesToDelete(VectorOfEntities& entitiesToDelete) {
|
||||
|
@ -258,6 +265,7 @@ void EntitySimulation::clearEntities() {
|
|||
}
|
||||
|
||||
void EntitySimulation::moveSimpleKinematics(const quint64& now) {
|
||||
PROFILE_RANGE_EX(simulation_physics, "Kinematics", 0xffff00ff, (uint64_t)_simpleKinematicEntities.size());
|
||||
SetOfEntities::iterator itemItr = _simpleKinematicEntities.begin();
|
||||
while (itemItr != _simpleKinematicEntities.end()) {
|
||||
EntityItemPointer entity = *itemItr;
|
||||
|
|
|
@ -15,8 +15,9 @@
|
|||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <Extents.h>
|
||||
#include <PerfStat.h>
|
||||
#include <Profile.h>
|
||||
|
||||
#include "EntitySimulation.h"
|
||||
#include "VariantMapToScriptValue.h"
|
||||
|
@ -1370,6 +1371,7 @@ void EntityTree::entityChanged(EntityItemPointer entity) {
|
|||
|
||||
|
||||
void EntityTree::fixupNeedsParentFixups() {
|
||||
PROFILE_RANGE(simulation_physics, "FixupParents");
|
||||
MovingEntitiesOperator moveOperator;
|
||||
|
||||
QWriteLocker locker(&_needsParentFixupLock);
|
||||
|
@ -1459,6 +1461,7 @@ void EntityTree::addToNeedsParentFixupList(EntityItemPointer entity) {
|
|||
}
|
||||
|
||||
void EntityTree::update(bool simulate) {
|
||||
PROFILE_RANGE(simulation_physics, "ET::update");
|
||||
fixupNeedsParentFixups();
|
||||
if (simulate && _simulation) {
|
||||
withWriteLock([&] {
|
||||
|
|
373
libraries/entities/src/HazePropertyGroup.cpp
Normal file
|
@ -0,0 +1,373 @@
|
|||
//
|
||||
// HazePropertyGroup.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Nissim hadar on 9/21/17.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <OctreePacketData.h>
|
||||
|
||||
#include "HazePropertyGroup.h"
|
||||
#include "EntityItemProperties.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_RANGE{ 1000.0f };
|
||||
const xColor HazePropertyGroup::DEFAULT_HAZE_COLOR{ 128, 154, 179 }; // Bluish
|
||||
const xColor HazePropertyGroup::DEFAULT_HAZE_GLARE_COLOR{ 255, 229, 179 }; // Yellowish
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_GLARE_ANGLE{ 20.0 };
|
||||
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_CEILING{ 200.0f };
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_BASE_REF{ 0.0f };
|
||||
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_BACKGROUND_BLEND{ 0.0f };
|
||||
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_KEYLIGHT_RANGE{ 1000.0 };
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_KEYLIGHT_ALTITUDE{ 200.0f };
|
||||
|
||||
void HazePropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_RANGE, Haze, haze, HazeRange, hazeRange);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_COLOR, Haze, haze, HazeColor, hazeColor);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_GLARE_COLOR, Haze, haze, HazeGlareColor, hazeGlareColor);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_ENABLE_GLARE, Haze, haze, HazeEnableGlare, hazeEnableGlare);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_GLARE_ANGLE, Haze, haze, HazeGlareAngle, hazeGlareAngle);
|
||||
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_ALTITUDE_EFFECT, Haze, haze, HazeAltitudeEffect, hazeAltitudeEffect);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_CEILING, Haze, haze, HazeCeiling, hazeCeiling);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_BASE_REF, Haze, haze, HazeBaseRef, hazeBaseRef);
|
||||
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_BACKGROUND_BLEND, Haze, haze, HazeBackgroundBlend, hazeBackgroundBlend);
|
||||
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_ATTENUATE_KEYLIGHT, Haze, haze, HazeAttenuateKeyLight, hazeAttenuateKeyLight);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_KEYLIGHT_RANGE, Haze, haze, HazeKeyLightRange, hazeKeyLightRange);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_KEYLIGHT_ALTITUDE, Haze, haze, HazeKeyLightAltitude, hazeKeyLightAltitude);
|
||||
}
|
||||
|
||||
void HazePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeRange, float, setHazeRange);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeColor, xColor, setHazeColor);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeGlareColor, xColor, setHazeGlareColor);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeEnableGlare, bool, setHazeEnableGlare);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeGlareAngle, float, setHazeGlareAngle);
|
||||
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeAltitudeEffect, bool, setHazeAltitudeEffect);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeCeiling, float, setHazeCeiling);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeBaseRef, float, setHazeBaseRef);
|
||||
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeBackgroundBlend, float, setHazeBackgroundBlend);
|
||||
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeAttenuateKeyLight, bool, setHazeAttenuateKeyLight);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeKeyLightRange, float, setHazeKeyLightRange);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeKeyLightAltitude, float, setHazeKeyLightAltitude);
|
||||
}
|
||||
|
||||
void HazePropertyGroup::merge(const HazePropertyGroup& other) {
|
||||
COPY_PROPERTY_IF_CHANGED(hazeRange);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeColor);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeGlareColor);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeEnableGlare);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeGlareAngle);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(hazeAltitudeEffect);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeCeiling);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeBaseRef);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(hazeBackgroundBlend);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(hazeAttenuateKeyLight);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeKeyLightRange);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeKeyLightAltitude);
|
||||
}
|
||||
|
||||
void HazePropertyGroup::debugDump() const {
|
||||
qCDebug(entities) << " HazePropertyGroup: ---------------------------------------------";
|
||||
|
||||
qCDebug(entities) << " _hazeRange:" << _hazeRange;
|
||||
qCDebug(entities) << " _hazeColor:" << _hazeColor;
|
||||
qCDebug(entities) << " _hazeGlareColor:" << _hazeGlareColor;
|
||||
qCDebug(entities) << " _hazeEnableGlare:" << _hazeEnableGlare;
|
||||
qCDebug(entities) << " _hazeGlareAngle:" << _hazeGlareAngle;
|
||||
|
||||
qCDebug(entities) << " _hazeAltitudeEffect:" << _hazeAltitudeEffect;
|
||||
qCDebug(entities) << " _hazeCeiling:" << _hazeCeiling;
|
||||
qCDebug(entities) << " _hazeBaseRef:" << _hazeBaseRef;
|
||||
|
||||
qCDebug(entities) << " _hazeBackgroundBlend:" << _hazeBackgroundBlend;
|
||||
|
||||
qCDebug(entities) << " _hazeAttenuateKeyLight:" << _hazeAttenuateKeyLight;
|
||||
qCDebug(entities) << " _hazeKeyLightRange:" << _hazeKeyLightRange;
|
||||
qCDebug(entities) << " _hazeKeyLightAltitude:" << _hazeKeyLightAltitude;
|
||||
}
|
||||
|
||||
void HazePropertyGroup::listChangedProperties(QList<QString>& out) {
|
||||
if (hazeRangeChanged()) {
|
||||
out << "haze-hazeRange";
|
||||
}
|
||||
if (hazeColorChanged()) {
|
||||
out << "haze-hazeColor";
|
||||
}
|
||||
if (hazeGlareColorChanged()) {
|
||||
out << "haze-hazeGlareColor";
|
||||
}
|
||||
if (hazeEnableGlareChanged()) {
|
||||
out << "haze-hazeEnableGlare";
|
||||
}
|
||||
if (hazeGlareAngleChanged()) {
|
||||
out << "haze-hazeGlareAngle";
|
||||
}
|
||||
|
||||
if (hazeAltitudeEffectChanged()) {
|
||||
out << "haze-hazeAltitudeEffect";
|
||||
}
|
||||
if (hazeCeilingChanged()) {
|
||||
out << "haze-hazeCeiling";
|
||||
}
|
||||
if (hazeBaseRefChanged()) {
|
||||
out << "haze-hazeBaseRef";
|
||||
}
|
||||
|
||||
if (hazeBackgroundBlendChanged()) {
|
||||
out << "haze-hazeBackgroundBlend";
|
||||
}
|
||||
|
||||
if (hazeAttenuateKeyLightChanged()) {
|
||||
out << "haze-hazeAttenuateKeyLight";
|
||||
}
|
||||
if (hazeKeyLightRangeChanged()) {
|
||||
out << "haze-hazeKeyLightRange";
|
||||
}
|
||||
if (hazeKeyLightAltitudeChanged()) {
|
||||
out << "haze-hazeKeyLightAltitude";
|
||||
}
|
||||
}
|
||||
|
||||
bool HazePropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_RANGE, getHazeRange());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_COLOR, getHazeColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, getHazeGlareColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ENABLE_GLARE, getHazeEnableGlare());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_GLARE_ANGLE, getHazeGlareAngle());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ALTITUDE_EFFECT, getHazeAltitudeEffect());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_CEILING, getHazeCeiling());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_BASE_REF, getHazeBaseRef());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_BACKGROUND_BLEND, getHazeBackgroundBlend());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ATTENUATE_KEYLIGHT, getHazeAttenuateKeyLight());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_RANGE, getHazeKeyLightRange());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_ALTITUDE, getHazeKeyLightAltitude());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HazePropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) {
|
||||
|
||||
int bytesRead = 0;
|
||||
bool overwriteLocalData = true;
|
||||
bool somethingChanged = false;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_RANGE, float, setHazeRange);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_COLOR, xColor, setHazeColor);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, xColor, setHazeGlareColor);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ENABLE_GLARE, bool, setHazeEnableGlare);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_ANGLE, float, setHazeGlareAngle);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ALTITUDE_EFFECT, bool, setHazeAltitudeEffect);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_CEILING, float, setHazeCeiling);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_BASE_REF, float, setHazeBaseRef);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_BACKGROUND_BLEND, float, setHazeBackgroundBlend);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ATTENUATE_KEYLIGHT, bool, setHazeAttenuateKeyLight);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_RANGE, float, setHazeKeyLightRange);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_ALTITUDE, float, setHazeKeyLightAltitude);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_RANGE, HazeRange);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_COLOR, HazeColor);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_GLARE_COLOR, HazeGlareColor);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_ENABLE_GLARE, HazeEnableGlare);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_GLARE_ANGLE, HazeGlareAngle);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_ALTITUDE_EFFECT, HazeAltitudeEffect);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_CEILING, HazeCeiling);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_BASE_REF, HazeBaseRef);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_BACKGROUND_BLEND, HazeBackgroundBlend);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_ATTENUATE_KEYLIGHT, HazeAttenuateKeyLight);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_KEYLIGHT_RANGE, HazeKeyLightRange);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_KEYLIGHT_ALTITUDE, HazeKeyLightAltitude);
|
||||
|
||||
processedBytes += bytesRead;
|
||||
|
||||
Q_UNUSED(somethingChanged);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HazePropertyGroup::markAllChanged() {
|
||||
_hazeRangeChanged = true;
|
||||
_hazeColorChanged = true;
|
||||
_hazeGlareColorChanged = true;
|
||||
_hazeEnableGlareChanged = true;
|
||||
_hazeGlareAngleChanged = true;
|
||||
|
||||
_hazeAltitudeEffectChanged = true;
|
||||
_hazeCeilingChanged = true;
|
||||
_hazeBaseRefChanged = true;
|
||||
|
||||
_hazeBackgroundBlendChanged = true;
|
||||
|
||||
_hazeAttenuateKeyLightChanged = true;
|
||||
_hazeKeyLightRangeChanged = true;
|
||||
_hazeKeyLightAltitudeChanged = true;
|
||||
}
|
||||
|
||||
EntityPropertyFlags HazePropertyGroup::getChangedProperties() const {
|
||||
EntityPropertyFlags changedProperties;
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_RANGE, hazeRange);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_COLOR, hazeColor);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_GLARE_COLOR, hazeGlareColor);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_ENABLE_GLARE, hazeEnableGlare);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_GLARE_ANGLE, hazeGlareAngle);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_ALTITUDE_EFFECT, hazeAltitudeEffect);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_CEILING, hazeCeiling);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_BASE_REF, hazeBaseRef);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_BACKGROUND_BLEND, hazeBackgroundBlend);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_ATTENUATE_KEYLIGHT, hazeAttenuateKeyLight);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_KEYLIGHT_RANGE, hazeKeyLightRange);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_KEYLIGHT_ALTITUDE, hazeKeyLightAltitude);
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
||||
void HazePropertyGroup::getProperties(EntityItemProperties& properties) const {
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeRange, getHazeRange);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeColor, getHazeColor);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeGlareColor, getHazeGlareColor);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeEnableGlare, getHazeEnableGlare);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeGlareAngle, getHazeGlareAngle);
|
||||
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeAltitudeEffect, getHazeAltitudeEffect);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeCeiling, getHazeCeiling);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeBaseRef, getHazeBaseRef);
|
||||
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeBackgroundBlend, getHazeBackgroundBlend);
|
||||
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeAttenuateKeyLight, getHazeAttenuateKeyLight);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeKeyLightRange, getHazeKeyLightRange);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeKeyLightAltitude, getHazeKeyLightAltitude);
|
||||
}
|
||||
|
||||
bool HazePropertyGroup::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = false;
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeRange, hazeRange, setHazeRange);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeColor, hazeColor, setHazeColor);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeGlareColor, hazeGlareColor, setHazeGlareColor);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeEnableGlare, hazeEnableGlare, setHazeEnableGlare);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeGlareAngle, hazeGlareAngle, setHazeGlareAngle);
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeAltitudeEffect, hazeAltitudeEffect, setHazeAltitudeEffect);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeCeiling, hazeCeiling, setHazeCeiling);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeBaseRef, hazeBaseRef, setHazeBaseRef);
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeBackgroundBlend, hazeBackgroundBlend, setHazeBackgroundBlend);
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeAttenuateKeyLight, hazeAttenuateKeyLight, setHazeAttenuateKeyLight);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeKeyLightRange, hazeKeyLightRange, setHazeKeyLightRange);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeKeyLightAltitude, hazeKeyLightAltitude, setHazeKeyLightAltitude);
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
||||
EntityPropertyFlags HazePropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const {
|
||||
EntityPropertyFlags requestedProperties;
|
||||
|
||||
requestedProperties += PROP_HAZE_RANGE;
|
||||
requestedProperties += PROP_HAZE_COLOR;
|
||||
requestedProperties += PROP_HAZE_GLARE_COLOR;
|
||||
requestedProperties += PROP_HAZE_ENABLE_GLARE;
|
||||
requestedProperties += PROP_HAZE_GLARE_ANGLE;
|
||||
|
||||
requestedProperties += PROP_HAZE_CEILING;
|
||||
requestedProperties += PROP_HAZE_BASE_REF;
|
||||
|
||||
requestedProperties += PROP_HAZE_BACKGROUND_BLEND;
|
||||
|
||||
requestedProperties += PROP_HAZE_ATTENUATE_KEYLIGHT;
|
||||
requestedProperties += PROP_HAZE_KEYLIGHT_RANGE;
|
||||
requestedProperties += PROP_HAZE_KEYLIGHT_ALTITUDE;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
void HazePropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_RANGE, getHazeRange());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_COLOR, getHazeColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, getHazeGlareColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ENABLE_GLARE, getHazeEnableGlare());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_GLARE_ANGLE, getHazeGlareAngle());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ALTITUDE_EFFECT, getHazeAltitudeEffect());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_CEILING, getHazeCeiling());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_BASE_REF, getHazeBaseRef());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_BACKGROUND_BLEND, getHazeBackgroundBlend());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ATTENUATE_KEYLIGHT, getHazeAttenuateKeyLight());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_RANGE, getHazeKeyLightRange());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_ALTITUDE, getHazeKeyLightAltitude());
|
||||
}
|
||||
|
||||
int HazePropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) {
|
||||
|
||||
int bytesRead = 0;
|
||||
const unsigned char* dataAt = data;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_RANGE, float, setHazeRange);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_COLOR, xColor, setHazeColor);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, xColor, setHazeGlareColor);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ENABLE_GLARE, bool, setHazeEnableGlare);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_ANGLE, float, setHazeGlareAngle);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ALTITUDE_EFFECT, bool, setHazeAltitudeEffect);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_CEILING, float, setHazeCeiling);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_BASE_REF, float, setHazeBaseRef);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_BACKGROUND_BLEND, float, setHazeBackgroundBlend);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ATTENUATE_KEYLIGHT, bool, setHazeAttenuateKeyLight);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_RANGE, float, setHazeKeyLightRange);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_ALTITUDE, float, setHazeKeyLightAltitude);
|
||||
|
||||
return bytesRead;
|
||||
}
|
111
libraries/entities/src/HazePropertyGroup.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
//
|
||||
// HazePropertyGroup.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Nissim hadar on 9/21/17.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_HazePropertyGroup_h
|
||||
#define hifi_HazePropertyGroup_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include "PropertyGroup.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
class EntityItemProperties;
|
||||
class EncodeBitstreamParams;
|
||||
class OctreePacketData;
|
||||
class EntityTreeElementExtraEncodeData;
|
||||
class ReadBitstreamToTreeParams;
|
||||
|
||||
class HazePropertyGroup : public PropertyGroup {
|
||||
public:
|
||||
// EntityItemProperty related helpers
|
||||
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties,
|
||||
QScriptEngine* engine, bool skipDefaults,
|
||||
EntityItemProperties& defaultEntityProperties) const override;
|
||||
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) override;
|
||||
|
||||
void merge(const HazePropertyGroup& other);
|
||||
|
||||
virtual void debugDump() const override;
|
||||
virtual void listChangedProperties(QList<QString>& out) override;
|
||||
|
||||
virtual bool appendToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const override;
|
||||
|
||||
virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags,
|
||||
const unsigned char*& dataAt, int& processedBytes) override;
|
||||
virtual void markAllChanged() override;
|
||||
virtual EntityPropertyFlags getChangedProperties() const override;
|
||||
|
||||
// EntityItem related helpers
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual void getProperties(EntityItemProperties& propertiesOut) const override;
|
||||
|
||||
/// returns true if something changed
|
||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||
|
||||
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const override;
|
||||
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) override;
|
||||
|
||||
static const float DEFAULT_HAZE_RANGE;
|
||||
static const xColor DEFAULT_HAZE_COLOR;
|
||||
static const xColor DEFAULT_HAZE_GLARE_COLOR;
|
||||
static const float DEFAULT_HAZE_GLARE_ANGLE;
|
||||
|
||||
static const float DEFAULT_HAZE_CEILING;
|
||||
static const float DEFAULT_HAZE_BASE_REF;
|
||||
|
||||
static const float DEFAULT_HAZE_BACKGROUND_BLEND;
|
||||
|
||||
static const float DEFAULT_HAZE_KEYLIGHT_RANGE;
|
||||
static const float DEFAULT_HAZE_KEYLIGHT_ALTITUDE;
|
||||
|
||||
// Range only parameters
|
||||
DEFINE_PROPERTY(PROP_HAZE_RANGE, HazeRange, hazeRange, float, DEFAULT_HAZE_RANGE);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_COLOR, HazeColor, hazeColor, xColor, DEFAULT_HAZE_COLOR);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_GLARE_COLOR, HazeGlareColor, hazeGlareColor, xColor, DEFAULT_HAZE_GLARE_COLOR);
|
||||
DEFINE_PROPERTY(PROP_HAZE_ENABLE_GLARE, HazeEnableGlare, hazeEnableGlare, bool, false);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_GLARE_ANGLE, HazeGlareAngle, hazeGlareAngle, float, DEFAULT_HAZE_GLARE_ANGLE);
|
||||
|
||||
// Altitude parameters
|
||||
DEFINE_PROPERTY(PROP_HAZE_ALTITUDE_EFFECT, HazeAltitudeEffect, hazeAltitudeEffect, bool, false);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_CEILING, HazeCeiling, hazeCeiling, float, DEFAULT_HAZE_CEILING);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_BASE_REF, HazeBaseRef, hazeBaseRef, float, DEFAULT_HAZE_BASE_REF);
|
||||
|
||||
// Background (skybox) blend value
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_BACKGROUND_BLEND, HazeBackgroundBlend, hazeBackgroundBlend, float, DEFAULT_HAZE_BACKGROUND_BLEND);
|
||||
|
||||
// hazeDirectional light attenuation
|
||||
DEFINE_PROPERTY(PROP_HAZE_ATTENUATE_KEYLIGHT, HazeAttenuateKeyLight, hazeAttenuateKeyLight, bool, false);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_KEYLIGHT_RANGE, HazeKeyLightRange, hazeKeyLightRange, float, DEFAULT_HAZE_KEYLIGHT_RANGE);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_KEYLIGHT_ALTITUDE, HazeKeyLightAltitude, hazeKeyLightAltitude, float, DEFAULT_HAZE_KEYLIGHT_ALTITUDE);
|
||||
};
|
||||
|
||||
#endif // hifi_HazePropertyGroup_h
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// KeyLightPropertyGroup.h
|
||||
// KeyLightPropertyGroup.cpp
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Sam Gateau on 2015/10/23.
|
||||
|
|
|
@ -557,12 +557,6 @@ void ModelEntityItem::setAnimationLoop(bool loop) {
|
|||
});
|
||||
}
|
||||
|
||||
bool ModelEntityItem::getAnimationLoop() const {
|
||||
return resultWithReadLock<bool>([&] {
|
||||
return _animationProperties.getLoop();
|
||||
});
|
||||
}
|
||||
|
||||
void ModelEntityItem::setAnimationHold(bool hold) {
|
||||
withWriteLock([&] {
|
||||
_animationProperties.setHold(hold);
|
||||
|
@ -610,8 +604,10 @@ float ModelEntityItem::getAnimationCurrentFrame() const {
|
|||
});
|
||||
}
|
||||
|
||||
float ModelEntityItem::getAnimationFPS() const {
|
||||
bool ModelEntityItem::isAnimatingSomething() const {
|
||||
return resultWithReadLock<float>([&] {
|
||||
return _animationProperties.getFPS();
|
||||
});
|
||||
return !_animationProperties.getURL().isEmpty() &&
|
||||
_animationProperties.getRunning() &&
|
||||
(_animationProperties.getFPS() != 0.0f);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -90,7 +90,6 @@ public:
|
|||
bool getAnimationAllowTranslation() const { return _animationProperties.getAllowTranslation(); };
|
||||
|
||||
void setAnimationLoop(bool loop);
|
||||
bool getAnimationLoop() const;
|
||||
|
||||
void setAnimationHold(bool hold);
|
||||
bool getAnimationHold() const;
|
||||
|
@ -101,10 +100,9 @@ public:
|
|||
void setAnimationLastFrame(float lastFrame);
|
||||
float getAnimationLastFrame() const;
|
||||
|
||||
|
||||
bool getAnimationIsPlaying() const;
|
||||
float getAnimationCurrentFrame() const;
|
||||
float getAnimationFPS() const;
|
||||
bool isAnimatingSomething() const;
|
||||
|
||||
static const QString DEFAULT_TEXTURES;
|
||||
const QString getTextures() const;
|
||||
|
@ -123,7 +121,6 @@ public:
|
|||
QVector<bool> getJointRotationsSet() const;
|
||||
QVector<glm::vec3> getJointTranslations() const;
|
||||
QVector<bool> getJointTranslationsSet() const;
|
||||
bool isAnimatingSomething() const;
|
||||
|
||||
private:
|
||||
void setAnimationSettings(const QString& value); // only called for old bitstream format
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "PolyLineEntityItem.h"
|
||||
|
||||
const float PolyLineEntityItem::DEFAULT_LINE_WIDTH = 0.1f;
|
||||
const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 70;
|
||||
const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 60;
|
||||
|
||||
|
||||
EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
|
@ -31,6 +31,7 @@ EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, cons
|
|||
return entity;
|
||||
}
|
||||
|
||||
|
||||
PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) {
|
||||
_type = EntityTypes::PolyLine;
|
||||
}
|
||||
|
@ -42,12 +43,15 @@ EntityItemProperties PolyLineEntityItem::getProperties(EntityPropertyFlags desir
|
|||
|
||||
properties._color = getXColor();
|
||||
properties._colorChanged = false;
|
||||
|
||||
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeColors, getStrokeColors);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(isUVModeStretch, getIsUVModeStretch);
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -60,8 +64,10 @@ bool PolyLineEntityItem::setProperties(const EntityItemProperties& properties) {
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeColors, setStrokeColors);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(isUVModeStretch, setIsUVModeStretch);
|
||||
|
||||
if (somethingChanged) {
|
||||
bool wantDebug = false;
|
||||
|
@ -108,6 +114,15 @@ bool PolyLineEntityItem::setNormals(const QVector<glm::vec3>& normals) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PolyLineEntityItem::setStrokeColors(const QVector<glm::vec3>& strokeColors) {
|
||||
withWriteLock([&] {
|
||||
_strokeColors = strokeColors;
|
||||
_strokeColorsChanged = true;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PolyLineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
|
||||
if (points.size() > MAX_POINTS_PER_LINE) {
|
||||
return false;
|
||||
|
@ -193,8 +208,10 @@ int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da
|
|||
READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth);
|
||||
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||
READ_ENTITY_PROPERTY(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
||||
READ_ENTITY_PROPERTY(PROP_STROKE_COLORS, QVector<glm::vec3>, setStrokeColors);
|
||||
READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
||||
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
|
||||
READ_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, bool, setIsUVModeStretch);
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
@ -207,8 +224,10 @@ EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParam
|
|||
requestedProperties += PROP_LINE_WIDTH;
|
||||
requestedProperties += PROP_LINE_POINTS;
|
||||
requestedProperties += PROP_NORMALS;
|
||||
requestedProperties += PROP_STROKE_COLORS;
|
||||
requestedProperties += PROP_STROKE_WIDTHS;
|
||||
requestedProperties += PROP_TEXTURES;
|
||||
requestedProperties += PROP_IS_UV_MODE_STRETCH;
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
|
@ -227,8 +246,10 @@ void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, Encode
|
|||
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth());
|
||||
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
|
||||
APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals());
|
||||
APPEND_ENTITY_PROPERTY(PROP_STROKE_COLORS, getStrokeColors());
|
||||
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths());
|
||||
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
|
||||
APPEND_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, getIsUVModeStretch());
|
||||
}
|
||||
|
||||
void PolyLineEntityItem::debugDump() const {
|
||||
|
@ -258,6 +279,14 @@ QVector<glm::vec3> PolyLineEntityItem::getNormals() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
QVector<glm::vec3> PolyLineEntityItem::getStrokeColors() const {
|
||||
QVector<glm::vec3> result;
|
||||
withReadLock([&] {
|
||||
result = _strokeColors;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
QVector<float> PolyLineEntityItem::getStrokeWidths() const {
|
||||
QVector<float> result;
|
||||
withReadLock([&] {
|
||||
|
|
|
@ -46,9 +46,11 @@ class PolyLineEntityItem : public EntityItem {
|
|||
xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; }
|
||||
|
||||
void setColor(const rgbColor& value) {
|
||||
_strokeColorsChanged = true;
|
||||
memcpy(_color, value, sizeof(_color));
|
||||
}
|
||||
void setColor(const xColor& value) {
|
||||
_strokeColorsChanged = true;
|
||||
_color[RED_INDEX] = value.red;
|
||||
_color[GREEN_INDEX] = value.green;
|
||||
_color[BLUE_INDEX] = value.blue;
|
||||
|
@ -64,9 +66,15 @@ class PolyLineEntityItem : public EntityItem {
|
|||
bool setNormals(const QVector<glm::vec3>& normals);
|
||||
QVector<glm::vec3> getNormals() const;
|
||||
|
||||
bool setStrokeColors(const QVector<glm::vec3>& strokeColors);
|
||||
QVector<glm::vec3> getStrokeColors() const;
|
||||
|
||||
bool setStrokeWidths(const QVector<float>& strokeWidths);
|
||||
QVector<float> getStrokeWidths() const;
|
||||
|
||||
void setIsUVModeStretch(bool isUVModeStretch){ _isUVModeStretch = isUVModeStretch; }
|
||||
bool getIsUVModeStretch() const{ return _isUVModeStretch; }
|
||||
|
||||
QString getTextures() const;
|
||||
void setTextures(const QString& textures);
|
||||
|
||||
|
@ -76,10 +84,11 @@ class PolyLineEntityItem : public EntityItem {
|
|||
|
||||
bool pointsChanged() const { return _pointsChanged; }
|
||||
bool normalsChanged() const { return _normalsChanged; }
|
||||
bool strokeColorsChanged() const { return _strokeColorsChanged; }
|
||||
bool strokeWidthsChanged() const { return _strokeWidthsChanged; }
|
||||
bool texturesChanged() const { return _texturesChangedFlag; }
|
||||
void resetTexturesChanged() { _texturesChangedFlag = false; }
|
||||
void resetPolyLineChanged() { _strokeWidthsChanged = _normalsChanged = _pointsChanged = false; }
|
||||
void resetPolyLineChanged() { _strokeColorsChanged = _strokeWidthsChanged = _normalsChanged = _pointsChanged = false; }
|
||||
|
||||
|
||||
// never have a ray intersection pick a PolyLineEntityItem.
|
||||
|
@ -103,11 +112,14 @@ private:
|
|||
float _lineWidth { DEFAULT_LINE_WIDTH };
|
||||
bool _pointsChanged { true };
|
||||
bool _normalsChanged { true };
|
||||
bool _strokeColorsChanged { true };
|
||||
bool _strokeWidthsChanged { true };
|
||||
QVector<glm::vec3> _points;
|
||||
QVector<glm::vec3> _normals;
|
||||
QVector<glm::vec3> _strokeColors;
|
||||
QVector<float> _strokeWidths;
|
||||
QString _textures;
|
||||
bool _isUVModeStretch;
|
||||
bool _texturesChangedFlag { false };
|
||||
mutable QReadWriteLock _quadReadWriteLock;
|
||||
};
|
||||
|
|
|
@ -69,6 +69,9 @@ EntityItemProperties ZoneEntityItem::getProperties(EntityPropertyFlags desiredPr
|
|||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ghostingAllowed, getGhostingAllowed);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(filterURL, getFilterURL);
|
||||
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(hazeMode, getHazeMode);
|
||||
_hazeProperties.getProperties(properties);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -104,16 +107,19 @@ bool ZoneEntityItem::setSubClassProperties(const EntityItemProperties& propertie
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(backgroundMode, setBackgroundMode);
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(flyingAllowed, setFlyingAllowed);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ghostingAllowed, setGhostingAllowed);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(filterURL, setFilterURL);
|
||||
|
||||
// Contains a QString property, must be synchronized
|
||||
withWriteLock([&] {
|
||||
_skyboxPropertiesChanged = _skyboxProperties.setProperties(properties);
|
||||
});
|
||||
|
||||
somethingChanged = somethingChanged || _keyLightPropertiesChanged || _stagePropertiesChanged || _skyboxPropertiesChanged;
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(flyingAllowed, setFlyingAllowed);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ghostingAllowed, setGhostingAllowed);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(filterURL, setFilterURL);
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(hazeMode, setHazeMode);
|
||||
_hazePropertiesChanged = _hazeProperties.setProperties(properties);
|
||||
|
||||
somethingChanged = somethingChanged || _keyLightPropertiesChanged || _stagePropertiesChanged || _skyboxPropertiesChanged || _hazePropertiesChanged;
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
@ -158,6 +164,15 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
|||
READ_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
||||
READ_ENTITY_PROPERTY(PROP_FILTER_URL, QString, setFilterURL);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_MODE, uint32_t, setHazeMode);
|
||||
|
||||
int bytesFromHaze = _hazeProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
propertyFlags, overwriteLocalData, _hazePropertiesChanged);
|
||||
|
||||
somethingChanged = somethingChanged || _hazePropertiesChanged;
|
||||
bytesRead += bytesFromHaze;
|
||||
dataAt += bytesFromHaze;
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
|
@ -170,10 +185,11 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p
|
|||
requestedProperties += _keyLightProperties.getEntityProperties(params);
|
||||
});
|
||||
|
||||
requestedProperties += _stageProperties.getEntityProperties(params);
|
||||
|
||||
requestedProperties += PROP_SHAPE_TYPE;
|
||||
requestedProperties += PROP_COMPOUND_SHAPE_URL;
|
||||
requestedProperties += PROP_BACKGROUND_MODE;
|
||||
requestedProperties += _stageProperties.getEntityProperties(params);
|
||||
|
||||
withReadLock([&] {
|
||||
requestedProperties += _skyboxProperties.getEntityProperties(params);
|
||||
|
@ -183,6 +199,9 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p
|
|||
requestedProperties += PROP_GHOSTING_ALLOWED;
|
||||
requestedProperties += PROP_FILTER_URL;
|
||||
|
||||
requestedProperties += PROP_HAZE_MODE;
|
||||
requestedProperties += _hazeProperties.getEntityProperties(params);
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
|
@ -208,11 +227,15 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
|
|||
APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, (uint32_t)getBackgroundMode()); // could this be a uint16??
|
||||
|
||||
_skyboxProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, getFlyingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, getGhostingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_FILTER_URL, getFilterURL());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_MODE, (uint32_t)getHazeMode());
|
||||
_hazeProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
}
|
||||
|
||||
void ZoneEntityItem::debugDump() const {
|
||||
|
@ -222,10 +245,12 @@ void ZoneEntityItem::debugDump() const {
|
|||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||
qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode);
|
||||
qCDebug(entities) << " _hazeMode:" << EntityItemProperties::getHazeModeString(_hazeMode);
|
||||
|
||||
_keyLightProperties.debugDump();
|
||||
_stageProperties.debugDump();
|
||||
_skyboxProperties.debugDump();
|
||||
_hazeProperties.debugDump();
|
||||
_stageProperties.debugDump();
|
||||
}
|
||||
|
||||
ShapeType ZoneEntityItem::getShapeType() const {
|
||||
|
@ -289,7 +314,119 @@ void ZoneEntityItem::resetRenderingPropertiesChanged() {
|
|||
withWriteLock([&] {
|
||||
_keyLightPropertiesChanged = false;
|
||||
_backgroundPropertiesChanged = false;
|
||||
_stagePropertiesChanged = false;
|
||||
_skyboxPropertiesChanged = false;
|
||||
_hazePropertiesChanged = false;
|
||||
_stagePropertiesChanged = false;
|
||||
});
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT) {
|
||||
_hazeMode = value;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ZoneEntityItem::getHazeMode() const {
|
||||
return _hazeMode;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeRange(const float hazeRange) {
|
||||
_hazeRange = hazeRange;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeRange() const {
|
||||
return _hazeRange;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeColor(const xColor hazeColor) {
|
||||
_hazeColor = hazeColor;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
xColor ZoneEntityItem::getHazeColor() const {
|
||||
return _hazeColor;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeGlareColor(const xColor hazeGlareColor) {
|
||||
_hazeGlareColor = hazeGlareColor;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
xColor ZoneEntityItem::getHazeGlareColor()const {
|
||||
return _hazeGlareColor;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeEnableGlare(const bool hazeEnableGlare) {
|
||||
_hazeEnableGlare = hazeEnableGlare;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
bool ZoneEntityItem::getHazeEnableGlare()const {
|
||||
return _hazeEnableGlare;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeGlareAngle(const float hazeGlareAngle) {
|
||||
_hazeGlareAngle = hazeGlareAngle;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeGlareAngle() const {
|
||||
return _hazeGlareAngle;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeCeiling(const float hazeCeiling) {
|
||||
_hazeCeiling = hazeCeiling;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeCeiling() const {
|
||||
return _hazeCeiling;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeBaseRef(const float hazeBaseRef) {
|
||||
_hazeBaseRef = hazeBaseRef;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeBaseRef() const {
|
||||
return _hazeBaseRef;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeBackgroundBlend(const float hazeBackgroundBlend) {
|
||||
_hazeBackgroundBlend = hazeBackgroundBlend;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeBackgroundBlend() const {
|
||||
return _hazeBackgroundBlend;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeAttenuateKeyLight(const bool hazeAttenuateKeyLight) {
|
||||
_hazeAttenuateKeyLight = hazeAttenuateKeyLight;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
bool ZoneEntityItem::getHazeAttenuateKeyLight() const {
|
||||
return _hazeAttenuateKeyLight;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeKeyLightRange(const float hazeKeyLightRange) {
|
||||
_hazeKeyLightRange = hazeKeyLightRange;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeKeyLightRange() const {
|
||||
return _hazeKeyLightRange;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeKeyLightAltitude(const float hazeKeyLightAltitude) {
|
||||
_hazeKeyLightAltitude = hazeKeyLightAltitude;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeKeyLightAltitude() const {
|
||||
return _hazeKeyLightAltitude;
|
||||
}
|
||||
|
||||
|
|