mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:37:46 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into pop_dynamicTestsMaster
This commit is contained in:
commit
cda43ec1ea
91 changed files with 1232 additions and 808 deletions
2
BUILD.md
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.
|
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
|
### OS Specific Build Guides
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
||||||
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
|
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
|
||||||
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
|
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
|
||||||
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
|
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
|
||||||
|
packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket");
|
||||||
|
|
||||||
static const int LOG_INTERVAL = MSECS_PER_SECOND / 10;
|
static const int LOG_INTERVAL = MSECS_PER_SECOND / 10;
|
||||||
auto timer = new QTimer(this);
|
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() {
|
void EntityScriptServer::run() {
|
||||||
// make sure we request our script once the agent connects to the domain
|
// make sure we request our script once the agent connects to the domain
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
|
@ -54,6 +54,9 @@ private slots:
|
||||||
|
|
||||||
void pushLogs();
|
void pushLogs();
|
||||||
|
|
||||||
|
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void negotiateAudioFormat();
|
void negotiateAudioFormat();
|
||||||
void selectAudioFormat(const QString& selectedCodecName);
|
void selectAudioFormat(const QString& selectedCodecName);
|
||||||
|
|
|
@ -210,6 +210,7 @@ endif()
|
||||||
# link required hifi libraries
|
# link required hifi libraries
|
||||||
link_hifi_libraries(
|
link_hifi_libraries(
|
||||||
shared octree ktx gpu gl gpu-gl procedural model render
|
shared octree ktx gpu gl gpu-gl procedural model render
|
||||||
|
pointers
|
||||||
recording fbx networking model-networking entities avatars trackers
|
recording fbx networking model-networking entities avatars trackers
|
||||||
audio audio-client animation script-engine physics
|
audio audio-client animation script-engine physics
|
||||||
render-utils entities-renderer avatars-renderer ui auto-updater midi
|
render-utils entities-renderer avatars-renderer ui auto-updater midi
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
import QtQuick.Controls 1.4 as Original
|
import QtQuick.Controls 1.4 as Original
|
||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
import "../styles-uit"
|
import "../styles-uit"
|
||||||
|
|
||||||
|
@ -26,6 +27,16 @@ Original.Button {
|
||||||
|
|
||||||
HifiConstants { id: hifi }
|
HifiConstants { id: hifi }
|
||||||
|
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (hovered) {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
|
}
|
||||||
|
|
||||||
style: ButtonStyle {
|
style: ButtonStyle {
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
|
|
|
@ -14,6 +14,8 @@ import QtQuick.Controls.Styles 1.4
|
||||||
|
|
||||||
import "../styles-uit"
|
import "../styles-uit"
|
||||||
|
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
Original.CheckBox {
|
Original.CheckBox {
|
||||||
id: checkBox
|
id: checkBox
|
||||||
|
|
||||||
|
@ -28,6 +30,15 @@ Original.CheckBox {
|
||||||
readonly property int checkRadius: 2
|
readonly property int checkRadius: 2
|
||||||
activeFocusOnPress: true
|
activeFocusOnPress: true
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: doesnt works for QQC1. check with QQC2
|
||||||
|
// onHovered: {
|
||||||
|
// tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
// }
|
||||||
|
|
||||||
style: CheckBoxStyle {
|
style: CheckBoxStyle {
|
||||||
indicator: Rectangle {
|
indicator: Rectangle {
|
||||||
id: box
|
id: box
|
||||||
|
|
|
@ -13,6 +13,7 @@ import QtQuick.Controls 2.2
|
||||||
|
|
||||||
import "../styles-uit"
|
import "../styles-uit"
|
||||||
import "../controls-uit" as HiFiControls
|
import "../controls-uit" as HiFiControls
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
id: checkBox
|
id: checkBox
|
||||||
|
@ -32,6 +33,17 @@ CheckBox {
|
||||||
readonly property int checkSize: Math.max(boxSize - 8, 10)
|
readonly property int checkSize: Math.max(boxSize - 8, 10)
|
||||||
readonly property int checkRadius: isRound ? checkSize / 2 : 2
|
readonly property int checkRadius: isRound ? checkSize / 2 : 2
|
||||||
focusPolicy: Qt.ClickFocus
|
focusPolicy: Qt.ClickFocus
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (hovered) {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
indicator: Rectangle {
|
indicator: Rectangle {
|
||||||
id: box
|
id: box
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
import QtQuick.Controls 1.4 as Original
|
import QtQuick.Controls 1.4 as Original
|
||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
import "../styles-uit"
|
import "../styles-uit"
|
||||||
|
|
||||||
|
@ -24,6 +25,16 @@ Original.Button {
|
||||||
width: 120
|
width: 120
|
||||||
height: 28
|
height: 28
|
||||||
|
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (hovered) {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
|
}
|
||||||
|
|
||||||
style: ButtonStyle {
|
style: ButtonStyle {
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: keyItem
|
id: keyItem
|
||||||
|
@ -32,8 +33,15 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onContainsMouseChanged: {
|
||||||
|
if (containsMouse) {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
mouse.accepted = true;
|
mouse.accepted = true;
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
|
|
||||||
webEntity.synthesizeKeyPress(glyph);
|
webEntity.synthesizeKeyPress(glyph);
|
||||||
webEntity.synthesizeKeyPress(glyph, mirrorText);
|
webEntity.synthesizeKeyPress(glyph, mirrorText);
|
||||||
|
|
|
@ -15,6 +15,8 @@ import QtQuick.Controls.Styles 1.4
|
||||||
import "../styles-uit"
|
import "../styles-uit"
|
||||||
import "../controls-uit" as HifiControls
|
import "../controls-uit" as HifiControls
|
||||||
|
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
Original.RadioButton {
|
Original.RadioButton {
|
||||||
id: radioButton
|
id: radioButton
|
||||||
HifiConstants { id: hifi }
|
HifiConstants { id: hifi }
|
||||||
|
@ -27,6 +29,15 @@ Original.RadioButton {
|
||||||
readonly property int checkSize: 10
|
readonly property int checkSize: 10
|
||||||
readonly property int checkRadius: 2
|
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 {
|
style: RadioButtonStyle {
|
||||||
indicator: Rectangle {
|
indicator: Rectangle {
|
||||||
id: box
|
id: box
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
import "../../controls-uit"
|
import "../../controls-uit"
|
||||||
|
|
||||||
|
@ -22,7 +23,16 @@ Preference {
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
id: button
|
id: button
|
||||||
onClicked: preference.trigger()
|
onHoveredChanged: {
|
||||||
|
if (hovered) {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
preference.trigger();
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
|
}
|
||||||
width: 180
|
width: 180
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
import "../../controls-uit"
|
import "../../controls-uit"
|
||||||
|
|
||||||
|
@ -38,6 +39,16 @@ Preference {
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
id: checkBox
|
id: checkBox
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (hovered) {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
|
}
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: spacer.bottom
|
top: spacer.bottom
|
||||||
left: parent.left
|
left: parent.left
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
import Hifi 1.0
|
import Hifi 1.0
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
import "toolbars"
|
import "toolbars"
|
||||||
import "../styles-uit"
|
import "../styles-uit"
|
||||||
|
|
||||||
|
@ -243,9 +245,15 @@ Item {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
acceptedButtons: Qt.LeftButton;
|
acceptedButtons: Qt.LeftButton;
|
||||||
onClicked: goFunction("hifi://" + hifiUrl);
|
onClicked: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
|
goFunction("hifi://" + hifiUrl);
|
||||||
|
}
|
||||||
hoverEnabled: true;
|
hoverEnabled: true;
|
||||||
onEntered: hoverThunk();
|
onEntered: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
hoverThunk();
|
||||||
|
}
|
||||||
onExited: unhoverThunk();
|
onExited: unhoverThunk();
|
||||||
}
|
}
|
||||||
StateImage {
|
StateImage {
|
||||||
|
@ -261,6 +269,7 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function go() {
|
function go() {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
goFunction(drillDownToPlace ? ("/places/" + placeName) : ("/user_stories/" + storyId));
|
goFunction(drillDownToPlace ? ("/places/" + placeName) : ("/user_stories/" + storyId));
|
||||||
}
|
}
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// skyboxchanger.qml
|
// SkyboxChanger.qml
|
||||||
//
|
// qml/hifi
|
||||||
//
|
//
|
||||||
// Created by Cain Kilgore on 9th August 2017
|
// Created by Cain Kilgore on 9th August 2017
|
||||||
// Copyright 2017 High Fidelity, Inc.
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
@ -9,33 +9,97 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// 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
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
id: root;
|
id: root;
|
||||||
|
HifiConstants { id: hifi; }
|
||||||
|
|
||||||
|
property var defaultThumbnails: [];
|
||||||
|
property var defaultFulls: [];
|
||||||
|
|
||||||
|
SkyboxSelectionModel {
|
||||||
|
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);
|
||||||
|
for (var i = 0; i < arr.length; i++) {
|
||||||
|
defaultThumbnails.push(arr[i].thumb);
|
||||||
|
defaultFulls.push(arr[i].full);
|
||||||
|
}
|
||||||
|
setDefaultSkyboxes();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDefaultSkyboxes() {
|
||||||
|
for (var i = 0; i < skyboxModel.count; i++) {
|
||||||
|
skyboxModel.setProperty(i, "thumbnailPath", defaultThumbnails[i]);
|
||||||
|
skyboxModel.setProperty(i, "fullSkyboxPath", defaultFulls[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function shuffle(array) {
|
||||||
|
var tmp, current, top = array.length;
|
||||||
|
if (top) {
|
||||||
|
while (--top) {
|
||||||
|
current = Math.floor(Math.random() * (top + 1));
|
||||||
|
tmp = array[current];
|
||||||
|
array[current] = array[top];
|
||||||
|
array[top] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
color: hifi.colors.baseGray;
|
function chooseRandom() {
|
||||||
|
for (var a = [], i=0; i < defaultFulls.length; ++i) {
|
||||||
|
a[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = shuffle(a);
|
||||||
|
|
||||||
|
for (var i = 0; i < skyboxModel.count; i++) {
|
||||||
|
skyboxModel.setProperty(i, "thumbnailPath", defaultThumbnails[a[i]]);
|
||||||
|
skyboxModel.setProperty(i, "fullSkyboxPath", defaultFulls[a[i]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
getSkyboxes();
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: titleBarContainer;
|
id: titleBarContainer;
|
||||||
// Size
|
|
||||||
width: parent.width;
|
width: parent.width;
|
||||||
height: 50;
|
height: childrenRect.height;
|
||||||
// Anchors
|
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
|
anchors.right: parent.right;
|
||||||
RalewaySemiBold {
|
anchors.topMargin: 20;
|
||||||
|
RalewayBold {
|
||||||
id: titleBarText;
|
id: titleBarText;
|
||||||
text: "Skybox Changer";
|
text: "Skybox Changer";
|
||||||
// Text size
|
|
||||||
size: hifi.fontSizes.overlayTitle;
|
size: hifi.fontSizes.overlayTitle;
|
||||||
// Anchors
|
anchors.top: parent.top;
|
||||||
anchors.fill: parent;
|
anchors.left: parent.left;
|
||||||
anchors.leftMargin: 16;
|
anchors.leftMargin: 40
|
||||||
// Style
|
height: paintedHeight;
|
||||||
color: hifi.colors.lightGrayText;
|
color: hifi.colors.lightGrayText;
|
||||||
// Alignment
|
|
||||||
horizontalAlignment: Text.AlignHCenter;
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
verticalAlignment: Text.AlignVCenter;
|
verticalAlignment: Text.AlignVCenter;
|
||||||
}
|
}
|
||||||
|
@ -43,131 +107,68 @@ Rectangle {
|
||||||
id: titleBarDesc;
|
id: titleBarDesc;
|
||||||
text: "Click an image to choose a new Skybox.";
|
text: "Click an image to choose a new Skybox.";
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
// Text size
|
|
||||||
size: 14;
|
size: 14;
|
||||||
// Anchors
|
anchors.top: titleBarText.bottom;
|
||||||
anchors.fill: parent;
|
anchors.left: parent.left;
|
||||||
anchors.top: titleBarText.bottom
|
anchors.leftMargin: 40
|
||||||
anchors.leftMargin: 16;
|
height: paintedHeight;
|
||||||
anchors.rightMargin: 16;
|
|
||||||
// Style
|
|
||||||
color: hifi.colors.lightGrayText;
|
color: hifi.colors.lightGrayText;
|
||||||
// Alignment
|
|
||||||
horizontalAlignment: Text.AlignHCenter;
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
verticalAlignment: Text.AlignVCenter;
|
verticalAlignment: Text.AlignVCenter;
|
||||||
}
|
}
|
||||||
|
HifiControls.Button {
|
||||||
|
id: randomButton
|
||||||
|
text: "Randomize"
|
||||||
|
color: hifi.buttons.blue
|
||||||
|
colorScheme: root.colorScheme
|
||||||
|
width: 100
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 5
|
||||||
|
anchors.rightMargin: 40
|
||||||
|
onClicked: {
|
||||||
|
chooseRandom()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This RowLayout could be a GridLayout instead for further expandability.
|
GridView {
|
||||||
// As this SkyboxChanger task only required 6 images, implementing GridLayout wasn't necessary.
|
id: gridView
|
||||||
// In the future if this is to be expanded to add more Skyboxes, it might be worth changing this.
|
interactive: false
|
||||||
RowLayout {
|
clip: true
|
||||||
id: row1
|
|
||||||
anchors.top: titleBarContainer.bottom
|
anchors.top: titleBarContainer.bottom
|
||||||
anchors.left: parent.left
|
anchors.topMargin: 20
|
||||||
anchors.leftMargin: 30
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
Layout.fillWidth: true
|
width: 400
|
||||||
anchors.topMargin: 30
|
height: parent.height
|
||||||
spacing: 10
|
currentIndex: -1
|
||||||
Image {
|
|
||||||
width: 200; height: 200
|
cellWidth: 200
|
||||||
fillMode: Image.Stretch
|
cellHeight: 200
|
||||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_1.jpg"
|
model: skyboxModel
|
||||||
clip: true
|
delegate: Item {
|
||||||
id: preview1
|
width: gridView.cellWidth
|
||||||
MouseArea {
|
height: gridView.cellHeight
|
||||||
|
Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
Image {
|
||||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/1.jpg'});
|
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 {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
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'});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signal sendToScript(var message);
|
signal sendToScript(var message);
|
||||||
|
}
|
||||||
}
|
|
40
interface/resources/qml/hifi/SkyboxSelectionModel.qml
Normal file
40
interface/resources/qml/hifi/SkyboxSelectionModel.qml
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// SkyboxSelectionModel.qml
|
||||||
|
// qml/hifi
|
||||||
|
//
|
||||||
|
// Created by Cain Kilgore on 21st October 2017
|
||||||
|
// Copyright 2017 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
|
||||||
|
//
|
||||||
|
|
||||||
|
import QtQuick 2.5
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: root;
|
||||||
|
ListElement{
|
||||||
|
thumbnailPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_1.jpg"
|
||||||
|
fullSkyboxPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/1.jpg"
|
||||||
|
}
|
||||||
|
ListElement{
|
||||||
|
thumbnailPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_1.jpg"
|
||||||
|
fullSkyboxPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/1.jpg"
|
||||||
|
}
|
||||||
|
ListElement{
|
||||||
|
thumbnailPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_1.jpg"
|
||||||
|
fullSkyboxPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/1.jpg"
|
||||||
|
}
|
||||||
|
ListElement{
|
||||||
|
thumbnailPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_1.jpg"
|
||||||
|
fullSkyboxPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/1.jpg"
|
||||||
|
}
|
||||||
|
ListElement{
|
||||||
|
thumbnailPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_1.jpg"
|
||||||
|
fullSkyboxPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/1.jpg"
|
||||||
|
}
|
||||||
|
ListElement{
|
||||||
|
thumbnailPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_1.jpg"
|
||||||
|
fullSkyboxPath: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/1.jpg"
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,8 @@ import QtQuick.Controls 1.4
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
readonly property var level: Audio.inputLevel;
|
readonly property var level: Audio.inputLevel;
|
||||||
|
|
||||||
|
@ -57,8 +59,16 @@ Rectangle {
|
||||||
|
|
||||||
hoverEnabled: true;
|
hoverEnabled: true;
|
||||||
scrollGestureEnabled: false;
|
scrollGestureEnabled: false;
|
||||||
onClicked: { Audio.muted = !Audio.muted; }
|
onClicked: {
|
||||||
|
Audio.muted = !Audio.muted;
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
|
}
|
||||||
drag.target: dragTarget;
|
drag.target: dragTarget;
|
||||||
|
onContainsMouseChanged: {
|
||||||
|
if (containsMouse) {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: newEntityButton
|
id: newEntityButton
|
||||||
|
@ -122,9 +123,11 @@ Item {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
enabled: true
|
enabled: true
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
newEntityButton.clicked();
|
newEntityButton.clicked();
|
||||||
}
|
}
|
||||||
onEntered: {
|
onEntered: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
newEntityButton.state = "hover state";
|
newEntityButton.state = "hover state";
|
||||||
}
|
}
|
||||||
onExited: {
|
onExited: {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: tabletButton
|
id: tabletButton
|
||||||
|
@ -130,11 +131,13 @@ Item {
|
||||||
}
|
}
|
||||||
tabletButton.clicked();
|
tabletButton.clicked();
|
||||||
if (tabletRoot) {
|
if (tabletRoot) {
|
||||||
tabletRoot.playButtonClickSound();
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onEntered: {
|
onEntered: {
|
||||||
tabletButton.isEntered = true;
|
tabletButton.isEntered = true;
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
|
||||||
if (tabletButton.isActive) {
|
if (tabletButton.isActive) {
|
||||||
tabletButton.state = "hover active state";
|
tabletButton.state = "hover active state";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,9 +9,13 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import QtQuick.Controls.Styles 1.4
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
import "../../styles-uit"
|
import "../../styles-uit"
|
||||||
import "."
|
import "."
|
||||||
|
|
||||||
FocusScope {
|
FocusScope {
|
||||||
id: root
|
id: root
|
||||||
implicitHeight: background.height
|
implicitHeight: background.height
|
||||||
|
@ -69,12 +73,17 @@ FocusScope {
|
||||||
onImplicitWidthChanged: listView !== null ? listView.recalcSize() : 0
|
onImplicitWidthChanged: listView !== null ? listView.recalcSize() : 0
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
enabled: name !== "" && item.enabled
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onEntered: listView.currentIndex = index
|
onEntered: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
listView.currentIndex = index
|
||||||
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.selected(item)
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
tabletRoot.playButtonClickSound();
|
root.selected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import Hifi 1.0
|
import Hifi 1.0
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
import "../../dialogs"
|
import "../../dialogs"
|
||||||
import "../../controls"
|
import "../../controls"
|
||||||
|
|
||||||
|
|
BIN
interface/resources/sounds/Button01.wav
Normal file
BIN
interface/resources/sounds/Button01.wav
Normal file
Binary file not shown.
BIN
interface/resources/sounds/Button02.wav
Normal file
BIN
interface/resources/sounds/Button02.wav
Normal file
Binary file not shown.
BIN
interface/resources/sounds/Button03.wav
Normal file
BIN
interface/resources/sounds/Button03.wav
Normal file
Binary file not shown.
BIN
interface/resources/sounds/Button04.wav
Normal file
BIN
interface/resources/sounds/Button04.wav
Normal file
Binary file not shown.
BIN
interface/resources/sounds/Button05.wav
Normal file
BIN
interface/resources/sounds/Button05.wav
Normal file
Binary file not shown.
BIN
interface/resources/sounds/Button06.wav
Normal file
BIN
interface/resources/sounds/Button06.wav
Normal file
Binary file not shown.
BIN
interface/resources/sounds/Button07.wav
Normal file
BIN
interface/resources/sounds/Button07.wav
Normal file
Binary file not shown.
BIN
interface/resources/sounds/Collapse.wav
Normal file
BIN
interface/resources/sounds/Collapse.wav
Normal file
Binary file not shown.
BIN
interface/resources/sounds/Expand.wav
Normal file
BIN
interface/resources/sounds/Expand.wav
Normal file
Binary file not shown.
BIN
interface/resources/sounds/Tab01.wav
Normal file
BIN
interface/resources/sounds/Tab01.wav
Normal file
Binary file not shown.
BIN
interface/resources/sounds/Tab02.wav
Normal file
BIN
interface/resources/sounds/Tab02.wav
Normal file
Binary file not shown.
BIN
interface/resources/sounds/Tab03.wav
Normal file
BIN
interface/resources/sounds/Tab03.wav
Normal file
Binary file not shown.
|
@ -1848,6 +1848,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
_rayPickManager.setPrecisionPicking(rayPickID, value);
|
_rayPickManager.setPrecisionPicking(rayPickID, value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Preload Tablet sounds
|
||||||
|
DependencyManager::get<TabletScriptingInterface>()->preloadSounds();
|
||||||
|
|
||||||
qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID());
|
qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2325,6 +2328,8 @@ void Application::initializeUi() {
|
||||||
|
|
||||||
surfaceContext->setContextProperty("Account", AccountScriptingInterface::getInstance());
|
surfaceContext->setContextProperty("Account", AccountScriptingInterface::getInstance());
|
||||||
surfaceContext->setContextProperty("Tablet", DependencyManager::get<TabletScriptingInterface>().data());
|
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("DialogsManager", _dialogsManagerScriptingInterface);
|
||||||
surfaceContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance());
|
surfaceContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance());
|
||||||
surfaceContext->setContextProperty("FaceTracker", DependencyManager::get<DdeFaceTracker>().data());
|
surfaceContext->setContextProperty("FaceTracker", DependencyManager::get<DdeFaceTracker>().data());
|
||||||
|
@ -2393,8 +2398,8 @@ void Application::initializeUi() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updateCamera(RenderArgs& renderArgs) {
|
void Application::updateCamera(RenderArgs& renderArgs) {
|
||||||
PROFILE_RANGE(render, "/updateCamera");
|
PROFILE_RANGE(render, __FUNCTION__);
|
||||||
PerformanceTimer perfTimer("CameraUpdates");
|
PerformanceTimer perfTimer("updateCamera");
|
||||||
|
|
||||||
glm::vec3 boomOffset;
|
glm::vec3 boomOffset;
|
||||||
auto myAvatar = getMyAvatar();
|
auto myAvatar = getMyAvatar();
|
||||||
|
@ -2610,7 +2615,7 @@ void Application::resizeGL() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::handleSandboxStatus(QNetworkReply* reply) {
|
void Application::handleSandboxStatus(QNetworkReply* reply) {
|
||||||
PROFILE_RANGE(render, "HandleSandboxStatus");
|
PROFILE_RANGE(render, __FUNCTION__);
|
||||||
|
|
||||||
bool sandboxIsRunning = SandboxUtils::readStatus(reply->readAll());
|
bool sandboxIsRunning = SandboxUtils::readStatus(reply->readAll());
|
||||||
qDebug() << "HandleSandboxStatus" << sandboxIsRunning;
|
qDebug() << "HandleSandboxStatus" << sandboxIsRunning;
|
||||||
|
@ -4639,7 +4644,6 @@ void Application::updateDialogs(float deltaTime) const {
|
||||||
static bool domainLoadingInProgress = false;
|
static bool domainLoadingInProgress = false;
|
||||||
|
|
||||||
void Application::update(float deltaTime) {
|
void Application::update(float deltaTime) {
|
||||||
|
|
||||||
PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_renderFrameCount + 1);
|
PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_renderFrameCount + 1);
|
||||||
|
|
||||||
if (!_physicsEnabled) {
|
if (!_physicsEnabled) {
|
||||||
|
@ -4834,11 +4838,11 @@ void Application::update(float deltaTime) {
|
||||||
QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>();
|
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");
|
PerformanceTimer perfTimer("physics");
|
||||||
if (_physicsEnabled) {
|
if (_physicsEnabled) {
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX(simulation_physics, "UpdateStates", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE(simulation_physics, "PreStep");
|
||||||
|
|
||||||
PerformanceTimer perfTimer("updateStates)");
|
PerformanceTimer perfTimer("updateStates)");
|
||||||
static VectorOfMotionStates motionStates;
|
static VectorOfMotionStates motionStates;
|
||||||
|
@ -4872,14 +4876,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");
|
PerformanceTimer perfTimer("stepSimulation");
|
||||||
getEntities()->getTree()->withWriteLock([&] {
|
getEntities()->getTree()->withWriteLock([&] {
|
||||||
_physicsEngine->stepSimulation();
|
_physicsEngine->stepSimulation();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX(simulation_physics, "HarvestChanges", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE(simulation_physics, "PostStep");
|
||||||
PerformanceTimer perfTimer("harvestChanges");
|
PerformanceTimer perfTimer("harvestChanges");
|
||||||
if (_physicsEngine->hasOutgoingChanges()) {
|
if (_physicsEngine->hasOutgoingChanges()) {
|
||||||
// grab the collision events BEFORE handleOutgoingChanges() because at this point
|
// grab the collision events BEFORE handleOutgoingChanges() because at this point
|
||||||
|
@ -4887,6 +4891,7 @@ void Application::update(float deltaTime) {
|
||||||
auto& collisionEvents = _physicsEngine->getCollisionEvents();
|
auto& collisionEvents = _physicsEngine->getCollisionEvents();
|
||||||
|
|
||||||
getEntities()->getTree()->withWriteLock([&] {
|
getEntities()->getTree()->withWriteLock([&] {
|
||||||
|
PROFILE_RANGE(simulation_physics, "Harvest");
|
||||||
PerformanceTimer perfTimer("handleOutgoingChanges");
|
PerformanceTimer perfTimer("handleOutgoingChanges");
|
||||||
|
|
||||||
const VectorOfMotionStates& outgoingChanges = _physicsEngine->getChangedMotionStates();
|
const VectorOfMotionStates& outgoingChanges = _physicsEngine->getChangedMotionStates();
|
||||||
|
@ -4899,18 +4904,25 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
if (!_aboutToQuit) {
|
if (!_aboutToQuit) {
|
||||||
// handleCollisionEvents() AFTER handleOutgoinChanges()
|
// handleCollisionEvents() AFTER handleOutgoinChanges()
|
||||||
PerformanceTimer perfTimer("entities");
|
{
|
||||||
avatarManager->handleCollisionEvents(collisionEvents);
|
PROFILE_RANGE(simulation_physics, "CollisionEvents");
|
||||||
// Collision events (and their scripts) must not be handled when we're locked, above. (That would risk
|
PerformanceTimer perfTimer("entities");
|
||||||
// deadlock.)
|
avatarManager->handleCollisionEvents(collisionEvents);
|
||||||
_entitySimulation->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
|
// NOTE: the getEntities()->update() call below will wait for lock
|
||||||
// and will simulate entity motion (the EntityTree has been given an EntitySimulation).
|
// and will simulate entity motion (the EntityTree has been given an EntitySimulation).
|
||||||
getEntities()->update(true); // update the models...
|
getEntities()->update(true); // update the models...
|
||||||
}
|
}
|
||||||
|
|
||||||
myAvatar->harvestResultsFromPhysicsSimulation(deltaTime);
|
{
|
||||||
|
PROFILE_RANGE(simulation_physics, "MyAvatar");
|
||||||
|
myAvatar->harvestResultsFromPhysicsSimulation(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails) &&
|
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails) &&
|
||||||
Menu::getInstance()->isOptionChecked(MenuOption::ExpandPhysicsSimulationTiming)) {
|
Menu::getInstance()->isOptionChecked(MenuOption::ExpandPhysicsSimulationTiming)) {
|
||||||
|
@ -4929,13 +4941,13 @@ void Application::update(float deltaTime) {
|
||||||
// AvatarManager update
|
// AvatarManager update
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
PROFILE_RANGE(simulation, "OtherAvatars");
|
||||||
PerformanceTimer perfTimer("otherAvatars");
|
PerformanceTimer perfTimer("otherAvatars");
|
||||||
PROFILE_RANGE_EX(simulation, "OtherAvatars", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
|
||||||
avatarManager->updateOtherAvatars(deltaTime);
|
avatarManager->updateOtherAvatars(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX(simulation, "MyAvatar", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE(simulation, "MyAvatar");
|
||||||
PerformanceTimer perfTimer("MyAvatar");
|
PerformanceTimer perfTimer("MyAvatar");
|
||||||
qApp->updateMyAvatarLookAtPosition();
|
qApp->updateMyAvatarLookAtPosition();
|
||||||
avatarManager->updateMyAvatar(deltaTime);
|
avatarManager->updateMyAvatar(deltaTime);
|
||||||
|
@ -5811,6 +5823,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
||||||
qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue<TabletProxy>, wrapperFromScriptValue<TabletProxy>);
|
qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue<TabletProxy>, wrapperFromScriptValue<TabletProxy>);
|
||||||
qScriptRegisterMetaType(scriptEngine.data(),
|
qScriptRegisterMetaType(scriptEngine.data(),
|
||||||
wrapperToScriptValue<TabletButtonProxy>, wrapperFromScriptValue<TabletButtonProxy>);
|
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());
|
scriptEngine->registerGlobalObject("Tablet", DependencyManager::get<TabletScriptingInterface>().data());
|
||||||
|
|
||||||
auto toolbarScriptingInterface = DependencyManager::get<ToolbarScriptingInterface>().data();
|
auto toolbarScriptingInterface = DependencyManager::get<ToolbarScriptingInterface>().data();
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
//
|
//
|
||||||
#include "JointRayPick.h"
|
#include "JointRayPick.h"
|
||||||
|
|
||||||
#include "DependencyManager.h"
|
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
|
|
||||||
JointRayPick::JointRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled) :
|
JointRayPick::JointRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled) :
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#ifndef hifi_JointRayPick_h
|
#ifndef hifi_JointRayPick_h
|
||||||
#define hifi_JointRayPick_h
|
#define hifi_JointRayPick_h
|
||||||
|
|
||||||
#include "RayPick.h"
|
#include <pointers/rays/RayPick.h>
|
||||||
|
|
||||||
class JointRayPick : public RayPick {
|
class JointRayPick : public RayPick {
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
#include "LaserPointer.h"
|
#include "LaserPointer.h"
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "ui/overlays/Overlay.h"
|
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
|
#include "RayPickScriptingInterface.h"
|
||||||
|
|
||||||
LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates,
|
LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates,
|
||||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled) :
|
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled) :
|
||||||
|
@ -22,9 +22,10 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende
|
||||||
_faceAvatar(faceAvatar),
|
_faceAvatar(faceAvatar),
|
||||||
_centerEndY(centerEndY),
|
_centerEndY(centerEndY),
|
||||||
_lockEnd(lockEnd),
|
_lockEnd(lockEnd),
|
||||||
_distanceScaleEnd(distanceScaleEnd)
|
_distanceScaleEnd(distanceScaleEnd),
|
||||||
|
_rayPickUID(DependencyManager::get<RayPickScriptingInterface>()->createRayPick(rayProps))
|
||||||
{
|
{
|
||||||
_rayPickUID = DependencyManager::get<RayPickScriptingInterface>()->createRayPick(rayProps);
|
|
||||||
|
|
||||||
for (auto& state : _renderStates) {
|
for (auto& state : _renderStates) {
|
||||||
if (!enabled || state.first != _currentRenderState) {
|
if (!enabled || state.first != _currentRenderState) {
|
||||||
|
@ -39,7 +40,7 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende
|
||||||
}
|
}
|
||||||
|
|
||||||
LaserPointer::~LaserPointer() {
|
LaserPointer::~LaserPointer() {
|
||||||
DependencyManager::get<RayPickScriptingInterface>()->removeRayPick(_rayPickUID);
|
qApp->getRayPickManager().removeRayPick(_rayPickUID);
|
||||||
|
|
||||||
for (auto& renderState : _renderStates) {
|
for (auto& renderState : _renderStates) {
|
||||||
renderState.second.deleteOverlays();
|
renderState.second.deleteOverlays();
|
||||||
|
@ -50,47 +51,51 @@ LaserPointer::~LaserPointer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::enable() {
|
void LaserPointer::enable() {
|
||||||
QWriteLocker lock(getLock());
|
qApp->getRayPickManager().enableRayPick(_rayPickUID);
|
||||||
DependencyManager::get<RayPickScriptingInterface>()->enableRayPick(_rayPickUID);
|
withWriteLock([&] {
|
||||||
_renderingEnabled = true;
|
_renderingEnabled = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::disable() {
|
void LaserPointer::disable() {
|
||||||
QWriteLocker lock(getLock());
|
qApp->getRayPickManager().disableRayPick(_rayPickUID);
|
||||||
DependencyManager::get<RayPickScriptingInterface>()->disableRayPick(_rayPickUID);
|
withWriteLock([&] {
|
||||||
_renderingEnabled = false;
|
_renderingEnabled = false;
|
||||||
if (!_currentRenderState.empty()) {
|
if (!_currentRenderState.empty()) {
|
||||||
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
|
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
|
||||||
disableRenderState(_renderStates[_currentRenderState]);
|
disableRenderState(_renderStates[_currentRenderState]);
|
||||||
|
}
|
||||||
|
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
|
||||||
|
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
|
});
|
||||||
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::setRenderState(const std::string& state) {
|
void LaserPointer::setRenderState(const std::string& state) {
|
||||||
QWriteLocker lock(getLock());
|
withWriteLock([&] {
|
||||||
if (!_currentRenderState.empty() && state != _currentRenderState) {
|
if (!_currentRenderState.empty() && state != _currentRenderState) {
|
||||||
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
|
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
|
||||||
disableRenderState(_renderStates[_currentRenderState]);
|
disableRenderState(_renderStates[_currentRenderState]);
|
||||||
|
}
|
||||||
|
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
|
||||||
|
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
|
_currentRenderState = state;
|
||||||
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
_currentRenderState = state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
|
void LaserPointer::editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
|
||||||
QWriteLocker lock(getLock());
|
withWriteLock([&] {
|
||||||
updateRenderStateOverlay(_renderStates[state].getStartID(), startProps);
|
updateRenderStateOverlay(_renderStates[state].getStartID(), startProps);
|
||||||
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
|
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
|
||||||
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
|
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
|
||||||
QVariant endDim = endProps.toMap()["dimensions"];
|
QVariant endDim = endProps.toMap()["dimensions"];
|
||||||
if (endDim.isValid()) {
|
if (endDim.isValid()) {
|
||||||
_renderStates[state].setEndDim(vec3FromVariant(endDim));
|
_renderStates[state].setEndDim(vec3FromVariant(endDim));
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& props) {
|
void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& props) {
|
||||||
|
@ -102,8 +107,7 @@ void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant&
|
||||||
}
|
}
|
||||||
|
|
||||||
const RayPickResult LaserPointer::getPrevRayPickResult() {
|
const RayPickResult LaserPointer::getPrevRayPickResult() {
|
||||||
QReadLocker lock(getLock());
|
return qApp->getRayPickManager().getPrevRayPickResult(_rayPickUID);
|
||||||
return DependencyManager::get<RayPickScriptingInterface>()->getPrevRayPickResult(_rayPickUID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState) {
|
void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState) {
|
||||||
|
@ -202,65 +206,45 @@ void LaserPointer::disableRenderState(const RenderState& renderState) {
|
||||||
|
|
||||||
void LaserPointer::update() {
|
void LaserPointer::update() {
|
||||||
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
|
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
|
||||||
QReadLocker lock(getLock());
|
withReadLock([&] {
|
||||||
RayPickResult prevRayPickResult = DependencyManager::get<RayPickScriptingInterface>()->getPrevRayPickResult(_rayPickUID);
|
RayPickResult prevRayPickResult = qApp->getRayPickManager().getPrevRayPickResult(_rayPickUID);
|
||||||
if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() &&
|
if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() &&
|
||||||
(prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) {
|
(prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) {
|
||||||
float distance = _laserLength > 0.0f ? _laserLength : prevRayPickResult.distance;
|
float distance = _laserLength > 0.0f ? _laserLength : prevRayPickResult.distance;
|
||||||
updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, distance, prevRayPickResult.objectID, prevRayPickResult.searchRay, false);
|
updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, distance, prevRayPickResult.objectID, prevRayPickResult.searchRay, false);
|
||||||
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
||||||
} else if (_renderingEnabled && !_currentRenderState.empty() && _defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
|
} else if (_renderingEnabled && !_currentRenderState.empty() && _defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
|
||||||
disableRenderState(_renderStates[_currentRenderState]);
|
disableRenderState(_renderStates[_currentRenderState]);
|
||||||
updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), prevRayPickResult.searchRay, true);
|
updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), prevRayPickResult.searchRay, true);
|
||||||
} else if (!_currentRenderState.empty()) {
|
} else if (!_currentRenderState.empty()) {
|
||||||
disableRenderState(_renderStates[_currentRenderState]);
|
disableRenderState(_renderStates[_currentRenderState]);
|
||||||
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
disableRenderState(_defaultRenderStates[_currentRenderState].second);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::setPrecisionPicking(const bool precisionPicking) {
|
void LaserPointer::setPrecisionPicking(const bool precisionPicking) {
|
||||||
QWriteLocker lock(getLock());
|
qApp->getRayPickManager().setPrecisionPicking(_rayPickUID, precisionPicking);
|
||||||
DependencyManager::get<RayPickScriptingInterface>()->setPrecisionPicking(_rayPickUID, precisionPicking);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::setLaserLength(const float laserLength) {
|
void LaserPointer::setLaserLength(const float laserLength) {
|
||||||
QWriteLocker lock(getLock());
|
withWriteLock([&] {
|
||||||
_laserLength = laserLength;
|
_laserLength = laserLength;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay) {
|
void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay) {
|
||||||
QWriteLocker lock(getLock());
|
withWriteLock([&] {
|
||||||
_objectLockEnd = std::pair<QUuid, bool>(objectID, isOverlay);
|
_objectLockEnd = std::pair<QUuid, bool>(objectID, isOverlay);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::setIgnoreEntities(const QScriptValue& ignoreEntities) {
|
void LaserPointer::setIgnoreItems(const QVector<QUuid>& ignoreItems) const {
|
||||||
QWriteLocker lock(getLock());
|
qApp->getRayPickManager().setIgnoreItems(_rayPickUID, ignoreItems);
|
||||||
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreEntities(_rayPickUID, ignoreEntities);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::setIncludeEntities(const QScriptValue& includeEntities) {
|
void LaserPointer::setIncludeItems(const QVector<QUuid>& includeItems) const {
|
||||||
QWriteLocker lock(getLock());
|
qApp->getRayPickManager().setIncludeItems(_rayPickUID, includeItems);
|
||||||
DependencyManager::get<RayPickScriptingInterface>()->setIncludeEntities(_rayPickUID, includeEntities);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LaserPointer::setIgnoreOverlays(const QScriptValue& ignoreOverlays) {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreOverlays(_rayPickUID, ignoreOverlays);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LaserPointer::setIncludeOverlays(const QScriptValue& includeOverlays) {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
DependencyManager::get<RayPickScriptingInterface>()->setIncludeOverlays(_rayPickUID, includeOverlays);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LaserPointer::setIgnoreAvatars(const QScriptValue& ignoreAvatars) {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreAvatars(_rayPickUID, ignoreAvatars);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LaserPointer::setIncludeAvatars(const QScriptValue& includeAvatars) {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
DependencyManager::get<RayPickScriptingInterface>()->setIncludeAvatars(_rayPickUID, includeAvatars);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) :
|
RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) :
|
||||||
|
@ -288,4 +272,4 @@ void RenderState::deleteOverlays() {
|
||||||
if (!_endID.isNull()) {
|
if (!_endID.isNull()) {
|
||||||
qApp->getOverlays().deleteOverlay(_endID);
|
qApp->getOverlays().deleteOverlay(_endID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,12 @@
|
||||||
#define hifi_LaserPointer_h
|
#define hifi_LaserPointer_h
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include "glm/glm.hpp"
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include "raypick/RayPickScriptingInterface.h"
|
#include <shared/ReadWriteLockable.h>
|
||||||
|
|
||||||
|
#include "ui/overlays/Overlay.h"
|
||||||
|
|
||||||
class RayPickResult;
|
class RayPickResult;
|
||||||
|
|
||||||
|
@ -49,9 +51,10 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class LaserPointer {
|
class LaserPointer : public ReadWriteLockable {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using Pointer = std::shared_ptr<LaserPointer>;
|
||||||
|
|
||||||
typedef std::unordered_map<std::string, RenderState> RenderStateMap;
|
typedef std::unordered_map<std::string, RenderState> RenderStateMap;
|
||||||
typedef std::unordered_map<std::string, std::pair<float, RenderState>> DefaultRenderStateMap;
|
typedef std::unordered_map<std::string, std::pair<float, RenderState>> DefaultRenderStateMap;
|
||||||
|
@ -73,14 +76,8 @@ public:
|
||||||
void setLaserLength(const float laserLength);
|
void setLaserLength(const float laserLength);
|
||||||
void setLockEndUUID(QUuid objectID, const bool isOverlay);
|
void setLockEndUUID(QUuid objectID, const bool isOverlay);
|
||||||
|
|
||||||
void setIgnoreEntities(const QScriptValue& ignoreEntities);
|
void setIgnoreItems(const QVector<QUuid>& ignoreItems) const;
|
||||||
void setIncludeEntities(const QScriptValue& includeEntities);
|
void setIncludeItems(const QVector<QUuid>& includeItems) const;
|
||||||
void setIgnoreOverlays(const QScriptValue& ignoreOverlays);
|
|
||||||
void setIncludeOverlays(const QScriptValue& includeOverlays);
|
|
||||||
void setIgnoreAvatars(const QScriptValue& ignoreAvatars);
|
|
||||||
void setIncludeAvatars(const QScriptValue& includeAvatars);
|
|
||||||
|
|
||||||
QReadWriteLock* getLock() { return &_lock; }
|
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
@ -96,8 +93,7 @@ private:
|
||||||
bool _distanceScaleEnd;
|
bool _distanceScaleEnd;
|
||||||
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
|
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
|
||||||
|
|
||||||
QUuid _rayPickUID;
|
const QUuid _rayPickUID;
|
||||||
QReadWriteLock _lock;
|
|
||||||
|
|
||||||
void updateRenderStateOverlay(const OverlayID& id, const QVariant& props);
|
void updateRenderStateOverlay(const OverlayID& id, const QVariant& props);
|
||||||
void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState);
|
void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState);
|
||||||
|
|
|
@ -12,138 +12,110 @@
|
||||||
|
|
||||||
QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
|
QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
|
||||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled) {
|
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled) {
|
||||||
|
QUuid result;
|
||||||
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled);
|
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled);
|
||||||
if (!laserPointer->getRayUID().isNull()) {
|
if (!laserPointer->getRayUID().isNull()) {
|
||||||
QWriteLocker containsLock(&_containsLock);
|
result = QUuid::createUuid();
|
||||||
QUuid id = QUuid::createUuid();
|
withWriteLock([&] { _laserPointers[result] = laserPointer; });
|
||||||
_laserPointers[id] = laserPointer;
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
return QUuid();
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::removeLaserPointer(const QUuid uid) {
|
|
||||||
QWriteLocker lock(&_containsLock);
|
LaserPointer::Pointer LaserPointerManager::find(const QUuid& uid) const {
|
||||||
_laserPointers.remove(uid);
|
return resultWithReadLock<LaserPointer::Pointer>([&] {
|
||||||
|
auto itr = _laserPointers.find(uid);
|
||||||
|
if (itr != _laserPointers.end()) {
|
||||||
|
return *itr;
|
||||||
|
}
|
||||||
|
return LaserPointer::Pointer();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::enableLaserPointer(const QUuid uid) {
|
|
||||||
QReadLocker lock(&_containsLock);
|
void LaserPointerManager::removeLaserPointer(const QUuid& uid) {
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
withWriteLock([&] {
|
||||||
if (laserPointer != _laserPointers.end()) {
|
_laserPointers.remove(uid);
|
||||||
laserPointer.value()->enable();
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void LaserPointerManager::enableLaserPointer(const QUuid& uid) const {
|
||||||
|
auto laserPointer = find(uid);
|
||||||
|
if (laserPointer) {
|
||||||
|
laserPointer->enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::disableLaserPointer(const QUuid uid) {
|
void LaserPointerManager::disableLaserPointer(const QUuid& uid) const {
|
||||||
QReadLocker lock(&_containsLock);
|
auto laserPointer = find(uid);
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
if (laserPointer) {
|
||||||
if (laserPointer != _laserPointers.end()) {
|
laserPointer->disable();
|
||||||
laserPointer.value()->disable();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderState) {
|
void LaserPointerManager::setRenderState(const QUuid& uid, const std::string& renderState) const {
|
||||||
QReadLocker lock(&_containsLock);
|
auto laserPointer = find(uid);
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
if (laserPointer) {
|
||||||
if (laserPointer != _laserPointers.end()) {
|
laserPointer->setRenderState(renderState);
|
||||||
laserPointer.value()->setRenderState(renderState);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
|
void LaserPointerManager::editRenderState(const QUuid& uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) const {
|
||||||
QReadLocker lock(&_containsLock);
|
auto laserPointer = find(uid);
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
if (laserPointer) {
|
||||||
if (laserPointer != _laserPointers.end()) {
|
laserPointer->editRenderState(state, startProps, pathProps, endProps);
|
||||||
laserPointer.value()->editRenderState(state, startProps, pathProps, endProps);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) {
|
const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid& uid) const {
|
||||||
QReadLocker lock(&_containsLock);
|
auto laserPointer = find(uid);
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
if (laserPointer) {
|
||||||
if (laserPointer != _laserPointers.end()) {
|
return laserPointer->getPrevRayPickResult();
|
||||||
return laserPointer.value()->getPrevRayPickResult();
|
|
||||||
}
|
}
|
||||||
return RayPickResult();
|
return RayPickResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::update() {
|
void LaserPointerManager::update() {
|
||||||
QReadLocker lock(&_containsLock);
|
auto cachedLaserPointers = resultWithReadLock<QList<std::shared_ptr<LaserPointer>>>([&] {
|
||||||
for (QUuid& uid : _laserPointers.keys()) {
|
return _laserPointers.values();
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
});
|
||||||
laserPointer.value()->update();
|
|
||||||
|
for (const auto& laserPointer : cachedLaserPointers) {
|
||||||
|
laserPointer->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) {
|
void LaserPointerManager::setPrecisionPicking(const QUuid& uid, const bool precisionPicking) const {
|
||||||
QReadLocker lock(&_containsLock);
|
auto laserPointer = find(uid);
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
if (laserPointer) {
|
||||||
if (laserPointer != _laserPointers.end()) {
|
laserPointer->setPrecisionPicking(precisionPicking);
|
||||||
laserPointer.value()->setPrecisionPicking(precisionPicking);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setLaserLength(QUuid uid, const float laserLength) {
|
void LaserPointerManager::setLaserLength(const QUuid& uid, const float laserLength) const {
|
||||||
QReadLocker lock(&_containsLock);
|
auto laserPointer = find(uid);
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
if (laserPointer) {
|
||||||
if (laserPointer != _laserPointers.end()) {
|
laserPointer->setLaserLength(laserLength);
|
||||||
laserPointer.value()->setLaserLength(laserLength);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
|
void LaserPointerManager::setIgnoreItems(const QUuid& uid, const QVector<QUuid>& ignoreEntities) const {
|
||||||
QReadLocker lock(&_containsLock);
|
auto laserPointer = find(uid);
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
if (laserPointer) {
|
||||||
if (laserPointer != _laserPointers.end()) {
|
laserPointer->setIgnoreItems(ignoreEntities);
|
||||||
laserPointer.value()->setIgnoreEntities(ignoreEntities);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
|
void LaserPointerManager::setIncludeItems(const QUuid& uid, const QVector<QUuid>& includeEntities) const {
|
||||||
QReadLocker lock(&_containsLock);
|
auto laserPointer = find(uid);
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
if (laserPointer) {
|
||||||
if (laserPointer != _laserPointers.end()) {
|
laserPointer->setIncludeItems(includeEntities);
|
||||||
laserPointer.value()->setIncludeEntities(includeEntities);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
|
void LaserPointerManager::setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const {
|
||||||
QReadLocker lock(&_containsLock);
|
auto laserPointer = find(uid);
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
if (laserPointer) {
|
||||||
if (laserPointer != _laserPointers.end()) {
|
laserPointer->setLockEndUUID(objectID, isOverlay);
|
||||||
laserPointer.value()->setIgnoreOverlays(ignoreOverlays);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
|
|
||||||
QReadLocker lock(&_containsLock);
|
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
|
||||||
if (laserPointer != _laserPointers.end()) {
|
|
||||||
laserPointer.value()->setIncludeOverlays(includeOverlays);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
|
|
||||||
QReadLocker lock(&_containsLock);
|
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
|
||||||
if (laserPointer != _laserPointers.end()) {
|
|
||||||
laserPointer.value()->setIgnoreAvatars(ignoreAvatars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
|
|
||||||
QReadLocker lock(&_containsLock);
|
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
|
||||||
if (laserPointer != _laserPointers.end()) {
|
|
||||||
laserPointer.value()->setIncludeAvatars(includeAvatars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) {
|
|
||||||
QReadLocker lock(&_containsLock);
|
|
||||||
auto laserPointer = _laserPointers.find(uid);
|
|
||||||
if (laserPointer != _laserPointers.end()) {
|
|
||||||
laserPointer.value()->setLockEndUUID(objectID, isOverlay);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,39 +14,38 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include <shared/ReadWriteLockable.h>
|
||||||
|
|
||||||
#include "LaserPointer.h"
|
#include "LaserPointer.h"
|
||||||
|
|
||||||
class RayPickResult;
|
class RayPickResult;
|
||||||
|
|
||||||
class LaserPointerManager {
|
|
||||||
|
class LaserPointerManager : protected ReadWriteLockable {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QUuid createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
|
QUuid createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
|
||||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled);
|
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled);
|
||||||
void removeLaserPointer(const QUuid uid);
|
|
||||||
void enableLaserPointer(const QUuid uid);
|
|
||||||
void disableLaserPointer(const QUuid uid);
|
|
||||||
void setRenderState(QUuid uid, const std::string& renderState);
|
|
||||||
void editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
|
|
||||||
const RayPickResult getPrevRayPickResult(const QUuid uid);
|
|
||||||
|
|
||||||
void setPrecisionPicking(QUuid uid, const bool precisionPicking);
|
void removeLaserPointer(const QUuid& uid);
|
||||||
void setLaserLength(QUuid uid, const float laserLength);
|
void enableLaserPointer(const QUuid& uid) const;
|
||||||
void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities);
|
void disableLaserPointer(const QUuid& uid) const;
|
||||||
void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities);
|
void setRenderState(const QUuid& uid, const std::string& renderState) const;
|
||||||
void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays);
|
void editRenderState(const QUuid& uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) const;
|
||||||
void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays);
|
const RayPickResult getPrevRayPickResult(const QUuid& uid) const;
|
||||||
void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars);
|
|
||||||
void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars);
|
|
||||||
|
|
||||||
void setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay);
|
void setPrecisionPicking(const QUuid& uid, const bool precisionPicking) const;
|
||||||
|
void setLaserLength(const QUuid& uid, const float laserLength) const;
|
||||||
|
void setIgnoreItems(const QUuid& uid, const QVector<QUuid>& ignoreEntities) const;
|
||||||
|
void setIncludeItems(const QUuid& uid, const QVector<QUuid>& includeEntities) const;
|
||||||
|
|
||||||
|
void setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const;
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
LaserPointer::Pointer find(const QUuid& uid) const;
|
||||||
QHash<QUuid, std::shared_ptr<LaserPointer>> _laserPointers;
|
QHash<QUuid, std::shared_ptr<LaserPointer>> _laserPointers;
|
||||||
QReadWriteLock _containsLock;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_LaserPointerManager_h
|
#endif // hifi_LaserPointerManager_h
|
||||||
|
|
|
@ -11,10 +11,19 @@
|
||||||
|
|
||||||
#include "LaserPointerScriptingInterface.h"
|
#include "LaserPointerScriptingInterface.h"
|
||||||
|
|
||||||
#include <QVariant>
|
#include <QtCore/QVariant>
|
||||||
#include "GLMHelpers.h"
|
|
||||||
|
|
||||||
QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) {
|
#include <GLMHelpers.h>
|
||||||
|
#include <RegisteredMetaTypes.h>
|
||||||
|
|
||||||
|
void LaserPointerScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) const {
|
||||||
|
qApp->getLaserPointerManager().setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems));
|
||||||
|
}
|
||||||
|
void LaserPointerScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) const {
|
||||||
|
qApp->getLaserPointerManager().setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems));
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) const {
|
||||||
QVariantMap propertyMap = properties.toMap();
|
QVariantMap propertyMap = properties.toMap();
|
||||||
|
|
||||||
bool faceAvatar = false;
|
bool faceAvatar = false;
|
||||||
|
@ -74,7 +83,7 @@ QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& propert
|
||||||
return qApp->getLaserPointerManager().createLaserPointer(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled);
|
return qApp->getLaserPointerManager().createLaserPointer(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerScriptingInterface::editRenderState(QUuid uid, const QString& renderState, const QVariant& properties) {
|
void LaserPointerScriptingInterface::editRenderState(const QUuid& uid, const QString& renderState, const QVariant& properties) const {
|
||||||
QVariantMap propMap = properties.toMap();
|
QVariantMap propMap = properties.toMap();
|
||||||
|
|
||||||
QVariant startProps;
|
QVariant startProps;
|
||||||
|
@ -95,7 +104,7 @@ void LaserPointerScriptingInterface::editRenderState(QUuid uid, const QString& r
|
||||||
qApp->getLaserPointerManager().editRenderState(uid, renderState.toStdString(), startProps, pathProps, endProps);
|
qApp->getLaserPointerManager().editRenderState(uid, renderState.toStdString(), startProps, pathProps, endProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
const RenderState LaserPointerScriptingInterface::buildRenderState(const QVariantMap& propMap) {
|
RenderState LaserPointerScriptingInterface::buildRenderState(const QVariantMap& propMap) {
|
||||||
QUuid startID;
|
QUuid startID;
|
||||||
if (propMap["start"].isValid()) {
|
if (propMap["start"].isValid()) {
|
||||||
QVariantMap startMap = propMap["start"].toMap();
|
QVariantMap startMap = propMap["start"].toMap();
|
||||||
|
|
|
@ -22,27 +22,23 @@ class LaserPointerScriptingInterface : public QObject, public Dependency {
|
||||||
SINGLETON_DEPENDENCY
|
SINGLETON_DEPENDENCY
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
Q_INVOKABLE QUuid createLaserPointer(const QVariant& properties);
|
Q_INVOKABLE QUuid createLaserPointer(const QVariant& properties) const;
|
||||||
Q_INVOKABLE void enableLaserPointer(QUuid uid) { qApp->getLaserPointerManager().enableLaserPointer(uid); }
|
Q_INVOKABLE void enableLaserPointer(const QUuid& uid) const { qApp->getLaserPointerManager().enableLaserPointer(uid); }
|
||||||
Q_INVOKABLE void disableLaserPointer(QUuid uid) { qApp->getLaserPointerManager().disableLaserPointer(uid); }
|
Q_INVOKABLE void disableLaserPointer(const QUuid& uid) const { qApp->getLaserPointerManager().disableLaserPointer(uid); }
|
||||||
Q_INVOKABLE void removeLaserPointer(QUuid uid) { qApp->getLaserPointerManager().removeLaserPointer(uid); }
|
Q_INVOKABLE void removeLaserPointer(const QUuid& uid) const { qApp->getLaserPointerManager().removeLaserPointer(uid); }
|
||||||
Q_INVOKABLE void editRenderState(QUuid uid, const QString& renderState, const QVariant& properties);
|
Q_INVOKABLE void editRenderState(const QUuid& uid, const QString& renderState, const QVariant& properties) const;
|
||||||
Q_INVOKABLE void setRenderState(QUuid uid, const QString& renderState) { qApp->getLaserPointerManager().setRenderState(uid, renderState.toStdString()); }
|
Q_INVOKABLE void setRenderState(const QUuid& uid, const QString& renderState) const { qApp->getLaserPointerManager().setRenderState(uid, renderState.toStdString()); }
|
||||||
Q_INVOKABLE RayPickResult getPrevRayPickResult(QUuid uid) { return qApp->getLaserPointerManager().getPrevRayPickResult(uid); }
|
Q_INVOKABLE RayPickResult getPrevRayPickResult(QUuid uid) const { return qApp->getLaserPointerManager().getPrevRayPickResult(uid); }
|
||||||
|
|
||||||
Q_INVOKABLE void setPrecisionPicking(QUuid uid, const bool precisionPicking) { qApp->getLaserPointerManager().setPrecisionPicking(uid, precisionPicking); }
|
Q_INVOKABLE void setPrecisionPicking(const QUuid& uid, bool precisionPicking) const { qApp->getLaserPointerManager().setPrecisionPicking(uid, precisionPicking); }
|
||||||
Q_INVOKABLE void setLaserLength(QUuid uid, const float laserLength) { qApp->getLaserPointerManager().setLaserLength(uid, laserLength); }
|
Q_INVOKABLE void setLaserLength(const QUuid& uid, float laserLength) const { qApp->getLaserPointerManager().setLaserLength(uid, laserLength); }
|
||||||
Q_INVOKABLE void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { qApp->getLaserPointerManager().setIgnoreEntities(uid, ignoreEntities); }
|
Q_INVOKABLE void setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreEntities) const;
|
||||||
Q_INVOKABLE void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { qApp->getLaserPointerManager().setIncludeEntities(uid, includeEntities); }
|
Q_INVOKABLE void setIncludeItems(const QUuid& uid, const QScriptValue& includeEntities) const;
|
||||||
Q_INVOKABLE void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { qApp->getLaserPointerManager().setIgnoreOverlays(uid, ignoreOverlays); }
|
|
||||||
Q_INVOKABLE void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { qApp->getLaserPointerManager().setIncludeOverlays(uid, includeOverlays); }
|
|
||||||
Q_INVOKABLE void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { qApp->getLaserPointerManager().setIgnoreAvatars(uid, ignoreAvatars); }
|
|
||||||
Q_INVOKABLE void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { qApp->getLaserPointerManager().setIncludeAvatars(uid, includeAvatars); }
|
|
||||||
|
|
||||||
Q_INVOKABLE void setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) { qApp->getLaserPointerManager().setLockEndUUID(uid, objectID, isOverlay); }
|
Q_INVOKABLE void setLockEndUUID(const QUuid& uid, const QUuid& objectID, bool isOverlay) const { qApp->getLaserPointerManager().setLockEndUUID(uid, objectID, isOverlay); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const RenderState buildRenderState(const QVariantMap& propMap);
|
static RenderState buildRenderState(const QVariantMap& propMap);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#ifndef hifi_MouseRayPick_h
|
#ifndef hifi_MouseRayPick_h
|
||||||
#define hifi_MouseRayPick_h
|
#define hifi_MouseRayPick_h
|
||||||
|
|
||||||
#include "RayPick.h"
|
#include <pointers/rays/RayPick.h>
|
||||||
|
|
||||||
class MouseRayPick : public RayPick {
|
class MouseRayPick : public RayPick {
|
||||||
|
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
//
|
|
||||||
// RayPick.cpp
|
|
||||||
// interface/src/raypick
|
|
||||||
//
|
|
||||||
// Created by Sam Gondelman 7/11/2017
|
|
||||||
// Copyright 2017 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 "RayPick.h"
|
|
||||||
|
|
||||||
RayPick::RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) :
|
|
||||||
_filter(filter),
|
|
||||||
_maxDistance(maxDistance),
|
|
||||||
_enabled(enabled)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void RayPick::enable() {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
_enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPick::disable() {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
_enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RayPickResult& RayPick::getPrevRayPickResult() {
|
|
||||||
QReadLocker lock(getLock());
|
|
||||||
return _prevResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPick::setIgnoreEntities(const QScriptValue& ignoreEntities) {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
_ignoreEntities = qVectorEntityItemIDFromScriptValue(ignoreEntities);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPick::setIncludeEntities(const QScriptValue& includeEntities) {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
_includeEntities = qVectorEntityItemIDFromScriptValue(includeEntities);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPick::setIgnoreOverlays(const QScriptValue& ignoreOverlays) {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
_ignoreOverlays = qVectorOverlayIDFromScriptValue(ignoreOverlays);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPick::setIncludeOverlays(const QScriptValue& includeOverlays) {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
_includeOverlays = qVectorOverlayIDFromScriptValue(includeOverlays);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPick::setIgnoreAvatars(const QScriptValue& ignoreAvatars) {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
_ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPick::setIncludeAvatars(const QScriptValue& includeAvatars) {
|
|
||||||
QWriteLocker lock(getLock());
|
|
||||||
_includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars);
|
|
||||||
}
|
|
|
@ -10,6 +10,8 @@
|
||||||
//
|
//
|
||||||
#include "RayPickManager.h"
|
#include "RayPickManager.h"
|
||||||
|
|
||||||
|
#include <pointers/rays/StaticRayPick.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "EntityScriptingInterface.h"
|
#include "EntityScriptingInterface.h"
|
||||||
#include "ui/overlays/Overlays.h"
|
#include "ui/overlays/Overlays.h"
|
||||||
|
@ -18,45 +20,50 @@
|
||||||
#include "DependencyManager.h"
|
#include "DependencyManager.h"
|
||||||
|
|
||||||
#include "JointRayPick.h"
|
#include "JointRayPick.h"
|
||||||
#include "StaticRayPick.h"
|
|
||||||
#include "MouseRayPick.h"
|
#include "MouseRayPick.h"
|
||||||
|
|
||||||
bool RayPickManager::checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, const RayPickFilter::Flags& mask) {
|
bool RayPickManager::checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, const RayCacheKey& key) {
|
||||||
if (cache.contains(ray) && cache[ray].find(mask) != cache[ray].end()) {
|
if (cache.contains(ray) && cache[ray].find(key) != cache[ray].end()) {
|
||||||
if (cache[ray][mask].distance < res.distance) {
|
if (cache[ray][key].distance < res.distance) {
|
||||||
res = cache[ray][mask];
|
res = cache[ray][key];
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::cacheResult(const bool intersects, const RayPickResult& resTemp, const RayPickFilter::Flags& mask, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache) {
|
void RayPickManager::cacheResult(const bool intersects, const RayPickResult& resTemp, const RayCacheKey& key, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache) {
|
||||||
if (intersects) {
|
if (intersects) {
|
||||||
cache[ray][mask] = resTemp;
|
cache[ray][key] = resTemp;
|
||||||
if (resTemp.distance < res.distance) {
|
if (resTemp.distance < res.distance) {
|
||||||
res = resTemp;
|
res = resTemp;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cache[ray][mask] = RayPickResult(res.searchRay);
|
cache[ray][key] = RayPickResult(res.searchRay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::update() {
|
void RayPickManager::update() {
|
||||||
QReadLocker lock(&_containsLock);
|
|
||||||
RayPickCache results;
|
RayPickCache results;
|
||||||
for (auto& uid : _rayPicks.keys()) {
|
QHash<QUuid, RayPick::Pointer> cachedRayPicks;
|
||||||
std::shared_ptr<RayPick> rayPick = _rayPicks[uid];
|
withReadLock([&] {
|
||||||
QWriteLocker lock(rayPick->getLock());
|
cachedRayPicks = _rayPicks;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const auto& uid : cachedRayPicks.keys()) {
|
||||||
|
std::shared_ptr<RayPick> rayPick = cachedRayPicks[uid];
|
||||||
if (!rayPick->isEnabled() || rayPick->getFilter().doesPickNothing() || rayPick->getMaxDistance() < 0.0f) {
|
if (!rayPick->isEnabled() || rayPick->getFilter().doesPickNothing() || rayPick->getMaxDistance() < 0.0f) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid;
|
PickRay ray;
|
||||||
PickRay ray = rayPick->getPickRay(valid);
|
|
||||||
|
|
||||||
if (!valid) {
|
{
|
||||||
continue;
|
bool valid;
|
||||||
|
ray = rayPick->getPickRay(valid);
|
||||||
|
if (!valid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<glm::vec3, glm::vec3> rayKey = QPair<glm::vec3, glm::vec3>(ray.origin, ray.direction);
|
QPair<glm::vec3, glm::vec3> rayKey = QPair<glm::vec3, glm::vec3>(ray.origin, ray.direction);
|
||||||
|
@ -67,16 +74,16 @@ void RayPickManager::update() {
|
||||||
bool fromCache = true;
|
bool fromCache = true;
|
||||||
bool invisible = rayPick->getFilter().doesPickInvisible();
|
bool invisible = rayPick->getFilter().doesPickInvisible();
|
||||||
bool nonCollidable = rayPick->getFilter().doesPickNonCollidable();
|
bool nonCollidable = rayPick->getFilter().doesPickNonCollidable();
|
||||||
RayPickFilter::Flags entityMask = rayPick->getFilter().getEntityFlags();
|
RayCacheKey entityKey = { rayPick->getFilter().getEntityFlags(), rayPick->getIncludeItems(), rayPick->getIgnoreItems() };
|
||||||
if (!checkAndCompareCachedResults(rayKey, results, res, entityMask)) {
|
if (!checkAndCompareCachedResults(rayKey, results, res, entityKey)) {
|
||||||
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCourse(),
|
entityRes = DependencyManager::get<EntityScriptingInterface>()->findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCoarse(),
|
||||||
rayPick->getIncludeEntites(), rayPick->getIgnoreEntites(), !invisible, !nonCollidable);
|
rayPick->getIncludeItemsAs<EntityItemID>(), rayPick->getIgnoreItemsAs<EntityItemID>(), !invisible, !nonCollidable);
|
||||||
fromCache = false;
|
fromCache = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fromCache) {
|
if (!fromCache) {
|
||||||
cacheResult(entityRes.intersects, RayPickResult(IntersectionType::ENTITY, entityRes.entityID, entityRes.distance, entityRes.intersection, ray, entityRes.surfaceNormal),
|
cacheResult(entityRes.intersects, RayPickResult(IntersectionType::ENTITY, entityRes.entityID, entityRes.distance, entityRes.intersection, ray, entityRes.surfaceNormal),
|
||||||
entityMask, res, rayKey, results);
|
entityKey, res, rayKey, results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,33 +92,34 @@ void RayPickManager::update() {
|
||||||
bool fromCache = true;
|
bool fromCache = true;
|
||||||
bool invisible = rayPick->getFilter().doesPickInvisible();
|
bool invisible = rayPick->getFilter().doesPickInvisible();
|
||||||
bool nonCollidable = rayPick->getFilter().doesPickNonCollidable();
|
bool nonCollidable = rayPick->getFilter().doesPickNonCollidable();
|
||||||
RayPickFilter::Flags overlayMask = rayPick->getFilter().getOverlayFlags();
|
RayCacheKey overlayKey = { rayPick->getFilter().getOverlayFlags(), rayPick->getIncludeItems(), rayPick->getIgnoreItems() };
|
||||||
if (!checkAndCompareCachedResults(rayKey, results, res, overlayMask)) {
|
if (!checkAndCompareCachedResults(rayKey, results, res, overlayKey)) {
|
||||||
overlayRes = qApp->getOverlays().findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCourse(),
|
overlayRes = qApp->getOverlays().findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCoarse(),
|
||||||
rayPick->getIncludeOverlays(), rayPick->getIgnoreOverlays(), !invisible, !nonCollidable);
|
rayPick->getIncludeItemsAs<OverlayID>(), rayPick->getIgnoreItemsAs<OverlayID>(), !invisible, !nonCollidable);
|
||||||
fromCache = false;
|
fromCache = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fromCache) {
|
if (!fromCache) {
|
||||||
cacheResult(overlayRes.intersects, RayPickResult(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, ray, overlayRes.surfaceNormal),
|
cacheResult(overlayRes.intersects, RayPickResult(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, ray, overlayRes.surfaceNormal),
|
||||||
overlayMask, res, rayKey, results);
|
overlayKey, res, rayKey, results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rayPick->getFilter().doesPickAvatars()) {
|
if (rayPick->getFilter().doesPickAvatars()) {
|
||||||
RayPickFilter::Flags avatarMask = rayPick->getFilter().getAvatarFlags();
|
RayCacheKey avatarKey = { rayPick->getFilter().getAvatarFlags(), rayPick->getIncludeItems(), rayPick->getIgnoreItems() };
|
||||||
if (!checkAndCompareCachedResults(rayKey, results, res, avatarMask)) {
|
if (!checkAndCompareCachedResults(rayKey, results, res, avatarKey)) {
|
||||||
RayToAvatarIntersectionResult avatarRes = DependencyManager::get<AvatarManager>()->findRayIntersectionVector(ray, rayPick->getIncludeAvatars(), rayPick->getIgnoreAvatars());
|
RayToAvatarIntersectionResult avatarRes = DependencyManager::get<AvatarManager>()->findRayIntersectionVector(ray,
|
||||||
cacheResult(avatarRes.intersects, RayPickResult(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection, ray), avatarMask, res, rayKey, results);
|
rayPick->getIncludeItemsAs<EntityItemID>(), rayPick->getIgnoreItemsAs<EntityItemID>());
|
||||||
|
cacheResult(avatarRes.intersects, RayPickResult(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection, ray), avatarKey, res, rayKey, results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't intersect with HUD in desktop mode
|
// Can't intersect with HUD in desktop mode
|
||||||
if (rayPick->getFilter().doesPickHUD() && DependencyManager::get<HMDScriptingInterface>()->isHMDMode()) {
|
if (rayPick->getFilter().doesPickHUD() && DependencyManager::get<HMDScriptingInterface>()->isHMDMode()) {
|
||||||
RayPickFilter::Flags hudMask = rayPick->getFilter().getHUDFlags();
|
RayCacheKey hudKey = { rayPick->getFilter().getHUDFlags(), QVector<QUuid>(), QVector<QUuid>() };
|
||||||
if (!checkAndCompareCachedResults(rayKey, results, res, hudMask)) {
|
if (!checkAndCompareCachedResults(rayKey, results, res, hudKey)) {
|
||||||
glm::vec3 hudRes = DependencyManager::get<HMDScriptingInterface>()->calculateRayUICollisionPoint(ray.origin, ray.direction);
|
glm::vec3 hudRes = DependencyManager::get<HMDScriptingInterface>()->calculateRayUICollisionPoint(ray.origin, ray.direction);
|
||||||
cacheResult(true, RayPickResult(IntersectionType::HUD, 0, glm::distance(ray.origin, hudRes), hudRes, ray), hudMask, res, rayKey, results);
|
cacheResult(true, RayPickResult(IntersectionType::HUD, 0, glm::distance(ray.origin, hudRes), hudRes, ray), hudKey, res, rayKey, results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,109 +131,87 @@ void RayPickManager::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid RayPickManager::createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled) {
|
QUuid RayPickManager::createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, float maxDistance, bool enabled) {
|
||||||
QWriteLocker lock(&_containsLock);
|
auto newRayPick = std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled);
|
||||||
QUuid id = QUuid::createUuid();
|
QUuid id = QUuid::createUuid();
|
||||||
_rayPicks[id] = std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled);
|
withWriteLock([&] {
|
||||||
|
_rayPicks[id] = newRayPick;
|
||||||
|
});
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid RayPickManager::createRayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) {
|
QUuid RayPickManager::createRayPick(const RayPickFilter& filter, float maxDistance, bool enabled) {
|
||||||
QWriteLocker lock(&_containsLock);
|
|
||||||
QUuid id = QUuid::createUuid();
|
QUuid id = QUuid::createUuid();
|
||||||
_rayPicks[id] = std::make_shared<MouseRayPick>(filter, maxDistance, enabled);
|
auto newRayPick = std::make_shared<MouseRayPick>(filter, maxDistance, enabled);
|
||||||
|
withWriteLock([&] {
|
||||||
|
_rayPicks[id] = newRayPick;
|
||||||
|
});
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid RayPickManager::createRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance, const bool enabled) {
|
QUuid RayPickManager::createRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, float maxDistance, bool enabled) {
|
||||||
QWriteLocker lock(&_containsLock);
|
|
||||||
QUuid id = QUuid::createUuid();
|
QUuid id = QUuid::createUuid();
|
||||||
_rayPicks[id] = std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled);
|
auto newRayPick = std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled);
|
||||||
|
withWriteLock([&] {
|
||||||
|
_rayPicks[id] = newRayPick;
|
||||||
|
});
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::removeRayPick(const QUuid uid) {
|
void RayPickManager::removeRayPick(const QUuid& uid) {
|
||||||
QWriteLocker lock(&_containsLock);
|
withWriteLock([&] {
|
||||||
_rayPicks.remove(uid);
|
_rayPicks.remove(uid);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::enableRayPick(const QUuid uid) {
|
RayPick::Pointer RayPickManager::findRayPick(const QUuid& uid) const {
|
||||||
QReadLocker containsLock(&_containsLock);
|
return resultWithReadLock<RayPick::Pointer>([&] {
|
||||||
auto rayPick = _rayPicks.find(uid);
|
if (_rayPicks.contains(uid)) {
|
||||||
if (rayPick != _rayPicks.end()) {
|
return _rayPicks[uid];
|
||||||
rayPick.value()->enable();
|
}
|
||||||
|
return RayPick::Pointer();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RayPickManager::enableRayPick(const QUuid& uid) const {
|
||||||
|
auto rayPick = findRayPick(uid);
|
||||||
|
if (rayPick) {
|
||||||
|
rayPick->enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::disableRayPick(const QUuid uid) {
|
void RayPickManager::disableRayPick(const QUuid& uid) const {
|
||||||
QReadLocker containsLock(&_containsLock);
|
auto rayPick = findRayPick(uid);
|
||||||
auto rayPick = _rayPicks.find(uid);
|
if (rayPick) {
|
||||||
if (rayPick != _rayPicks.end()) {
|
rayPick->disable();
|
||||||
rayPick.value()->disable();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) {
|
RayPickResult RayPickManager::getPrevRayPickResult(const QUuid& uid) const {
|
||||||
QReadLocker containsLock(&_containsLock);
|
auto rayPick = findRayPick(uid);
|
||||||
auto rayPick = _rayPicks.find(uid);
|
if (rayPick) {
|
||||||
if (rayPick != _rayPicks.end()) {
|
return rayPick->getPrevRayPickResult();
|
||||||
return rayPick.value()->getPrevRayPickResult();
|
|
||||||
}
|
}
|
||||||
return RayPickResult();
|
return RayPickResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) {
|
void RayPickManager::setPrecisionPicking(const QUuid& uid, bool precisionPicking) const {
|
||||||
QReadLocker containsLock(&_containsLock);
|
auto rayPick = findRayPick(uid);
|
||||||
auto rayPick = _rayPicks.find(uid);
|
if (rayPick) {
|
||||||
if (rayPick != _rayPicks.end()) {
|
rayPick->setPrecisionPicking(precisionPicking);
|
||||||
rayPick.value()->setPrecisionPicking(precisionPicking);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
|
void RayPickManager::setIgnoreItems(const QUuid& uid, const QVector<QUuid>& ignore) const {
|
||||||
QReadLocker containsLock(&_containsLock);
|
auto rayPick = findRayPick(uid);
|
||||||
auto rayPick = _rayPicks.find(uid);
|
if (rayPick) {
|
||||||
if (rayPick != _rayPicks.end()) {
|
rayPick->setIgnoreItems(ignore);
|
||||||
rayPick.value()->setIgnoreEntities(ignoreEntities);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
|
void RayPickManager::setIncludeItems(const QUuid& uid, const QVector<QUuid>& include) const {
|
||||||
QReadLocker containsLock(&_containsLock);
|
auto rayPick = findRayPick(uid);
|
||||||
auto rayPick = _rayPicks.find(uid);
|
if (rayPick) {
|
||||||
if (rayPick != _rayPicks.end()) {
|
rayPick->setIncludeItems(include);
|
||||||
rayPick.value()->setIncludeEntities(includeEntities);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
|
|
||||||
QReadLocker containsLock(&_containsLock);
|
|
||||||
auto rayPick = _rayPicks.find(uid);
|
|
||||||
if (rayPick != _rayPicks.end()) {
|
|
||||||
rayPick.value()->setIgnoreOverlays(ignoreOverlays);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
|
|
||||||
QReadLocker containsLock(&_containsLock);
|
|
||||||
auto rayPick = _rayPicks.find(uid);
|
|
||||||
if (rayPick != _rayPicks.end()) {
|
|
||||||
rayPick.value()->setIncludeOverlays(includeOverlays);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
|
|
||||||
QReadLocker containsLock(&_containsLock);
|
|
||||||
auto rayPick = _rayPicks.find(uid);
|
|
||||||
if (rayPick != _rayPicks.end()) {
|
|
||||||
rayPick.value()->setIgnoreAvatars(ignoreAvatars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
|
|
||||||
QReadLocker containsLock(&_containsLock);
|
|
||||||
auto rayPick = _rayPicks.find(uid);
|
|
||||||
if (rayPick != _rayPicks.end()) {
|
|
||||||
rayPick.value()->setIncludeAvatars(includeAvatars);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,19 +11,39 @@
|
||||||
#ifndef hifi_RayPickManager_h
|
#ifndef hifi_RayPickManager_h
|
||||||
#define hifi_RayPickManager_h
|
#define hifi_RayPickManager_h
|
||||||
|
|
||||||
#include "RayPick.h"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QtCore/QObject>
|
|
||||||
|
|
||||||
#include "RegisteredMetaTypes.h"
|
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
#include <RegisteredMetaTypes.h>
|
||||||
|
#include <pointers/rays/RayPick.h>
|
||||||
|
|
||||||
|
|
||||||
class RayPickResult;
|
class RayPickResult;
|
||||||
|
|
||||||
class RayPickManager {
|
typedef struct RayCacheKey {
|
||||||
|
RayPickFilter::Flags mask;
|
||||||
|
QVector<QUuid> include;
|
||||||
|
QVector<QUuid> ignore;
|
||||||
|
|
||||||
|
bool operator==(const RayCacheKey& other) const {
|
||||||
|
return (mask == other.mask && include == other.include && ignore == other.ignore);
|
||||||
|
}
|
||||||
|
} RayCacheKey;
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <>
|
||||||
|
struct hash<RayCacheKey> {
|
||||||
|
size_t operator()(const RayCacheKey& k) const {
|
||||||
|
return ((hash<RayPickFilter::Flags>()(k.mask) ^ (qHash(k.include) << 1)) >> 1) ^ (qHash(k.ignore) << 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class RayPickManager : protected ReadWriteLockable {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void update();
|
void update();
|
||||||
|
@ -31,28 +51,24 @@ public:
|
||||||
QUuid createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled);
|
QUuid createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled);
|
||||||
QUuid createRayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled);
|
QUuid createRayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled);
|
||||||
QUuid createRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance, const bool enabled);
|
QUuid createRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance, const bool enabled);
|
||||||
void removeRayPick(const QUuid uid);
|
void removeRayPick(const QUuid& uid);
|
||||||
void enableRayPick(const QUuid uid);
|
void enableRayPick(const QUuid& uid) const;
|
||||||
void disableRayPick(const QUuid uid);
|
void disableRayPick(const QUuid& uid) const;
|
||||||
const RayPickResult getPrevRayPickResult(const QUuid uid);
|
RayPickResult getPrevRayPickResult(const QUuid& uid) const;
|
||||||
|
|
||||||
void setPrecisionPicking(QUuid uid, const bool precisionPicking);
|
void setPrecisionPicking(const QUuid& uid, bool precisionPicking) const;
|
||||||
void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities);
|
void setIgnoreItems(const QUuid& uid, const QVector<QUuid>& ignore) const;
|
||||||
void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities);
|
void setIncludeItems(const QUuid& uid, const QVector<QUuid>& include) const;
|
||||||
void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays);
|
|
||||||
void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays);
|
|
||||||
void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars);
|
|
||||||
void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<QUuid, std::shared_ptr<RayPick>> _rayPicks;
|
RayPick::Pointer findRayPick(const QUuid& uid) const;
|
||||||
QReadWriteLock _containsLock;
|
QHash<QUuid, RayPick::Pointer> _rayPicks;
|
||||||
|
|
||||||
typedef QHash<QPair<glm::vec3, glm::vec3>, std::unordered_map<RayPickFilter::Flags, RayPickResult>> RayPickCache;
|
typedef QHash<QPair<glm::vec3, glm::vec3>, std::unordered_map<RayCacheKey, RayPickResult>> RayPickCache;
|
||||||
|
|
||||||
// Returns true if this ray exists in the cache, and if it does, update res if the cached result is closer
|
// Returns true if this ray exists in the cache, and if it does, update res if the cached result is closer
|
||||||
bool checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, const RayPickFilter::Flags& mask);
|
bool checkAndCompareCachedResults(QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache, RayPickResult& res, const RayCacheKey& key);
|
||||||
void cacheResult(const bool intersects, const RayPickResult& resTemp, const RayPickFilter::Flags& mask, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache);
|
void cacheResult(const bool intersects, const RayPickResult& resTemp, const RayCacheKey& key, RayPickResult& res, QPair<glm::vec3, glm::vec3>& ray, RayPickCache& cache);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_RayPickManager_h
|
#endif // hifi_RayPickManager_h
|
|
@ -66,46 +66,30 @@ QUuid RayPickScriptingInterface::createRayPick(const QVariant& properties) {
|
||||||
return QUuid();
|
return QUuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickScriptingInterface::enableRayPick(QUuid uid) {
|
void RayPickScriptingInterface::enableRayPick(const QUuid& uid) {
|
||||||
qApp->getRayPickManager().enableRayPick(uid);
|
qApp->getRayPickManager().enableRayPick(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickScriptingInterface::disableRayPick(QUuid uid) {
|
void RayPickScriptingInterface::disableRayPick(const QUuid& uid) {
|
||||||
qApp->getRayPickManager().disableRayPick(uid);
|
qApp->getRayPickManager().disableRayPick(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickScriptingInterface::removeRayPick(QUuid uid) {
|
void RayPickScriptingInterface::removeRayPick(const QUuid& uid) {
|
||||||
qApp->getRayPickManager().removeRayPick(uid);
|
qApp->getRayPickManager().removeRayPick(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
RayPickResult RayPickScriptingInterface::getPrevRayPickResult(QUuid uid) {
|
RayPickResult RayPickScriptingInterface::getPrevRayPickResult(const QUuid& uid) {
|
||||||
return qApp->getRayPickManager().getPrevRayPickResult(uid);
|
return qApp->getRayPickManager().getPrevRayPickResult(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickScriptingInterface::setPrecisionPicking(QUuid uid, const bool precisionPicking) {
|
void RayPickScriptingInterface::setPrecisionPicking(const QUuid& uid, const bool precisionPicking) {
|
||||||
qApp->getRayPickManager().setPrecisionPicking(uid, precisionPicking);
|
qApp->getRayPickManager().setPrecisionPicking(uid, precisionPicking);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickScriptingInterface::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
|
void RayPickScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) {
|
||||||
qApp->getRayPickManager().setIgnoreEntities(uid, ignoreEntities);
|
qApp->getRayPickManager().setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayPickScriptingInterface::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
|
void RayPickScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) {
|
||||||
qApp->getRayPickManager().setIncludeEntities(uid, includeEntities);
|
qApp->getRayPickManager().setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems));
|
||||||
}
|
|
||||||
|
|
||||||
void RayPickScriptingInterface::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
|
|
||||||
qApp->getRayPickManager().setIgnoreOverlays(uid, ignoreOverlays);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPickScriptingInterface::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
|
|
||||||
qApp->getRayPickManager().setIncludeOverlays(uid, includeOverlays);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPickScriptingInterface::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
|
|
||||||
qApp->getRayPickManager().setIgnoreAvatars(uid, ignoreAvatars);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RayPickScriptingInterface::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
|
|
||||||
qApp->getRayPickManager().setIncludeAvatars(uid, includeAvatars);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,9 @@
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
#include "RegisteredMetaTypes.h"
|
#include <RegisteredMetaTypes.h>
|
||||||
#include "DependencyManager.h"
|
#include <DependencyManager.h>
|
||||||
|
#include <pointers/rays/RayPick.h>
|
||||||
#include "RayPick.h"
|
|
||||||
|
|
||||||
class RayPickScriptingInterface : public QObject, public Dependency {
|
class RayPickScriptingInterface : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -25,7 +24,7 @@ class RayPickScriptingInterface : public QObject, public Dependency {
|
||||||
Q_PROPERTY(unsigned int PICK_OVERLAYS READ PICK_OVERLAYS CONSTANT)
|
Q_PROPERTY(unsigned int PICK_OVERLAYS READ PICK_OVERLAYS CONSTANT)
|
||||||
Q_PROPERTY(unsigned int PICK_AVATARS READ PICK_AVATARS CONSTANT)
|
Q_PROPERTY(unsigned int PICK_AVATARS READ PICK_AVATARS CONSTANT)
|
||||||
Q_PROPERTY(unsigned int PICK_HUD READ PICK_HUD CONSTANT)
|
Q_PROPERTY(unsigned int PICK_HUD READ PICK_HUD CONSTANT)
|
||||||
Q_PROPERTY(unsigned int PICK_COURSE READ PICK_COURSE CONSTANT)
|
Q_PROPERTY(unsigned int PICK_COARSE READ PICK_COARSE CONSTANT)
|
||||||
Q_PROPERTY(unsigned int PICK_INCLUDE_INVISIBLE READ PICK_INCLUDE_INVISIBLE CONSTANT)
|
Q_PROPERTY(unsigned int PICK_INCLUDE_INVISIBLE READ PICK_INCLUDE_INVISIBLE CONSTANT)
|
||||||
Q_PROPERTY(unsigned int PICK_INCLUDE_NONCOLLIDABLE READ PICK_INCLUDE_NONCOLLIDABLE CONSTANT)
|
Q_PROPERTY(unsigned int PICK_INCLUDE_NONCOLLIDABLE READ PICK_INCLUDE_NONCOLLIDABLE CONSTANT)
|
||||||
Q_PROPERTY(unsigned int PICK_ALL_INTERSECTIONS READ PICK_ALL_INTERSECTIONS CONSTANT)
|
Q_PROPERTY(unsigned int PICK_ALL_INTERSECTIONS READ PICK_ALL_INTERSECTIONS CONSTANT)
|
||||||
|
@ -38,25 +37,21 @@ class RayPickScriptingInterface : public QObject, public Dependency {
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
Q_INVOKABLE QUuid createRayPick(const QVariant& properties);
|
Q_INVOKABLE QUuid createRayPick(const QVariant& properties);
|
||||||
Q_INVOKABLE void enableRayPick(QUuid uid);
|
Q_INVOKABLE void enableRayPick(const QUuid& uid);
|
||||||
Q_INVOKABLE void disableRayPick(QUuid uid);
|
Q_INVOKABLE void disableRayPick(const QUuid& uid);
|
||||||
Q_INVOKABLE void removeRayPick(QUuid uid);
|
Q_INVOKABLE void removeRayPick(const QUuid& uid);
|
||||||
Q_INVOKABLE RayPickResult getPrevRayPickResult(QUuid uid);
|
Q_INVOKABLE RayPickResult getPrevRayPickResult(const QUuid& uid);
|
||||||
|
|
||||||
Q_INVOKABLE void setPrecisionPicking(QUuid uid, const bool precisionPicking);
|
Q_INVOKABLE void setPrecisionPicking(const QUuid& uid, const bool precisionPicking);
|
||||||
Q_INVOKABLE void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities);
|
Q_INVOKABLE void setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreEntities);
|
||||||
Q_INVOKABLE void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities);
|
Q_INVOKABLE void setIncludeItems(const QUuid& uid, const QScriptValue& includeEntities);
|
||||||
Q_INVOKABLE void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays);
|
|
||||||
Q_INVOKABLE void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays);
|
|
||||||
Q_INVOKABLE void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars);
|
|
||||||
Q_INVOKABLE void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars);
|
|
||||||
|
|
||||||
unsigned int PICK_NOTHING() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_NOTHING); }
|
unsigned int PICK_NOTHING() { return 0; }
|
||||||
unsigned int PICK_ENTITIES() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_ENTITIES); }
|
unsigned int PICK_ENTITIES() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_ENTITIES); }
|
||||||
unsigned int PICK_OVERLAYS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_OVERLAYS); }
|
unsigned int PICK_OVERLAYS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_OVERLAYS); }
|
||||||
unsigned int PICK_AVATARS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_AVATARS); }
|
unsigned int PICK_AVATARS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_AVATARS); }
|
||||||
unsigned int PICK_HUD() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_HUD); }
|
unsigned int PICK_HUD() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_HUD); }
|
||||||
unsigned int PICK_COURSE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_COURSE); }
|
unsigned int PICK_COARSE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_COARSE); }
|
||||||
unsigned int PICK_INCLUDE_INVISIBLE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_INCLUDE_INVISIBLE); }
|
unsigned int PICK_INCLUDE_INVISIBLE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_INCLUDE_INVISIBLE); }
|
||||||
unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_INCLUDE_NONCOLLIDABLE); }
|
unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_INCLUDE_NONCOLLIDABLE); }
|
||||||
unsigned int PICK_ALL_INTERSECTIONS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_ALL_INTERSECTIONS); }
|
unsigned int PICK_ALL_INTERSECTIONS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_ALL_INTERSECTIONS); }
|
||||||
|
|
|
@ -51,13 +51,11 @@ void Image3DOverlay::update(float deltatime) {
|
||||||
_texture = DependencyManager::get<TextureCache>()->getTexture(_url);
|
_texture = DependencyManager::get<TextureCache>()->getTexture(_url);
|
||||||
_textureIsLoaded = false;
|
_textureIsLoaded = false;
|
||||||
}
|
}
|
||||||
#if OVERLAY_PANELS
|
|
||||||
if (usecTimestampNow() > _transformExpiry) {
|
if (usecTimestampNow() > _transformExpiry) {
|
||||||
Transform transform = getTransform();
|
Transform transform = getTransform();
|
||||||
applyTransformTo(transform);
|
applyTransformTo(transform);
|
||||||
setTransform(transform);
|
setTransform(transform);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
Parent::update(deltatime);
|
Parent::update(deltatime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,3 @@ bool Text3DOverlay::findRayIntersection(const glm::vec3 &origin, const glm::vec3
|
||||||
return Billboard3DOverlay::findRayIntersection(origin, direction, distance, face, surfaceNormal);
|
return Billboard3DOverlay::findRayIntersection(origin, direction, distance, face, surfaceNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform Text3DOverlay::evalRenderTransform() {
|
|
||||||
return Parent::evalRenderTransform();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -65,9 +65,6 @@ public:
|
||||||
|
|
||||||
virtual Text3DOverlay* createClone() const override;
|
virtual Text3DOverlay* createClone() const override;
|
||||||
|
|
||||||
protected:
|
|
||||||
Transform evalRenderTransform() override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextRenderer3D* _textRenderer = nullptr;
|
TextRenderer3D* _textRenderer = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,6 @@ static const float OPAQUE_ALPHA_THRESHOLD = 0.99f;
|
||||||
|
|
||||||
const QString Web3DOverlay::TYPE = "web3d";
|
const QString Web3DOverlay::TYPE = "web3d";
|
||||||
const QString Web3DOverlay::QML = "Web3DOverlay.qml";
|
const QString Web3DOverlay::QML = "Web3DOverlay.qml";
|
||||||
|
|
||||||
Web3DOverlay::Web3DOverlay() : _dpi(DPI) {
|
Web3DOverlay::Web3DOverlay() : _dpi(DPI) {
|
||||||
_touchDevice.setCapabilities(QTouchDevice::Position);
|
_touchDevice.setCapabilities(QTouchDevice::Position);
|
||||||
_touchDevice.setType(QTouchDevice::TouchScreen);
|
_touchDevice.setType(QTouchDevice::TouchScreen);
|
||||||
|
@ -248,6 +247,9 @@ void Web3DOverlay::setupQmlSurface() {
|
||||||
|
|
||||||
_webSurface->getSurfaceContext()->setContextProperty("pathToFonts", "../../");
|
_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());
|
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface.data());
|
||||||
// mark the TabletProxy object as cpp ownership.
|
// mark the TabletProxy object as cpp ownership.
|
||||||
QObject* tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system");
|
QObject* tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system");
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "AnimUtil.h"
|
#include "AnimUtil.h"
|
||||||
#include "IKTarget.h"
|
#include "IKTarget.h"
|
||||||
|
|
||||||
|
|
||||||
static int nextRigId = 1;
|
static int nextRigId = 1;
|
||||||
static std::map<int, Rig*> rigRegistry;
|
static std::map<int, Rig*> rigRegistry;
|
||||||
static std::mutex rigRegistryMutex;
|
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) {
|
void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, const glm::mat4& rigToWorldTransform) {
|
||||||
|
DETAILED_PROFILE_RANGE_EX(simulation_animation_detail, __FUNCTION__, 0xffff00ff, 0);
|
||||||
PROFILE_RANGE_EX(simulation_animation_detail, __FUNCTION__, 0xffff00ff, 0);
|
DETAILED_PERFORMANCE_TIMER("updateAnimations");
|
||||||
PerformanceTimer perfTimer("updateAnimations");
|
|
||||||
|
|
||||||
setModelOffset(rootTransform);
|
setModelOffset(rootTransform);
|
||||||
|
|
||||||
if (_animNode && _enabledAnimations) {
|
if (_animNode && _enabledAnimations) {
|
||||||
PerformanceTimer perfTimer("handleTriggers");
|
DETAILED_PERFORMANCE_TIMER("handleTriggers");
|
||||||
|
|
||||||
updateAnimationStateHandlers();
|
updateAnimationStateHandlers();
|
||||||
_animVars.setRigToGeometryTransform(_rigToGeometryTransform);
|
_animVars.setRigToGeometryTransform(_rigToGeometryTransform);
|
||||||
|
@ -1658,7 +1658,7 @@ bool Rig::getModelRegistrationPoint(glm::vec3& modelRegistrationPointOut) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::applyOverridePoses() {
|
void Rig::applyOverridePoses() {
|
||||||
PerformanceTimer perfTimer("override");
|
DETAILED_PERFORMANCE_TIMER("override");
|
||||||
if (_numOverrides == 0 || !_animSkeleton) {
|
if (_numOverrides == 0 || !_animSkeleton) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1675,7 +1675,7 @@ void Rig::applyOverridePoses() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) {
|
void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) {
|
||||||
PerformanceTimer perfTimer("buildAbsolute");
|
DETAILED_PERFORMANCE_TIMER("buildAbsolute");
|
||||||
if (!_animSkeleton) {
|
if (!_animSkeleton) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1730,8 +1730,9 @@ void Rig::copyJointsIntoJointData(QVector<JointData>& jointDataVec) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
|
void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
|
||||||
PerformanceTimer perfTimer("copyJoints");
|
DETAILED_PROFILE_RANGE(simulation_animation_detail, "copyJoints");
|
||||||
PROFILE_RANGE(simulation_animation_detail, "copyJoints");
|
DETAILED_PERFORMANCE_TIMER("copyJoints");
|
||||||
|
|
||||||
if (!_animSkeleton) {
|
if (!_animSkeleton) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,6 +160,8 @@ void EntityTreeRenderer::shutdown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, render::Transaction& transaction) {
|
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
|
// Clear any expired entities
|
||||||
// FIXME should be able to use std::remove_if, but it fails due to some
|
// FIXME should be able to use std::remove_if, but it fails due to some
|
||||||
// weird compilation error related to EntityItemID assignment operators
|
// 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) {
|
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;
|
std::unordered_set<EntityItemID> changedEntities;
|
||||||
_changedEntitiesGuard.withWriteLock([&] {
|
_changedEntitiesGuard.withWriteLock([&] {
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -223,6 +227,7 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_renderablesToUpdate.empty()) {
|
if (!_renderablesToUpdate.empty()) {
|
||||||
|
PROFILE_RANGE_EX(simulation_physics, "UpdateRenderables", 0xffff00ff, (uint64_t)_renderablesToUpdate.size());
|
||||||
for (const auto& entry : _renderablesToUpdate) {
|
for (const auto& entry : _renderablesToUpdate) {
|
||||||
const auto& renderable = entry.second;
|
const auto& renderable = entry.second;
|
||||||
renderable->updateInScene(scene, transaction);
|
renderable->updateInScene(scene, transaction);
|
||||||
|
@ -232,6 +237,7 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::update(bool simulate) {
|
void EntityTreeRenderer::update(bool simulate) {
|
||||||
|
PROFILE_RANGE(simulation_physics, "ETR::update");
|
||||||
PerformanceTimer perfTimer("ETRupdate");
|
PerformanceTimer perfTimer("ETRupdate");
|
||||||
if (_tree && !_shuttingDown) {
|
if (_tree && !_shuttingDown) {
|
||||||
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
||||||
|
@ -239,22 +245,14 @@ void EntityTreeRenderer::update(bool simulate) {
|
||||||
|
|
||||||
// Update the rendereable entities as needed
|
// Update the rendereable entities as needed
|
||||||
{
|
{
|
||||||
|
PROFILE_RANGE(simulation_physics, "Scene");
|
||||||
PerformanceTimer sceneTimer("scene");
|
PerformanceTimer sceneTimer("scene");
|
||||||
auto scene = _viewState->getMain3DScene();
|
auto scene = _viewState->getMain3DScene();
|
||||||
if (scene) {
|
if (scene) {
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
{
|
addPendingEntities(scene, transaction);
|
||||||
PerformanceTimer pt("add");
|
updateChangedEntities(scene, transaction);
|
||||||
addPendingEntities(scene, transaction);
|
scene->enqueueTransaction(transaction);
|
||||||
}
|
|
||||||
{
|
|
||||||
PerformanceTimer pt("change");
|
|
||||||
updateChangedEntities(scene, transaction);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
PerformanceTimer pt("enqueue");
|
|
||||||
scene->enqueueTransaction(transaction);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +334,8 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityIt
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTreeRenderer::checkEnterLeaveEntities() {
|
bool EntityTreeRenderer::checkEnterLeaveEntities() {
|
||||||
PerformanceTimer perfTimer("checkEnterLeaveEntities");
|
PROFILE_RANGE(simulation_physics, "EnterLeave");
|
||||||
|
PerformanceTimer perfTimer("enterLeave");
|
||||||
auto now = usecTimestampNow();
|
auto now = usecTimestampNow();
|
||||||
bool didUpdate = false;
|
bool didUpdate = false;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "RenderableWebEntityItem.h"
|
#include "RenderableWebEntityItem.h"
|
||||||
#include "RenderableZoneEntityItem.h"
|
#include "RenderableZoneEntityItem.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
using namespace render::entities;
|
using namespace render::entities;
|
||||||
|
|
||||||
|
@ -271,6 +272,7 @@ void EntityRenderer::removeFromScene(const ScenePointer& scene, Transaction& tra
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityRenderer::updateInScene(const ScenePointer& scene, Transaction& transaction) {
|
void EntityRenderer::updateInScene(const ScenePointer& scene, Transaction& transaction) {
|
||||||
|
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
|
||||||
if (!isValidRenderItem()) {
|
if (!isValidRenderItem()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -330,6 +332,7 @@ bool EntityRenderer::needsRenderUpdateFromEntity(const EntityItemPointer& entity
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) {
|
void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) {
|
||||||
|
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
auto transparent = isTransparent();
|
auto transparent = isTransparent();
|
||||||
if (_prevIsTransparent && !transparent) {
|
if (_prevIsTransparent && !transparent) {
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "EntityTreeRenderer.h"
|
#include "EntityTreeRenderer.h"
|
||||||
#include "EntitiesRendererLogging.h"
|
#include "EntitiesRendererLogging.h"
|
||||||
|
|
||||||
|
|
||||||
static CollisionRenderMeshCache collisionMeshCache;
|
static CollisionRenderMeshCache collisionMeshCache;
|
||||||
|
|
||||||
void ModelEntityWrapper::setModel(const ModelPointer& model) {
|
void ModelEntityWrapper::setModel(const ModelPointer& model) {
|
||||||
|
@ -107,6 +108,7 @@ QVariantMap parseTexturesToMap(QString textures, const QVariantMap& defaultTextu
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableModelEntityItem::doInitialModelSimulation() {
|
void RenderableModelEntityItem::doInitialModelSimulation() {
|
||||||
|
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
|
||||||
ModelPointer model = getModel();
|
ModelPointer model = getModel();
|
||||||
if (!model) {
|
if (!model) {
|
||||||
return;
|
return;
|
||||||
|
@ -123,11 +125,11 @@ void RenderableModelEntityItem::doInitialModelSimulation() {
|
||||||
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
|
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
|
||||||
model->setRotation(getRotation());
|
model->setRotation(getRotation());
|
||||||
model->setTranslation(getPosition());
|
model->setTranslation(getPosition());
|
||||||
{
|
|
||||||
PerformanceTimer perfTimer("model->simulate");
|
if (_needsInitialSimulation) {
|
||||||
model->simulate(0.0f);
|
model->simulate(0.0f);
|
||||||
|
_needsInitialSimulation = false;
|
||||||
}
|
}
|
||||||
_needsInitialSimulation = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableModelEntityItem::autoResizeJointArrays() {
|
void RenderableModelEntityItem::autoResizeJointArrays() {
|
||||||
|
@ -138,6 +140,7 @@ void RenderableModelEntityItem::autoResizeJointArrays() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderableModelEntityItem::needsUpdateModelBounds() const {
|
bool RenderableModelEntityItem::needsUpdateModelBounds() const {
|
||||||
|
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
|
||||||
ModelPointer model = getModel();
|
ModelPointer model = getModel();
|
||||||
if (!hasModel() || !model) {
|
if (!hasModel() || !model) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -151,7 +154,7 @@ bool RenderableModelEntityItem::needsUpdateModelBounds() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMovingRelativeToParent() || isAnimatingSomething()) {
|
if (isAnimatingSomething()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,13 +181,61 @@ bool RenderableModelEntityItem::needsUpdateModelBounds() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return model->needsReload();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableModelEntityItem::updateModelBounds() {
|
void RenderableModelEntityItem::updateModelBounds() {
|
||||||
if (needsUpdateModelBounds()) {
|
DETAILED_PROFILE_RANGE(simulation_physics, "updateModelBounds");
|
||||||
doInitialModelSimulation();
|
|
||||||
|
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;
|
_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.
|
// we have both URLs AND both geometries AND they are both fully loaded.
|
||||||
if (_needsInitialSimulation) {
|
if (_needsInitialSimulation) {
|
||||||
// the _model's offset will be wrong until _needsInitialSimulation is false
|
// 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();
|
const_cast<RenderableModelEntityItem*>(this)->doInitialModelSimulation();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -839,7 +890,7 @@ void RenderableModelEntityItem::setJointTranslationsSet(const QVector<bool>& tra
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableModelEntityItem::locationChanged(bool tellPhysics) {
|
void RenderableModelEntityItem::locationChanged(bool tellPhysics) {
|
||||||
PerformanceTimer pertTimer("locationChanged");
|
DETAILED_PERFORMANCE_TIMER("locationChanged");
|
||||||
EntityItem::locationChanged(tellPhysics);
|
EntityItem::locationChanged(tellPhysics);
|
||||||
auto model = getModel();
|
auto model = getModel();
|
||||||
if (model && model->isLoaded()) {
|
if (model && model->isLoaded()) {
|
||||||
|
@ -880,7 +931,6 @@ void RenderableModelEntityItem::copyAnimationJointDataToModel() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// relay any inbound joint changes from scripts/animation/network to the model/rig
|
// relay any inbound joint changes from scripts/animation/network to the model/rig
|
||||||
_jointDataLock.withWriteLock([&] {
|
_jointDataLock.withWriteLock([&] {
|
||||||
for (int index = 0; index < _localJointData.size(); ++index) {
|
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;
|
||||||
using namespace render::entities;
|
using namespace render::entities;
|
||||||
|
|
||||||
ItemKey ModelEntityRenderer::getKey() {
|
ItemKey ModelEntityRenderer::getKey() {
|
||||||
return ItemKey::Builder().withTypeMeta();
|
return ItemKey::Builder().withTypeMeta().withTypeShape();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ModelEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) {
|
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) {
|
void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
|
||||||
|
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
|
||||||
if (_hasModel != entity->hasModel()) {
|
if (_hasModel != entity->hasModel()) {
|
||||||
_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) {
|
if (model->isVisible() != _visible) {
|
||||||
// FIXME: this seems like it could be optimized if we tracked our last known visible state in
|
// 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.
|
// so most of the time we don't do anything in this function.
|
||||||
model->setVisibleInScene(_visible, scene);
|
model->setVisibleInScene(_visible, scene);
|
||||||
}
|
}
|
||||||
|
// TODO? early exit here when not visible?
|
||||||
|
|
||||||
//entity->doInitialModelSimulation();
|
{
|
||||||
if (model->needsFixupInScene()) {
|
DETAILED_PROFILE_RANGE(simulation_physics, "Fixup");
|
||||||
model->removeFromScene(scene, transaction);
|
if (model->needsFixupInScene()) {
|
||||||
render::Item::Status::Getters statusGetters;
|
model->removeFromScene(scene, transaction);
|
||||||
makeStatusGetters(entity, statusGetters);
|
render::Item::Status::Getters statusGetters;
|
||||||
model->addToScene(scene, transaction, 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
|
// 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();
|
model->updateRenderItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a copy of the animation properites
|
{
|
||||||
auto newAnimationProperties = entity->getAnimationProperties();
|
DETAILED_PROFILE_RANGE(simulation_physics, "CheckAnimation");
|
||||||
if (newAnimationProperties != _renderAnimationProperties) {
|
// make a copy of the animation properites
|
||||||
withWriteLock([&] {
|
auto newAnimationProperties = entity->getAnimationProperties();
|
||||||
_renderAnimationProperties = newAnimationProperties;
|
if (newAnimationProperties != _renderAnimationProperties) {
|
||||||
_currentFrame = _renderAnimationProperties.getCurrentFrame();
|
withWriteLock([&] {
|
||||||
});
|
_renderAnimationProperties = newAnimationProperties;
|
||||||
|
_currentFrame = _renderAnimationProperties.getCurrentFrame();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_animating) {
|
if (_animating) {
|
||||||
|
DETAILED_PROFILE_RANGE(simulation_physics, "Animate");
|
||||||
if (!jointsMapped()) {
|
if (!jointsMapped()) {
|
||||||
mapJoints(entity, model->getJointNames());
|
mapJoints(entity, model->getJointNames());
|
||||||
}
|
}
|
||||||
|
@ -1247,15 +1299,16 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
|
|
||||||
// NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items
|
// NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items
|
||||||
void ModelEntityRenderer::doRender(RenderArgs* args) {
|
void ModelEntityRenderer::doRender(RenderArgs* args) {
|
||||||
PROFILE_RANGE(render_detail, "MetaModelRender");
|
DETAILED_PROFILE_RANGE(render_detail, "MetaModelRender");
|
||||||
PerformanceTimer perfTimer("RMEIrender");
|
DETAILED_PERFORMANCE_TIMER("RMEIrender");
|
||||||
|
|
||||||
ModelPointer model;
|
ModelPointer model;
|
||||||
withReadLock([&]{
|
withReadLock([&]{
|
||||||
model = _model;
|
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);
|
static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
batch.setModelTransform(_modelTransform); // we want to include the scale as well
|
batch.setModelTransform(_modelTransform); // we want to include the scale as well
|
||||||
|
|
|
@ -108,7 +108,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool needsUpdateModelBounds() const;
|
bool needsUpdateModelBounds() const;
|
||||||
bool isAnimatingSomething() const;
|
|
||||||
void autoResizeJointArrays();
|
void autoResizeJointArrays();
|
||||||
void copyAnimationJointDataToModel();
|
void copyAnimationJointDataToModel();
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
|
|
||||||
class EntitiesScriptEngineProvider {
|
class EntitiesScriptEngineProvider {
|
||||||
public:
|
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;
|
virtual QFuture<QVariant> getLocalEntityScriptDetails(const EntityItemID& entityID) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -228,11 +228,21 @@ const std::array<ComponentPair, COMPONENT_MODE_ITEM_COUNT> COMPONENT_MODES = { {
|
||||||
} };
|
} };
|
||||||
|
|
||||||
QString EntityItemProperties::getHazeModeAsString() const {
|
QString EntityItemProperties::getHazeModeAsString() const {
|
||||||
return COMPONENT_MODES[_hazeMode].second;
|
// 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) {
|
QString EntityItemProperties::getHazeModeString(uint32_t mode) {
|
||||||
return COMPONENT_MODES[mode].second;
|
// 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) {
|
void EntityItemProperties::setHazeModeFromString(const QString& hazeMode) {
|
||||||
|
|
|
@ -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 {
|
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
||||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
|
||||||
|
|
|
@ -188,11 +188,11 @@ public slots:
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
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
|
/**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
|
* and it exposes a property with the specified name `method`, it will be called
|
||||||
* using `params` as the list of arguments.
|
* 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());
|
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
|
/**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;
|
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
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AACube.h>
|
|
||||||
|
|
||||||
#include "EntitySimulation.h"
|
#include "EntitySimulation.h"
|
||||||
|
|
||||||
|
#include <AACube.h>
|
||||||
|
#include <Profile.h>
|
||||||
|
|
||||||
#include "EntitiesLogging.h"
|
#include "EntitiesLogging.h"
|
||||||
#include "MovingEntitiesOperator.h"
|
#include "MovingEntitiesOperator.h"
|
||||||
|
|
||||||
|
@ -27,6 +29,7 @@ void EntitySimulation::setEntityTree(EntityTreePointer tree) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntitySimulation::updateEntities() {
|
void EntitySimulation::updateEntities() {
|
||||||
|
PROFILE_RANGE(simulation_physics, "ES::updateEntities");
|
||||||
QMutexLocker lock(&_mutex);
|
QMutexLocker lock(&_mutex);
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
|
|
||||||
|
@ -35,8 +38,12 @@ void EntitySimulation::updateEntities() {
|
||||||
callUpdateOnEntitiesThatNeedIt(now);
|
callUpdateOnEntitiesThatNeedIt(now);
|
||||||
moveSimpleKinematics(now);
|
moveSimpleKinematics(now);
|
||||||
updateEntitiesInternal(now);
|
updateEntitiesInternal(now);
|
||||||
PerformanceTimer perfTimer("sortingEntities");
|
|
||||||
sortEntitiesThatMoved();
|
{
|
||||||
|
PROFILE_RANGE(simulation_physics, "Sort");
|
||||||
|
PerformanceTimer perfTimer("sortingEntities");
|
||||||
|
sortEntitiesThatMoved();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntitySimulation::takeEntitiesToDelete(VectorOfEntities& entitiesToDelete) {
|
void EntitySimulation::takeEntitiesToDelete(VectorOfEntities& entitiesToDelete) {
|
||||||
|
@ -258,6 +265,7 @@ void EntitySimulation::clearEntities() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntitySimulation::moveSimpleKinematics(const quint64& now) {
|
void EntitySimulation::moveSimpleKinematics(const quint64& now) {
|
||||||
|
PROFILE_RANGE_EX(simulation_physics, "Kinematics", 0xffff00ff, (uint64_t)_simpleKinematicEntities.size());
|
||||||
SetOfEntities::iterator itemItr = _simpleKinematicEntities.begin();
|
SetOfEntities::iterator itemItr = _simpleKinematicEntities.begin();
|
||||||
while (itemItr != _simpleKinematicEntities.end()) {
|
while (itemItr != _simpleKinematicEntities.end()) {
|
||||||
EntityItemPointer entity = *itemItr;
|
EntityItemPointer entity = *itemItr;
|
||||||
|
|
|
@ -25,8 +25,9 @@
|
||||||
|
|
||||||
#include <QtScript/QScriptEngine>
|
#include <QtScript/QScriptEngine>
|
||||||
|
|
||||||
#include <PerfStat.h>
|
|
||||||
#include <Extents.h>
|
#include <Extents.h>
|
||||||
|
#include <PerfStat.h>
|
||||||
|
#include <Profile.h>
|
||||||
|
|
||||||
#include "EntitySimulation.h"
|
#include "EntitySimulation.h"
|
||||||
#include "VariantMapToScriptValue.h"
|
#include "VariantMapToScriptValue.h"
|
||||||
|
@ -1628,6 +1629,7 @@ void EntityTree::entityChanged(EntityItemPointer entity) {
|
||||||
|
|
||||||
|
|
||||||
void EntityTree::fixupNeedsParentFixups() {
|
void EntityTree::fixupNeedsParentFixups() {
|
||||||
|
PROFILE_RANGE(simulation_physics, "FixupParents");
|
||||||
MovingEntitiesOperator moveOperator;
|
MovingEntitiesOperator moveOperator;
|
||||||
|
|
||||||
QWriteLocker locker(&_needsParentFixupLock);
|
QWriteLocker locker(&_needsParentFixupLock);
|
||||||
|
@ -1717,6 +1719,7 @@ void EntityTree::addToNeedsParentFixupList(EntityItemPointer entity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTree::update(bool simulate) {
|
void EntityTree::update(bool simulate) {
|
||||||
|
PROFILE_RANGE(simulation_physics, "ET::update");
|
||||||
fixupNeedsParentFixups();
|
fixupNeedsParentFixups();
|
||||||
if (simulate && _simulation) {
|
if (simulate && _simulation) {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
|
|
|
@ -557,12 +557,6 @@ void ModelEntityItem::setAnimationLoop(bool loop) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModelEntityItem::getAnimationLoop() const {
|
|
||||||
return resultWithReadLock<bool>([&] {
|
|
||||||
return _animationProperties.getLoop();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelEntityItem::setAnimationHold(bool hold) {
|
void ModelEntityItem::setAnimationHold(bool hold) {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_animationProperties.setHold(hold);
|
_animationProperties.setHold(hold);
|
||||||
|
@ -610,8 +604,10 @@ float ModelEntityItem::getAnimationCurrentFrame() const {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
float ModelEntityItem::getAnimationFPS() const {
|
bool ModelEntityItem::isAnimatingSomething() const {
|
||||||
return resultWithReadLock<float>([&] {
|
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(); };
|
bool getAnimationAllowTranslation() const { return _animationProperties.getAllowTranslation(); };
|
||||||
|
|
||||||
void setAnimationLoop(bool loop);
|
void setAnimationLoop(bool loop);
|
||||||
bool getAnimationLoop() const;
|
|
||||||
|
|
||||||
void setAnimationHold(bool hold);
|
void setAnimationHold(bool hold);
|
||||||
bool getAnimationHold() const;
|
bool getAnimationHold() const;
|
||||||
|
@ -101,10 +100,9 @@ public:
|
||||||
void setAnimationLastFrame(float lastFrame);
|
void setAnimationLastFrame(float lastFrame);
|
||||||
float getAnimationLastFrame() const;
|
float getAnimationLastFrame() const;
|
||||||
|
|
||||||
|
|
||||||
bool getAnimationIsPlaying() const;
|
bool getAnimationIsPlaying() const;
|
||||||
float getAnimationCurrentFrame() const;
|
float getAnimationCurrentFrame() const;
|
||||||
float getAnimationFPS() const;
|
bool isAnimatingSomething() const;
|
||||||
|
|
||||||
static const QString DEFAULT_TEXTURES;
|
static const QString DEFAULT_TEXTURES;
|
||||||
const QString getTextures() const;
|
const QString getTextures() const;
|
||||||
|
@ -123,7 +121,6 @@ public:
|
||||||
QVector<bool> getJointRotationsSet() const;
|
QVector<bool> getJointRotationsSet() const;
|
||||||
QVector<glm::vec3> getJointTranslations() const;
|
QVector<glm::vec3> getJointTranslations() const;
|
||||||
QVector<bool> getJointTranslationsSet() const;
|
QVector<bool> getJointTranslationsSet() const;
|
||||||
bool isAnimatingSomething() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setAnimationSettings(const QString& value); // only called for old bitstream format
|
void setAnimationSettings(const QString& value); // only called for old bitstream format
|
||||||
|
|
|
@ -321,8 +321,10 @@ void ZoneEntityItem::resetRenderingPropertiesChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneEntityItem::setHazeMode(const uint32_t value) {
|
void ZoneEntityItem::setHazeMode(const uint32_t value) {
|
||||||
_hazeMode = value;
|
if (value < COMPONENT_MODE_ITEM_COUNT) {
|
||||||
_hazePropertiesChanged = true;
|
_hazeMode = value;
|
||||||
|
_hazePropertiesChanged = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ZoneEntityItem::getHazeMode() const {
|
uint32_t ZoneEntityItem::getHazeMode() const {
|
||||||
|
|
|
@ -138,6 +138,8 @@ public:
|
||||||
static const bool DEFAULT_GHOSTING_ALLOWED;
|
static const bool DEFAULT_GHOSTING_ALLOWED;
|
||||||
static const QString DEFAULT_FILTER_URL;
|
static const QString DEFAULT_FILTER_URL;
|
||||||
|
|
||||||
|
static const uint32_t DEFAULT_HAZE_MODE{ (uint32_t)COMPONENT_MODE_INHERIT };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
KeyLightPropertyGroup _keyLightProperties;
|
KeyLightPropertyGroup _keyLightProperties;
|
||||||
|
|
||||||
|
@ -146,7 +148,7 @@ protected:
|
||||||
|
|
||||||
BackgroundMode _backgroundMode = BACKGROUND_MODE_INHERIT;
|
BackgroundMode _backgroundMode = BACKGROUND_MODE_INHERIT;
|
||||||
|
|
||||||
uint8_t _hazeMode{ (uint8_t)COMPONENT_MODE_INHERIT };
|
uint32_t _hazeMode{ DEFAULT_HAZE_MODE };
|
||||||
|
|
||||||
float _hazeRange{ HazePropertyGroup::DEFAULT_HAZE_RANGE };
|
float _hazeRange{ HazePropertyGroup::DEFAULT_HAZE_RANGE };
|
||||||
xColor _hazeColor{ HazePropertyGroup::DEFAULT_HAZE_COLOR };
|
xColor _hazeColor{ HazePropertyGroup::DEFAULT_HAZE_COLOR };
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <glm/gtx/transform.hpp>
|
#include <glm/gtx/transform.hpp>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <qcompilerdetection.h>
|
#include <qcompilerdetection.h>
|
||||||
|
#include <ComponentMode.h>
|
||||||
|
|
||||||
using namespace model;
|
using namespace model;
|
||||||
|
|
||||||
|
@ -256,8 +257,9 @@ void SunSkyStage::setSkybox(const SkyboxPointer& skybox) {
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Haze
|
void SunSkyStage::setHazeMode(uint32_t hazeMode) {
|
||||||
void SunSkyStage::setHazeMode(uint32_t mode) {
|
if (hazeMode < COMPONENT_MODE_ITEM_COUNT) {
|
||||||
_hazeMode = mode;
|
_hazeMode = hazeMode;
|
||||||
invalidate();
|
invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,30 @@ bool EntityScriptClient::reloadServerScript(QUuid entityID) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityScriptClient::callEntityServerMethod(QUuid entityID, const QString& method, const QStringList& params) {
|
||||||
|
// Send packet to entity script server
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);
|
||||||
|
|
||||||
|
if (entityScriptServer) {
|
||||||
|
auto packetList = NLPacketList::create(PacketType::EntityScriptCallMethod, QByteArray(), true, true);
|
||||||
|
|
||||||
|
packetList->write(entityID.toRfc4122());
|
||||||
|
|
||||||
|
packetList->writeString(method);
|
||||||
|
|
||||||
|
quint16 paramCount = params.length();
|
||||||
|
packetList->writePrimitive(paramCount);
|
||||||
|
|
||||||
|
foreach(const QString& param, params) {
|
||||||
|
packetList->writeString(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeList->sendPacketList(std::move(packetList), *entityScriptServer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MessageID EntityScriptClient::getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback) {
|
MessageID EntityScriptClient::getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback) {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);
|
SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);
|
||||||
|
|
|
@ -58,6 +58,8 @@ public:
|
||||||
|
|
||||||
bool reloadServerScript(QUuid entityID);
|
bool reloadServerScript(QUuid entityID);
|
||||||
MessageID getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback);
|
MessageID getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback);
|
||||||
|
void callEntityServerMethod(QUuid id, const QString& method, const QStringList& params);
|
||||||
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleNodeKilled(SharedNodePointer node);
|
void handleNodeKilled(SharedNodePointer node);
|
||||||
|
|
|
@ -123,6 +123,7 @@ public:
|
||||||
ReplicatedBulkAvatarData,
|
ReplicatedBulkAvatarData,
|
||||||
OctreeFileReplacementFromUrl,
|
OctreeFileReplacementFromUrl,
|
||||||
ChallengeOwnership,
|
ChallengeOwnership,
|
||||||
|
EntityScriptCallMethod,
|
||||||
NUM_PACKET_TYPE
|
NUM_PACKET_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
5
libraries/pointers/CMakeLists.txt
Normal file
5
libraries/pointers/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
set(TARGET_NAME pointers)
|
||||||
|
setup_hifi_library()
|
||||||
|
GroupSources(src)
|
||||||
|
link_hifi_libraries(shared)
|
||||||
|
|
6
libraries/pointers/src/pointers/PointerManager.cpp
Normal file
6
libraries/pointers/src/pointers/PointerManager.cpp
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include "PointerManager.h"
|
||||||
|
|
||||||
|
PointerManager::PointerManager() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
30
libraries/pointers/src/pointers/PointerManager.h
Normal file
30
libraries/pointers/src/pointers/PointerManager.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2017/10/16
|
||||||
|
// Copyright 2013-2017 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_pointers_PointerManager_h
|
||||||
|
#define hifi_pointers_PointerManager_h
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
#include <PointerEvent.h>
|
||||||
|
|
||||||
|
class PointerManager : public QObject, public Dependency {
|
||||||
|
Q_OBJECT
|
||||||
|
SINGLETON_DEPENDENCY
|
||||||
|
public:
|
||||||
|
PointerManager();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void triggerBegin(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
void triggerContinue(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
void triggerEnd(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
|
||||||
|
void hoverEnter(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
void hoverOver(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
void hoverLeave(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_pointers_PointerManager_h
|
81
libraries/pointers/src/pointers/rays/RayPick.cpp
Normal file
81
libraries/pointers/src/pointers/rays/RayPick.cpp
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
//
|
||||||
|
// Created by Sam Gondelman 7/11/2017
|
||||||
|
// Copyright 2017 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 "RayPick.h"
|
||||||
|
|
||||||
|
const RayPickFilter RayPickFilter::NOTHING;
|
||||||
|
|
||||||
|
RayPick::RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) :
|
||||||
|
_filter(filter),
|
||||||
|
_maxDistance(maxDistance),
|
||||||
|
_enabled(enabled)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RayPick::enable(bool enabled) {
|
||||||
|
withWriteLock([&] {
|
||||||
|
_enabled = enabled;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RayPickFilter RayPick::getFilter() const {
|
||||||
|
return resultWithReadLock<RayPickFilter>([&] {
|
||||||
|
return _filter;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
float RayPick::getMaxDistance() const {
|
||||||
|
return _maxDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RayPick::isEnabled() const {
|
||||||
|
return resultWithReadLock<bool>([&] {
|
||||||
|
return _enabled;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RayPick::setPrecisionPicking(bool precisionPicking) {
|
||||||
|
withWriteLock([&]{
|
||||||
|
_filter.setFlag(RayPickFilter::PICK_COARSE, !precisionPicking);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RayPick::setRayPickResult(const RayPickResult& rayPickResult) {
|
||||||
|
withWriteLock([&] {
|
||||||
|
_prevResult = rayPickResult;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QUuid> RayPick::getIgnoreItems() const {
|
||||||
|
return resultWithReadLock<QVector<QUuid>>([&] {
|
||||||
|
return _ignoreItems;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QUuid> RayPick::getIncludeItems() const {
|
||||||
|
return resultWithReadLock<QVector<QUuid>>([&] {
|
||||||
|
return _includeItems;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RayPickResult RayPick::getPrevRayPickResult() const {
|
||||||
|
return resultWithReadLock<RayPickResult>([&] {
|
||||||
|
return _prevResult;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RayPick::setIgnoreItems(const QVector<QUuid>& ignoreItems) {
|
||||||
|
withWriteLock([&] {
|
||||||
|
_ignoreItems = ignoreItems;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RayPick::setIncludeItems(const QVector<QUuid>& includeItems) {
|
||||||
|
withWriteLock([&] {
|
||||||
|
_includeItems = includeItems;
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,7 +1,4 @@
|
||||||
//
|
//
|
||||||
// RayPick.h
|
|
||||||
// interface/src/raypick
|
|
||||||
//
|
|
||||||
// Created by Sam Gondelman 7/11/2017
|
// Created by Sam Gondelman 7/11/2017
|
||||||
// Copyright 2017 High Fidelity, Inc.
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
|
@ -12,22 +9,22 @@
|
||||||
#define hifi_RayPick_h
|
#define hifi_RayPick_h
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "RegisteredMetaTypes.h"
|
#include <bitset>
|
||||||
|
|
||||||
#include "EntityItemID.h"
|
#include <QtCore/QUuid>
|
||||||
#include "ui/overlays/Overlay.h"
|
|
||||||
#include <QReadWriteLock>
|
#include <RegisteredMetaTypes.h>
|
||||||
|
#include <shared/ReadWriteLockable.h>
|
||||||
|
|
||||||
class RayPickFilter {
|
class RayPickFilter {
|
||||||
public:
|
public:
|
||||||
enum FlagBit {
|
enum FlagBit {
|
||||||
PICK_NOTHING = 0,
|
PICK_ENTITIES = 0,
|
||||||
PICK_ENTITIES,
|
|
||||||
PICK_OVERLAYS,
|
PICK_OVERLAYS,
|
||||||
PICK_AVATARS,
|
PICK_AVATARS,
|
||||||
PICK_HUD,
|
PICK_HUD,
|
||||||
|
|
||||||
PICK_COURSE, // if not set, does precise intersection, otherwise, doesn't
|
PICK_COARSE, // if not set, does precise intersection, otherwise, doesn't
|
||||||
|
|
||||||
PICK_INCLUDE_INVISIBLE, // if not set, will not intersect invisible elements, otherwise, intersects both visible and invisible elements
|
PICK_INCLUDE_INVISIBLE, // if not set, will not intersect invisible elements, otherwise, intersects both visible and invisible elements
|
||||||
PICK_INCLUDE_NONCOLLIDABLE, // if not set, will not intersect noncollidable elements, otherwise, intersects both collidable and noncollidable elements
|
PICK_INCLUDE_NONCOLLIDABLE, // if not set, will not intersect noncollidable elements, otherwise, intersects both collidable and noncollidable elements
|
||||||
|
@ -42,7 +39,7 @@ public:
|
||||||
// The key is the Flags
|
// The key is the Flags
|
||||||
Flags _flags;
|
Flags _flags;
|
||||||
|
|
||||||
RayPickFilter() : _flags(getBitMask(PICK_NOTHING)) {}
|
RayPickFilter() {}
|
||||||
RayPickFilter(const Flags& flags) : _flags(flags) {}
|
RayPickFilter(const Flags& flags) : _flags(flags) {}
|
||||||
|
|
||||||
bool operator== (const RayPickFilter& rhs) const { return _flags == rhs._flags; }
|
bool operator== (const RayPickFilter& rhs) const { return _flags == rhs._flags; }
|
||||||
|
@ -50,13 +47,13 @@ public:
|
||||||
|
|
||||||
void setFlag(FlagBit flag, bool value) { _flags[flag] = value; }
|
void setFlag(FlagBit flag, bool value) { _flags[flag] = value; }
|
||||||
|
|
||||||
bool doesPickNothing() const { return _flags[PICK_NOTHING]; }
|
bool doesPickNothing() const { return _flags == NOTHING._flags; }
|
||||||
bool doesPickEntities() const { return _flags[PICK_ENTITIES]; }
|
bool doesPickEntities() const { return _flags[PICK_ENTITIES]; }
|
||||||
bool doesPickOverlays() const { return _flags[PICK_OVERLAYS]; }
|
bool doesPickOverlays() const { return _flags[PICK_OVERLAYS]; }
|
||||||
bool doesPickAvatars() const { return _flags[PICK_AVATARS]; }
|
bool doesPickAvatars() const { return _flags[PICK_AVATARS]; }
|
||||||
bool doesPickHUD() const { return _flags[PICK_HUD]; }
|
bool doesPickHUD() const { return _flags[PICK_HUD]; }
|
||||||
|
|
||||||
bool doesPickCourse() const { return _flags[PICK_COURSE]; }
|
bool doesPickCoarse() const { return _flags[PICK_COARSE]; }
|
||||||
bool doesPickInvisible() const { return _flags[PICK_INCLUDE_INVISIBLE]; }
|
bool doesPickInvisible() const { return _flags[PICK_INCLUDE_INVISIBLE]; }
|
||||||
bool doesPickNonCollidable() const { return _flags[PICK_INCLUDE_NONCOLLIDABLE]; }
|
bool doesPickNonCollidable() const { return _flags[PICK_INCLUDE_NONCOLLIDABLE]; }
|
||||||
|
|
||||||
|
@ -71,8 +68,8 @@ public:
|
||||||
if (doesPickNonCollidable()) {
|
if (doesPickNonCollidable()) {
|
||||||
toReturn |= getBitMask(PICK_INCLUDE_NONCOLLIDABLE);
|
toReturn |= getBitMask(PICK_INCLUDE_NONCOLLIDABLE);
|
||||||
}
|
}
|
||||||
if (doesPickCourse()) {
|
if (doesPickCoarse()) {
|
||||||
toReturn |= getBitMask(PICK_COURSE);
|
toReturn |= getBitMask(PICK_COARSE);
|
||||||
}
|
}
|
||||||
return Flags(toReturn);
|
return Flags(toReturn);
|
||||||
}
|
}
|
||||||
|
@ -84,66 +81,76 @@ public:
|
||||||
if (doesPickNonCollidable()) {
|
if (doesPickNonCollidable()) {
|
||||||
toReturn |= getBitMask(PICK_INCLUDE_NONCOLLIDABLE);
|
toReturn |= getBitMask(PICK_INCLUDE_NONCOLLIDABLE);
|
||||||
}
|
}
|
||||||
if (doesPickCourse()) {
|
if (doesPickCoarse()) {
|
||||||
toReturn |= getBitMask(PICK_COURSE);
|
toReturn |= getBitMask(PICK_COARSE);
|
||||||
}
|
}
|
||||||
return Flags(toReturn);
|
return Flags(toReturn);
|
||||||
}
|
}
|
||||||
Flags getAvatarFlags() const { return Flags(getBitMask(PICK_AVATARS)); }
|
Flags getAvatarFlags() const { return Flags(getBitMask(PICK_AVATARS)); }
|
||||||
Flags getHUDFlags() const { return Flags(getBitMask(PICK_HUD)); }
|
Flags getHUDFlags() const { return Flags(getBitMask(PICK_HUD)); }
|
||||||
|
|
||||||
static unsigned int getBitMask(FlagBit bit) { return 1 << bit; }
|
static constexpr unsigned int getBitMask(FlagBit bit) { return 1 << bit; }
|
||||||
|
|
||||||
|
static const RayPickFilter NOTHING;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RayPick {
|
class RayPick : protected ReadWriteLockable {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using Pointer = std::shared_ptr<RayPick>;
|
||||||
|
|
||||||
RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled);
|
RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled);
|
||||||
|
|
||||||
virtual const PickRay getPickRay(bool& valid) const = 0;
|
virtual const PickRay getPickRay(bool& valid) const = 0;
|
||||||
|
|
||||||
void enable();
|
void enable(bool enabled = true);
|
||||||
void disable();
|
void disable() { enable(false); }
|
||||||
|
|
||||||
const RayPickFilter& getFilter() { return _filter; }
|
RayPickFilter getFilter() const;
|
||||||
float getMaxDistance() { return _maxDistance; }
|
float getMaxDistance() const;
|
||||||
bool isEnabled() { return _enabled; }
|
bool isEnabled() const;
|
||||||
const RayPickResult& getPrevRayPickResult();
|
RayPickResult getPrevRayPickResult() const;
|
||||||
|
|
||||||
void setPrecisionPicking(bool precisionPicking) { _filter.setFlag(RayPickFilter::PICK_COURSE, !precisionPicking); }
|
void setPrecisionPicking(bool precisionPicking);
|
||||||
|
|
||||||
void setRayPickResult(const RayPickResult& rayPickResult) { _prevResult = rayPickResult; }
|
void setRayPickResult(const RayPickResult& rayPickResult);
|
||||||
|
|
||||||
const QVector<EntityItemID>& getIgnoreEntites() { return _ignoreEntities; }
|
QVector<QUuid> getIgnoreItems() const;
|
||||||
const QVector<EntityItemID>& getIncludeEntites() { return _includeEntities; }
|
QVector<QUuid> getIncludeItems() const;
|
||||||
const QVector<OverlayID>& getIgnoreOverlays() { return _ignoreOverlays; }
|
|
||||||
const QVector<OverlayID>& getIncludeOverlays() { return _includeOverlays; }
|
|
||||||
const QVector<EntityItemID>& getIgnoreAvatars() { return _ignoreAvatars; }
|
|
||||||
const QVector<EntityItemID>& getIncludeAvatars() { return _includeAvatars; }
|
|
||||||
void setIgnoreEntities(const QScriptValue& ignoreEntities);
|
|
||||||
void setIncludeEntities(const QScriptValue& includeEntities);
|
|
||||||
void setIgnoreOverlays(const QScriptValue& ignoreOverlays);
|
|
||||||
void setIncludeOverlays(const QScriptValue& includeOverlays);
|
|
||||||
void setIgnoreAvatars(const QScriptValue& ignoreAvatars);
|
|
||||||
void setIncludeAvatars(const QScriptValue& includeAvatars);
|
|
||||||
|
|
||||||
QReadWriteLock* getLock() { return &_lock; }
|
template <typename T>
|
||||||
|
QVector<T> getIgnoreItemsAs() const {
|
||||||
|
QVector<T> result;
|
||||||
|
withReadLock([&] {
|
||||||
|
for (const auto& uid : _ignoreItems) {
|
||||||
|
result.push_back(uid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
QVector<T> getIncludeItemsAs() const {
|
||||||
|
QVector<T> result;
|
||||||
|
withReadLock([&] {
|
||||||
|
for (const auto& uid : _includeItems) {
|
||||||
|
result.push_back(uid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIgnoreItems(const QVector<QUuid>& items);
|
||||||
|
void setIncludeItems(const QVector<QUuid>& items);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RayPickFilter _filter;
|
RayPickFilter _filter;
|
||||||
float _maxDistance;
|
const float _maxDistance;
|
||||||
bool _enabled;
|
bool _enabled;
|
||||||
RayPickResult _prevResult;
|
RayPickResult _prevResult;
|
||||||
|
|
||||||
QVector<EntityItemID> _ignoreEntities;
|
QVector<QUuid> _ignoreItems;
|
||||||
QVector<EntityItemID> _includeEntities;
|
QVector<QUuid> _includeItems;
|
||||||
QVector<OverlayID> _ignoreOverlays;
|
|
||||||
QVector<OverlayID> _includeOverlays;
|
|
||||||
QVector<EntityItemID> _ignoreAvatars;
|
|
||||||
QVector<EntityItemID> _includeAvatars;
|
|
||||||
|
|
||||||
QReadWriteLock _lock;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_RayPick_h
|
#endif // hifi_RayPick_h
|
|
@ -1,7 +1,4 @@
|
||||||
//
|
//
|
||||||
// StaticRayPick.cpp
|
|
||||||
// interface/src/raypick
|
|
||||||
//
|
|
||||||
// Created by Sam Gondelman 7/11/2017
|
// Created by Sam Gondelman 7/11/2017
|
||||||
// Copyright 2017 High Fidelity, Inc.
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
//
|
//
|
|
@ -1,7 +1,4 @@
|
||||||
//
|
//
|
||||||
// StaticRayPick.h
|
|
||||||
// interface/src/raypick
|
|
||||||
//
|
|
||||||
// Created by Sam Gondelman 7/11/2017
|
// Created by Sam Gondelman 7/11/2017
|
||||||
// Copyright 2017 High Fidelity, Inc.
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
//
|
//
|
|
@ -121,8 +121,6 @@ bool Model::needsFixupInScene() const {
|
||||||
return (_needsFixupInScene || !_addedToScene) && !_needsReload && isLoaded();
|
return (_needsFixupInScene || !_addedToScene) && !_needsReload && isLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO?: should we combine translation and rotation into single method to avoid double-work?
|
|
||||||
// (figure out where we call these)
|
|
||||||
void Model::setTranslation(const glm::vec3& translation) {
|
void Model::setTranslation(const glm::vec3& translation) {
|
||||||
_translation = translation;
|
_translation = translation;
|
||||||
updateRenderItems();
|
updateRenderItems();
|
||||||
|
@ -133,6 +131,14 @@ void Model::setRotation(const glm::quat& rotation) {
|
||||||
updateRenderItems();
|
updateRenderItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// temporary HACK: set transform while avoiding implicit calls to updateRenderItems()
|
||||||
|
// TODO: make setRotation() and friends set flag to be used later to decide to updateRenderItems()
|
||||||
|
void Model::setTransformNoUpdateRenderItems(const Transform& transform) {
|
||||||
|
_translation = transform.getTranslation();
|
||||||
|
_rotation = transform.getRotation();
|
||||||
|
// DO NOT call updateRenderItems() here!
|
||||||
|
}
|
||||||
|
|
||||||
Transform Model::getTransform() const {
|
Transform Model::getTransform() const {
|
||||||
if (_spatiallyNestableOverride) {
|
if (_spatiallyNestableOverride) {
|
||||||
bool success;
|
bool success;
|
||||||
|
@ -957,7 +963,7 @@ Blender::Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointe
|
||||||
}
|
}
|
||||||
|
|
||||||
void Blender::run() {
|
void Blender::run() {
|
||||||
PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } });
|
DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } });
|
||||||
QVector<glm::vec3> vertices, normals;
|
QVector<glm::vec3> vertices, normals;
|
||||||
if (_model) {
|
if (_model) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
@ -1078,8 +1084,7 @@ void Model::snapToRegistrationPoint() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::simulate(float deltaTime, bool fullUpdate) {
|
void Model::simulate(float deltaTime, bool fullUpdate) {
|
||||||
PROFILE_RANGE(simulation_detail, __FUNCTION__);
|
DETAILED_PROFILE_RANGE(simulation_detail, __FUNCTION__);
|
||||||
PerformanceTimer perfTimer("Model::simulate");
|
|
||||||
fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit)
|
fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit)
|
||||||
|| (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint);
|
|| (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint);
|
||||||
|
|
||||||
|
@ -1117,7 +1122,7 @@ void Model::computeMeshPartLocalBounds() {
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
void Model::updateClusterMatrices() {
|
void Model::updateClusterMatrices() {
|
||||||
PerformanceTimer perfTimer("Model::updateClusterMatrices");
|
DETAILED_PERFORMANCE_TIMER("Model::updateClusterMatrices");
|
||||||
|
|
||||||
if (!_needsUpdateClusterMatrices || !isLoaded()) {
|
if (!_needsUpdateClusterMatrices || !isLoaded()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -206,6 +206,7 @@ public:
|
||||||
|
|
||||||
void setTranslation(const glm::vec3& translation);
|
void setTranslation(const glm::vec3& translation);
|
||||||
void setRotation(const glm::quat& rotation);
|
void setRotation(const glm::quat& rotation);
|
||||||
|
void setTransformNoUpdateRenderItems(const Transform& transform); // temporary HACK
|
||||||
|
|
||||||
const glm::vec3& getTranslation() const { return _translation; }
|
const glm::vec3& getTranslation() const { return _translation; }
|
||||||
const glm::quat& getRotation() const { return _rotation; }
|
const glm::quat& getRotation() const { return _rotation; }
|
||||||
|
|
|
@ -2476,7 +2476,7 @@ void ScriptEngine::callWithEnvironment(const EntityItemID& entityID, const QUrl&
|
||||||
doWithEnvironment(entityID, sandboxURL, operation);
|
doWithEnvironment(entityID, sandboxURL, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params) {
|
void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params, const QUuid& remoteCallerID) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
#ifdef THREAD_DEBUGGING
|
#ifdef THREAD_DEBUGGING
|
||||||
qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
|
qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
|
||||||
|
@ -2486,7 +2486,8 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
||||||
QMetaObject::invokeMethod(this, "callEntityScriptMethod",
|
QMetaObject::invokeMethod(this, "callEntityScriptMethod",
|
||||||
Q_ARG(const EntityItemID&, entityID),
|
Q_ARG(const EntityItemID&, entityID),
|
||||||
Q_ARG(const QString&, methodName),
|
Q_ARG(const QString&, methodName),
|
||||||
Q_ARG(const QStringList&, params));
|
Q_ARG(const QStringList&, params),
|
||||||
|
Q_ARG(const QUuid&, remoteCallerID));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef THREAD_DEBUGGING
|
#ifdef THREAD_DEBUGGING
|
||||||
|
@ -2500,13 +2501,41 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
||||||
if (isEntityScriptRunning(entityID)) {
|
if (isEntityScriptRunning(entityID)) {
|
||||||
EntityScriptDetails details = _entityScripts[entityID];
|
EntityScriptDetails details = _entityScripts[entityID];
|
||||||
QScriptValue entityScript = details.scriptObject; // previously loaded
|
QScriptValue entityScript = details.scriptObject; // previously loaded
|
||||||
if (entityScript.property(methodName).isFunction()) {
|
|
||||||
|
// If this is a remote call, we need to check to see if the function is remotely callable
|
||||||
|
// we do this by checking for the existance of the 'remotelyCallable' property on the
|
||||||
|
// entityScript. And we confirm that the method name is included. If this fails, the
|
||||||
|
// function will not be called.
|
||||||
|
bool callAllowed = false;
|
||||||
|
if (remoteCallerID == QUuid()) {
|
||||||
|
callAllowed = true;
|
||||||
|
} else {
|
||||||
|
if (entityScript.property("remotelyCallable").isArray()) {
|
||||||
|
auto callables = entityScript.property("remotelyCallable");
|
||||||
|
auto callableCount = callables.property("length").toInteger();
|
||||||
|
for (int i = 0; i < callableCount; i++) {
|
||||||
|
auto callable = callables.property(i).toString();
|
||||||
|
if (callable == methodName) {
|
||||||
|
callAllowed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!callAllowed) {
|
||||||
|
qDebug() << "Method [" << methodName << "] not remotely callable.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callAllowed && entityScript.property(methodName).isFunction()) {
|
||||||
QScriptValueList args;
|
QScriptValueList args;
|
||||||
args << entityID.toScriptValue(this);
|
args << entityID.toScriptValue(this);
|
||||||
args << qScriptValueFromSequence(this, params);
|
args << qScriptValueFromSequence(this, params);
|
||||||
callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
QScriptValue oldData = this->globalObject().property("Script").property("remoteCallerID");
|
||||||
|
this->globalObject().property("Script").setProperty("remoteCallerID", remoteCallerID.toString()); // Make the remoteCallerID available to javascript as a global.
|
||||||
|
callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
|
||||||
|
this->globalObject().property("Script").setProperty("remoteCallerID", oldData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,8 @@ public:
|
||||||
Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap = false); // will call unload method
|
Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap = false); // will call unload method
|
||||||
Q_INVOKABLE void unloadAllEntityScripts();
|
Q_INVOKABLE void unloadAllEntityScripts();
|
||||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
|
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
|
||||||
const QStringList& params = QStringList()) override;
|
const QStringList& params = QStringList(),
|
||||||
|
const QUuid& remoteCallerID = QUuid()) override;
|
||||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const PointerEvent& event);
|
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const PointerEvent& event);
|
||||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision);
|
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision);
|
||||||
|
|
||||||
|
|
|
@ -97,5 +97,12 @@ private:
|
||||||
static QMap<QString, PerformanceTimerRecord> _records;
|
static QMap<QString, PerformanceTimerRecord> _records;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// uncomment WANT_DETAILED_PERFORMANCE_TIMERS definition to enable performance timers in high-frequency contexts
|
||||||
|
//#define WANT_DETAILED_PERFORMANCE_TIMERS
|
||||||
|
#ifdef WANT_DETAILED_PERFORMANCE_TIMERS
|
||||||
|
#define DETAILED_PERFORMANCE_TIMER(name) PerformanceTimer detailedPerformanceTimer(name);
|
||||||
|
#else // WANT_DETAILED_PERFORMANCE_TIMERS
|
||||||
|
#define DETAILED_PERFORMANCE_TIMER(name) ; // no-op
|
||||||
|
#endif // WANT_DETAILED_PERFORMANCE_TIMERS
|
||||||
|
|
||||||
#endif // hifi_PerfStat_h
|
#endif // hifi_PerfStat_h
|
||||||
|
|
|
@ -108,4 +108,14 @@ inline void metadata(const QString& metadataType, const QVariantMap& args) {
|
||||||
#define SAMPLE_PROFILE_COUNTER(chance, category, name, ...) if (randFloat() <= chance) { PROFILE_COUNTER(category, name, ##__VA_ARGS__); }
|
#define SAMPLE_PROFILE_COUNTER(chance, category, name, ...) if (randFloat() <= chance) { PROFILE_COUNTER(category, name, ##__VA_ARGS__); }
|
||||||
#define SAMPLE_PROFILE_INSTANT(chance, category, name, ...) if (randFloat() <= chance) { PROFILE_INSTANT(category, name, ##__VA_ARGS__); }
|
#define SAMPLE_PROFILE_INSTANT(chance, category, name, ...) if (randFloat() <= chance) { PROFILE_INSTANT(category, name, ##__VA_ARGS__); }
|
||||||
|
|
||||||
|
// uncomment WANT_DETAILED_PROFILING definition to enable profiling in high-frequency contexts
|
||||||
|
//#define WANT_DETAILED_PROFILING
|
||||||
|
#ifdef WANT_DETAILED_PROFILING
|
||||||
|
#define DETAILED_PROFILE_RANGE(category, name) Duration profileRangeThis(trace_##category(), name);
|
||||||
|
#define DETAILED_PROFILE_RANGE_EX(category, name, argbColor, payload, ...) Duration profileRangeThis(trace_##category(), name, argbColor, (uint64_t)payload, ##__VA_ARGS__);
|
||||||
|
#else // WANT_DETAILED_PROFILING
|
||||||
|
#define DETAILED_PROFILE_RANGE(category, name) ; // no-op
|
||||||
|
#define DETAILED_PROFILE_RANGE_EX(category, name, argbColor, payload, ...) ; // no-op
|
||||||
|
#endif // WANT_DETAILED_PROFILING
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,16 +23,28 @@
|
||||||
#include "ToolbarScriptingInterface.h"
|
#include "ToolbarScriptingInterface.h"
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
|
|
||||||
|
#include <AudioInjector.h>
|
||||||
|
|
||||||
|
#include "SettingHandle.h"
|
||||||
|
|
||||||
// FIXME move to global app properties
|
// FIXME move to global app properties
|
||||||
const QString SYSTEM_TOOLBAR = "com.highfidelity.interface.toolbar.system";
|
const QString SYSTEM_TOOLBAR = "com.highfidelity.interface.toolbar.system";
|
||||||
const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system";
|
const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system";
|
||||||
const QString TabletScriptingInterface::QML = "hifi/tablet/TabletRoot.qml";
|
const QString TabletScriptingInterface::QML = "hifi/tablet/TabletRoot.qml";
|
||||||
|
|
||||||
|
|
||||||
|
static Setting::Handle<QStringList> tabletSoundsButtonClick("TabletSounds", QStringList { "/sounds/Button06.wav",
|
||||||
|
"/sounds/Button04.wav",
|
||||||
|
"/sounds/Button07.wav",
|
||||||
|
"/sounds/Tab01.wav",
|
||||||
|
"/sounds/Tab02.wav" });
|
||||||
|
|
||||||
TabletScriptingInterface::TabletScriptingInterface() {
|
TabletScriptingInterface::TabletScriptingInterface() {
|
||||||
|
qmlRegisterType<TabletScriptingInterface>("TabletScriptingInterface", 1, 0, "TabletEnums");
|
||||||
}
|
}
|
||||||
|
|
||||||
TabletScriptingInterface::~TabletScriptingInterface() {
|
TabletScriptingInterface::~TabletScriptingInterface() {
|
||||||
|
tabletSoundsButtonClick.set(tabletSoundsButtonClick.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolbarProxy* TabletScriptingInterface::getSystemToolbarProxy() {
|
ToolbarProxy* TabletScriptingInterface::getSystemToolbarProxy() {
|
||||||
|
@ -63,6 +75,29 @@ TabletProxy* TabletScriptingInterface::getTablet(const QString& tabletId) {
|
||||||
return tabletProxy;
|
return tabletProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabletScriptingInterface::preloadSounds() {
|
||||||
|
//preload audio events
|
||||||
|
const QStringList &audioSettings = tabletSoundsButtonClick.get();
|
||||||
|
for (int i = 0; i < TabletAudioEvents::Last; i++) {
|
||||||
|
QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + audioSettings.at(i));
|
||||||
|
SharedSoundPointer sound = DependencyManager::get<SoundCache>()->
|
||||||
|
getSound(QUrl::fromLocalFile(inf.absoluteFilePath()));
|
||||||
|
_audioEvents.insert(static_cast<TabletAudioEvents>(i), sound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabletScriptingInterface::playSound(TabletAudioEvents aEvent) {
|
||||||
|
SharedSoundPointer sound = _audioEvents[aEvent];
|
||||||
|
if (sound) {
|
||||||
|
AudioInjectorOptions options;
|
||||||
|
options.stereo = sound->isStereo();
|
||||||
|
options.ambisonic = sound->isAmbisonic();
|
||||||
|
options.localOnly = true;
|
||||||
|
|
||||||
|
AudioInjectorPointer injector = AudioInjector::playSoundAndDelete(sound->getByteArray(), options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TabletScriptingInterface::setToolbarMode(bool toolbarMode) {
|
void TabletScriptingInterface::setToolbarMode(bool toolbarMode) {
|
||||||
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
||||||
_toolbarMode = toolbarMode;
|
_toolbarMode = toolbarMode;
|
||||||
|
@ -323,9 +358,12 @@ void TabletProxy::emitWebEvent(const QVariant& msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabletProxy::onTabletShown() {
|
void TabletProxy::onTabletShown() {
|
||||||
if (_tabletShown && _showRunningScripts) {
|
if (_tabletShown) {
|
||||||
_showRunningScripts = false;
|
static_cast<TabletScriptingInterface*>(parent())->playSound(TabletScriptingInterface::TabletOpen);
|
||||||
pushOntoStack("../../hifi/dialogs/TabletRunningScripts.qml");
|
if (_showRunningScripts) {
|
||||||
|
_showRunningScripts = false;
|
||||||
|
pushOntoStack("../../hifi/dialogs/TabletRunningScripts.qml");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
#include <glm/gtx/quaternion.hpp>
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
#include "SoundCache.h"
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
class ToolbarProxy;
|
class ToolbarProxy;
|
||||||
|
@ -40,8 +40,11 @@ class OffscreenQmlSurface;
|
||||||
class TabletScriptingInterface : public QObject, public Dependency {
|
class TabletScriptingInterface : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
enum TabletAudioEvents { ButtonClick, ButtonHover, TabletOpen, TabletHandsIn, TabletHandsOut, Last};
|
||||||
|
Q_ENUM(TabletAudioEvents)
|
||||||
|
|
||||||
TabletScriptingInterface();
|
TabletScriptingInterface();
|
||||||
~TabletScriptingInterface();
|
virtual ~TabletScriptingInterface();
|
||||||
static const QString QML;
|
static const QString QML;
|
||||||
|
|
||||||
void setToolbarScriptingInterface(ToolbarScriptingInterface* toolbarScriptingInterface) { _toolbarScriptingInterface = toolbarScriptingInterface; }
|
void setToolbarScriptingInterface(ToolbarScriptingInterface* toolbarScriptingInterface) { _toolbarScriptingInterface = toolbarScriptingInterface; }
|
||||||
|
@ -54,6 +57,9 @@ public:
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE TabletProxy* getTablet(const QString& tabletId);
|
Q_INVOKABLE TabletProxy* getTablet(const QString& tabletId);
|
||||||
|
|
||||||
|
void preloadSounds();
|
||||||
|
Q_INVOKABLE void playSound(TabletAudioEvents aEvent);
|
||||||
|
|
||||||
void setToolbarMode(bool toolbarMode);
|
void setToolbarMode(bool toolbarMode);
|
||||||
|
|
||||||
void setQmlTabletRoot(QString tabletId, OffscreenQmlSurface* offscreenQmlSurface);
|
void setQmlTabletRoot(QString tabletId, OffscreenQmlSurface* offscreenQmlSurface);
|
||||||
|
@ -77,6 +83,7 @@ private:
|
||||||
void processTabletEvents(QObject* object, const QKeyEvent* event);
|
void processTabletEvents(QObject* object, const QKeyEvent* event);
|
||||||
ToolbarProxy* getSystemToolbarProxy();
|
ToolbarProxy* getSystemToolbarProxy();
|
||||||
|
|
||||||
|
QMap<TabletAudioEvents, SharedSoundPointer> _audioEvents;
|
||||||
protected:
|
protected:
|
||||||
std::map<QString, TabletProxy*> _tabletProxies;
|
std::map<QString, TabletProxy*> _tabletProxies;
|
||||||
ToolbarScriptingInterface* _toolbarScriptingInterface { nullptr };
|
ToolbarScriptingInterface* _toolbarScriptingInterface { nullptr };
|
||||||
|
|
|
@ -141,8 +141,11 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setIgnoreTablet = function() {
|
this.setIgnoreTablet = function() {
|
||||||
RayPick.setIgnoreOverlays(_this.leftControllerRayPick, [HMD.tabletID]);
|
if (HMD.tabletID !== this.tabletID) {
|
||||||
RayPick.setIgnoreOverlays(_this.rightControllerRayPick, [HMD.tabletID]);
|
this.tabletID = HMD.tabletID;
|
||||||
|
RayPick.setIgnoreItems(_this.leftControllerRayPick, _this.blacklist.concat([HMD.tabletID]));
|
||||||
|
RayPick.setIgnoreItems(_this.rightControllerRayPick, _this.blacklist.concat([HMD.tabletID]));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.update = function () {
|
this.update = function () {
|
||||||
|
@ -367,9 +370,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setBlacklist = function() {
|
this.setBlacklist = function() {
|
||||||
RayPick.setIgnoreEntities(_this.leftControllerRayPick, this.blacklist);
|
RayPick.setIgnoreItems(_this.leftControllerRayPick, this.blacklist.concat(HMD.tabletID));
|
||||||
RayPick.setIgnoreEntities(_this.rightControllerRayPick, this.blacklist);
|
RayPick.setIgnoreItems(_this.rightControllerRayPick, this.blacklist.concat(HMD.tabletID));
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var MAPPING_NAME = "com.highfidelity.controllerDispatcher";
|
var MAPPING_NAME = "com.highfidelity.controllerDispatcher";
|
||||||
|
|
|
@ -127,6 +127,13 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
this.updateLaserPointer = function(controllerData) {
|
this.updateLaserPointer = function(controllerData) {
|
||||||
LaserPointers.enableLaserPointer(this.laserPointer);
|
LaserPointers.enableLaserPointer(this.laserPointer);
|
||||||
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
||||||
|
|
||||||
|
if (HMD.tabletID !== this.tabletID || HMD.tabletButtonID !== this.tabletButtonID || HMD.tabletScreenID !== this.tabletScreenID) {
|
||||||
|
this.tabletID = HMD.tabletID;
|
||||||
|
this.tabletButtonID = HMD.tabletButtonID;
|
||||||
|
this.tabletScreenID = HMD.tabletScreenID;
|
||||||
|
LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.pointingAtTablet = function(objectID) {
|
this.pointingAtTablet = function(objectID) {
|
||||||
|
@ -233,7 +240,7 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
defaultRenderStates: defaultRenderStates
|
defaultRenderStates: defaultRenderStates
|
||||||
});
|
});
|
||||||
|
|
||||||
LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]);
|
LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var leftHandInEditMode = new InEditMode(LEFT_HAND);
|
var leftHandInEditMode = new InEditMode(LEFT_HAND);
|
||||||
|
|
|
@ -177,6 +177,11 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.updateLaserPointer = function(controllerData) {
|
this.updateLaserPointer = function(controllerData) {
|
||||||
LaserPointers.enableLaserPointer(this.laserPointer);
|
LaserPointers.enableLaserPointer(this.laserPointer);
|
||||||
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
||||||
|
|
||||||
|
if (HMD.tabletID !== this.tabletID) {
|
||||||
|
this.tabletID = HMD.tabletID;
|
||||||
|
LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.processControllerTriggers = function(controllerData) {
|
this.processControllerTriggers = function(controllerData) {
|
||||||
|
@ -369,7 +374,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
defaultRenderStates: defaultRenderStates
|
defaultRenderStates: defaultRenderStates
|
||||||
});
|
});
|
||||||
|
|
||||||
LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID]);
|
LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var leftOverlayLaserInput = new OverlayLaserInput(LEFT_HAND);
|
var leftOverlayLaserInput = new OverlayLaserInput(LEFT_HAND);
|
||||||
|
|
|
@ -349,10 +349,10 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setIgnoreEntities = function(entitiesToIgnore) {
|
this.setIgnoreEntities = function(entitiesToIgnore) {
|
||||||
LaserPointers.setIgnoreEntities(this.teleportRayHandVisible, entitiesToIgnore);
|
LaserPointers.setIgnoreItems(this.teleportRayHandVisible, entitiesToIgnore);
|
||||||
LaserPointers.setIgnoreEntities(this.teleportRayHandInvisible, entitiesToIgnore);
|
LaserPointers.setIgnoreItems(this.teleportRayHandInvisible, entitiesToIgnore);
|
||||||
LaserPointers.setIgnoreEntities(this.teleportRayHeadVisible, entitiesToIgnore);
|
LaserPointers.setIgnoreItems(this.teleportRayHeadVisible, entitiesToIgnore);
|
||||||
LaserPointers.setIgnoreEntities(this.teleportRayHeadInvisible, entitiesToIgnore);
|
LaserPointers.setIgnoreItems(this.teleportRayHeadInvisible, entitiesToIgnore);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ function Grabber() {
|
||||||
filter: RayPick.PICK_OVERLAYS,
|
filter: RayPick.PICK_OVERLAYS,
|
||||||
enabled: true
|
enabled: true
|
||||||
});
|
});
|
||||||
RayPick.setIncludeOverlays(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]);
|
RayPick.setIncludeItems(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]);
|
||||||
var renderStates = [{name: "grabbed", end: beacon}];
|
var renderStates = [{name: "grabbed", end: beacon}];
|
||||||
this.mouseRayEntities = LaserPointers.createLaserPointer({
|
this.mouseRayEntities = LaserPointers.createLaserPointer({
|
||||||
joint: "Mouse",
|
joint: "Mouse",
|
||||||
|
|
|
@ -33,10 +33,4 @@ Audio.disconnected.connect(function(){
|
||||||
Audio.playSound(disconnectSound, soundOptions);
|
Audio.playSound(disconnectSound, soundOptions);
|
||||||
});
|
});
|
||||||
|
|
||||||
Audio.mutedChanged.connect(function () {
|
|
||||||
if (Audio.muted) {
|
|
||||||
Audio.playSound(micMutedSound, soundOptions);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}()); // END LOCAL_SCOPE
|
}()); // END LOCAL_SCOPE
|
||||||
|
|
Loading…
Reference in a new issue