mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 02:16:51 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into blocks
This commit is contained in:
commit
7ce31f3f69
24 changed files with 352 additions and 124 deletions
|
@ -49,7 +49,7 @@
|
||||||
Var STR_CONTAINS_VAR_3
|
Var STR_CONTAINS_VAR_3
|
||||||
Var STR_CONTAINS_VAR_4
|
Var STR_CONTAINS_VAR_4
|
||||||
Var STR_RETURN_VAR
|
Var STR_RETURN_VAR
|
||||||
|
|
||||||
Function StrContains
|
Function StrContains
|
||||||
Exch $STR_NEEDLE
|
Exch $STR_NEEDLE
|
||||||
Exch 1
|
Exch 1
|
||||||
|
@ -343,22 +343,29 @@ SectionEnd
|
||||||
;--------------------------------
|
;--------------------------------
|
||||||
;Pages
|
;Pages
|
||||||
!insertmacro MUI_PAGE_WELCOME
|
!insertmacro MUI_PAGE_WELCOME
|
||||||
|
|
||||||
!insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@"
|
!insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@"
|
||||||
|
|
||||||
|
Page custom InstallTypesPage ReadInstallTypes
|
||||||
|
|
||||||
|
!define MUI_PAGE_CUSTOMFUNCTION_PRE AbortFunction
|
||||||
!insertmacro MUI_PAGE_DIRECTORY
|
!insertmacro MUI_PAGE_DIRECTORY
|
||||||
|
|
||||||
;Start Menu Folder Page Configuration
|
;Start Menu Folder Page Configuration
|
||||||
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM"
|
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM"
|
||||||
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
|
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
|
||||||
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
|
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
|
||||||
|
|
||||||
|
!define MUI_PAGE_CUSTOMFUNCTION_PRE AbortFunction
|
||||||
!insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER
|
!insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER
|
||||||
|
|
||||||
|
!define MUI_PAGE_CUSTOMFUNCTION_PRE AbortFunction
|
||||||
@CPACK_NSIS_PAGE_COMPONENTS@
|
@CPACK_NSIS_PAGE_COMPONENTS@
|
||||||
|
|
||||||
Page custom PostInstallOptionsPage ReadPostInstallOptions
|
Page custom PostInstallOptionsPage ReadPostInstallOptions
|
||||||
|
|
||||||
!insertmacro MUI_PAGE_INSTFILES
|
!insertmacro MUI_PAGE_INSTFILES
|
||||||
|
|
||||||
!insertmacro MUI_UNPAGE_CONFIRM
|
!insertmacro MUI_UNPAGE_CONFIRM
|
||||||
!insertmacro MUI_UNPAGE_INSTFILES
|
!insertmacro MUI_UNPAGE_INSTFILES
|
||||||
|
|
||||||
|
@ -442,6 +449,10 @@ Var CleanInstallCheckbox
|
||||||
Var CurrentOffset
|
Var CurrentOffset
|
||||||
Var OffsetUnits
|
Var OffsetUnits
|
||||||
Var CopyFromProductionCheckbox
|
Var CopyFromProductionCheckbox
|
||||||
|
Var ExpressInstallRadioButton
|
||||||
|
Var CustomInstallRadioButton
|
||||||
|
Var InstallTypeDialog
|
||||||
|
Var Express
|
||||||
|
|
||||||
!macro SetPostInstallOption Checkbox OptionName Default
|
!macro SetPostInstallOption Checkbox OptionName Default
|
||||||
; reads the value for the given post install option to the registry
|
; reads the value for the given post install option to the registry
|
||||||
|
@ -459,6 +470,60 @@ Var CopyFromProductionCheckbox
|
||||||
${EndIf}
|
${EndIf}
|
||||||
!macroend
|
!macroend
|
||||||
|
|
||||||
|
Function InstallTypesPage
|
||||||
|
!insertmacro MUI_HEADER_TEXT "Choose Installation Type" "Express or Custom Install"
|
||||||
|
|
||||||
|
nsDialogs::Create 1018
|
||||||
|
Pop $InstallTypeDialog
|
||||||
|
|
||||||
|
${If} $InstallTypeDialog == error
|
||||||
|
Abort
|
||||||
|
${EndIf}
|
||||||
|
|
||||||
|
StrCpy $CurrentOffset 0
|
||||||
|
StrCpy $OffsetUnits u
|
||||||
|
StrCpy $Express "0"
|
||||||
|
|
||||||
|
${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@}
|
||||||
|
${NSD_CreateRadioButton} 30% $CurrentOffset$OffsetUnits 100% 10u "Express Install (Recommended)"; $\nInstalls High Fidelity Interface and High Fidelity Sandbox"
|
||||||
|
pop $ExpressInstallRadioButton
|
||||||
|
${NSD_OnClick} $ExpressInstallRadioButton ChangeExpressLabel
|
||||||
|
IntOp $CurrentOffset $CurrentOffset + 15
|
||||||
|
|
||||||
|
${NSD_CreateRadiobutton} 30% $CurrentOffset$OffsetUnits 100% 10u "Custom Install (Advanced)"
|
||||||
|
pop $CustomInstallRadioButton
|
||||||
|
${NSD_OnClick} $CustomInstallRadioButton ChangeCustomLabel
|
||||||
|
${EndIf}
|
||||||
|
|
||||||
|
; Express Install selected by default
|
||||||
|
${NSD_Check} $ExpressInstallRadioButton
|
||||||
|
Call ChangeExpressLabel
|
||||||
|
|
||||||
|
nsDialogs::Show
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
|
Function ChangeExpressLabel
|
||||||
|
Push $R1
|
||||||
|
GetDlgItem $R1 $HWNDPARENT 1
|
||||||
|
SendMessage $R1 ${WM_SETTEXT} 0 "STR:Install"
|
||||||
|
Pop $R1
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
|
Function ChangeCustomLabel
|
||||||
|
Push $R1
|
||||||
|
GetDlgItem $R1 $HWNDPARENT 1
|
||||||
|
SendMessage $R1 ${WM_SETTEXT} 0 "STR:Next >"
|
||||||
|
Pop $R1
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
|
Function AbortFunction
|
||||||
|
; Check if Express is set, if so, abort the post install options page
|
||||||
|
Call HandleInstallTypes ; Sets Express if ExpressInstallRadioButton is checked and installs with defaults
|
||||||
|
StrCmp $Express "1" 0 end
|
||||||
|
Abort
|
||||||
|
end:
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
Function PostInstallOptionsPage
|
Function PostInstallOptionsPage
|
||||||
!insertmacro MUI_HEADER_TEXT "Setup Options" ""
|
!insertmacro MUI_HEADER_TEXT "Setup Options" ""
|
||||||
|
|
||||||
|
@ -549,9 +614,15 @@ Function PostInstallOptionsPage
|
||||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Copy settings and content from production install"
|
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Copy settings and content from production install"
|
||||||
Pop $CopyFromProductionCheckbox
|
Pop $CopyFromProductionCheckbox
|
||||||
|
|
||||||
${NSD_SetState} $CopyFromProductionCheckbox ${BST_CHECKED}
|
${NSD_SetState} $CopyFromProductionCheckbox ${BST_UNCHECKED}
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
|
; Check if Express is set, if so, abort the post install options page
|
||||||
|
Call HandleInstallTypes ; Sets Express if ExpressInstallRadioButton is checked and installs with defaults
|
||||||
|
StrCmp $Express "1" 0 end
|
||||||
|
Abort
|
||||||
|
end:
|
||||||
|
|
||||||
nsDialogs::Show
|
nsDialogs::Show
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
|
@ -567,6 +638,16 @@ Var LaunchServerNowState
|
||||||
Var LaunchClientNowState
|
Var LaunchClientNowState
|
||||||
Var CopyFromProductionState
|
Var CopyFromProductionState
|
||||||
Var CleanInstallState
|
Var CleanInstallState
|
||||||
|
Var ExpressInstallState
|
||||||
|
Var CustomInstallState
|
||||||
|
|
||||||
|
Function ReadInstallTypes
|
||||||
|
${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@}
|
||||||
|
; check if the user asked for express/custom install
|
||||||
|
${NSD_GetState} $ExpressInstallRadioButton $ExpressInstallState
|
||||||
|
${NSD_GetState} $CustomInstallRadioButton $CustomInstallState
|
||||||
|
${EndIf}
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
Function ReadPostInstallOptions
|
Function ReadPostInstallOptions
|
||||||
${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@}
|
${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@}
|
||||||
|
@ -603,6 +684,28 @@ Function ReadPostInstallOptions
|
||||||
${EndIf}
|
${EndIf}
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
|
Function HandleInstallTypes
|
||||||
|
${If} $ExpressInstallState == ${BST_CHECKED}
|
||||||
|
|
||||||
|
StrCpy $Express "1"
|
||||||
|
|
||||||
|
; over ride custom checkboxes and select defaults
|
||||||
|
${NSD_SetState} $DesktopClientCheckbox ${BST_CHECKED}
|
||||||
|
${NSD_SetState} $ServerStartupCheckbox ${BST_CHECKED}
|
||||||
|
${NSD_SetState} $LaunchServerNowCheckbox ${BST_CHECKED}
|
||||||
|
${NSD_SetState} $LaunchClientNowCheckbox ${BST_CHECKED}
|
||||||
|
|
||||||
|
${If} @PR_BUILD@ == 1
|
||||||
|
${NSD_SetState} $CopyFromProductionCheckbox ${BST_UNCHECKED}
|
||||||
|
${EndIf}
|
||||||
|
|
||||||
|
; call ReadPostInstallOptions and HandlePostInstallOptions with defaults selected
|
||||||
|
Call ReadPostInstallOptions
|
||||||
|
Call HandlePostInstallOptions
|
||||||
|
|
||||||
|
${EndIf}
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
Function HandlePostInstallOptions
|
Function HandlePostInstallOptions
|
||||||
${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@}
|
${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@}
|
||||||
; check if the user asked for a desktop shortcut to High Fidelity
|
; check if the user asked for a desktop shortcut to High Fidelity
|
||||||
|
@ -624,6 +727,7 @@ Function HandlePostInstallOptions
|
||||||
!insertmacro WritePostInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ NO
|
!insertmacro WritePostInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ NO
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
|
|
||||||
; check if the user asked to have Sandbox launched every startup
|
; check if the user asked to have Sandbox launched every startup
|
||||||
${If} $ServerStartupState == ${BST_CHECKED}
|
${If} $ServerStartupState == ${BST_CHECKED}
|
||||||
; in case we added a shortcut in the global context, pull that now
|
; in case we added a shortcut in the global context, pull that now
|
||||||
|
|
BIN
interface/resources/images/cursor-arrow.png
Normal file
BIN
interface/resources/images/cursor-arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
interface/resources/images/cursor-link.png
Normal file
BIN
interface/resources/images/cursor-link.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
BIN
interface/resources/images/cursor-none.png
Normal file
BIN
interface/resources/images/cursor-none.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 133 B |
BIN
interface/resources/images/cursor-reticle.png
Normal file
BIN
interface/resources/images/cursor-reticle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9 KiB |
|
@ -28,6 +28,7 @@ ScrollingWindow {
|
||||||
minSize: Qt.vector2d(200, 300)
|
minSize: Qt.vector2d(200, 300)
|
||||||
|
|
||||||
property int colorScheme: hifi.colorSchemes.dark
|
property int colorScheme: hifi.colorSchemes.dark
|
||||||
|
property int selectionMode: SelectionMode.ExtendedSelection
|
||||||
|
|
||||||
HifiConstants { id: hifi }
|
HifiConstants { id: hifi }
|
||||||
|
|
||||||
|
@ -35,7 +36,8 @@ ScrollingWindow {
|
||||||
property var assetProxyModel: Assets.proxyModel;
|
property var assetProxyModel: Assets.proxyModel;
|
||||||
property var assetMappingsModel: Assets.mappingModel;
|
property var assetMappingsModel: Assets.mappingModel;
|
||||||
property var currentDirectory;
|
property var currentDirectory;
|
||||||
|
property var selectedItems: treeView.selection.selectedIndexes.length;
|
||||||
|
|
||||||
Settings {
|
Settings {
|
||||||
category: "Overlay.AssetServer"
|
category: "Overlay.AssetServer"
|
||||||
property alias x: root.x
|
property alias x: root.x
|
||||||
|
@ -48,7 +50,7 @@ ScrollingWindow {
|
||||||
assetMappingsModel.errorGettingMappings.connect(handleGetMappingsError);
|
assetMappingsModel.errorGettingMappings.connect(handleGetMappingsError);
|
||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
function doDeleteFile(path) {
|
function doDeleteFile(path) {
|
||||||
console.log("Deleting " + path);
|
console.log("Deleting " + path);
|
||||||
|
|
||||||
|
@ -118,11 +120,23 @@ ScrollingWindow {
|
||||||
|
|
||||||
function canAddToWorld(path) {
|
function canAddToWorld(path) {
|
||||||
var supportedExtensions = [/\.fbx\b/i, /\.obj\b/i];
|
var supportedExtensions = [/\.fbx\b/i, /\.obj\b/i];
|
||||||
|
|
||||||
|
if (selectedItems > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return supportedExtensions.reduce(function(total, current) {
|
return supportedExtensions.reduce(function(total, current) {
|
||||||
return total | new RegExp(current).test(path);
|
return total | new RegExp(current).test(path);
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function canRename() {
|
||||||
|
if (treeView.selection.hasSelection && selectedItems == 1) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function clear() {
|
function clear() {
|
||||||
Assets.mappingModel.clear();
|
Assets.mappingModel.clear();
|
||||||
|
@ -299,23 +313,37 @@ ScrollingWindow {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function deleteFile(index) {
|
function deleteFile(index) {
|
||||||
|
var path = [];
|
||||||
|
|
||||||
if (!index) {
|
if (!index) {
|
||||||
index = treeView.selection.currentIndex;
|
for (var i = 0; i < selectedItems; i++) {
|
||||||
|
treeView.selection.setCurrentIndex(treeView.selection.selectedIndexes[i], 0x100);
|
||||||
|
index = treeView.selection.currentIndex;
|
||||||
|
path[i] = assetProxyModel.data(index, 0x100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var path = assetProxyModel.data(index, 0x100);
|
|
||||||
if (!path) {
|
if (!path) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var modalMessage = "";
|
||||||
|
var items = selectedItems.toString();
|
||||||
var isFolder = assetProxyModel.data(treeView.selection.currentIndex, 0x101);
|
var isFolder = assetProxyModel.data(treeView.selection.currentIndex, 0x101);
|
||||||
var typeString = isFolder ? 'folder' : 'file';
|
var typeString = isFolder ? 'folder' : 'file';
|
||||||
|
|
||||||
|
if (selectedItems > 1) {
|
||||||
|
modalMessage = "You are about to delete " + items + " items \nDo you want to continue?";
|
||||||
|
} else {
|
||||||
|
modalMessage = "You are about to delete the following " + typeString + ":\n" + path + "\nDo you want to continue?";
|
||||||
|
}
|
||||||
|
|
||||||
var object = desktop.messageBox({
|
var object = desktop.messageBox({
|
||||||
icon: hifi.icons.question,
|
icon: hifi.icons.question,
|
||||||
buttons: OriginalDialogs.StandardButton.Yes + OriginalDialogs.StandardButton.No,
|
buttons: OriginalDialogs.StandardButton.Yes + OriginalDialogs.StandardButton.No,
|
||||||
defaultButton: OriginalDialogs.StandardButton.Yes,
|
defaultButton: OriginalDialogs.StandardButton.Yes,
|
||||||
title: "Delete",
|
title: "Delete",
|
||||||
text: "You are about to delete the following " + typeString + ":\n" + path + "\nDo you want to continue?"
|
text: modalMessage
|
||||||
});
|
});
|
||||||
object.selected.connect(function(button) {
|
object.selected.connect(function(button) {
|
||||||
if (button === OriginalDialogs.StandardButton.Yes) {
|
if (button === OriginalDialogs.StandardButton.Yes) {
|
||||||
|
@ -455,20 +483,20 @@ ScrollingWindow {
|
||||||
color: hifi.buttons.black
|
color: hifi.buttons.black
|
||||||
colorScheme: root.colorScheme
|
colorScheme: root.colorScheme
|
||||||
width: 120
|
width: 120
|
||||||
|
|
||||||
enabled: canAddToWorld(assetProxyModel.data(treeView.selection.currentIndex, 0x100))
|
enabled: canAddToWorld(assetProxyModel.data(treeView.selection.currentIndex, 0x100))
|
||||||
|
|
||||||
onClicked: root.addToWorld()
|
onClicked: root.addToWorld()
|
||||||
}
|
}
|
||||||
|
|
||||||
HifiControls.Button {
|
HifiControls.Button {
|
||||||
text: "Rename"
|
text: "Rename"
|
||||||
color: hifi.buttons.black
|
color: hifi.buttons.black
|
||||||
colorScheme: root.colorScheme
|
colorScheme: root.colorScheme
|
||||||
width: 80
|
width: 80
|
||||||
|
|
||||||
onClicked: root.renameFile()
|
onClicked: root.renameFile()
|
||||||
enabled: treeView.selection.hasSelection
|
enabled: canRename()
|
||||||
}
|
}
|
||||||
|
|
||||||
HifiControls.Button {
|
HifiControls.Button {
|
||||||
|
@ -524,6 +552,7 @@ ScrollingWindow {
|
||||||
treeModel: assetProxyModel
|
treeModel: assetProxyModel
|
||||||
canEdit: true
|
canEdit: true
|
||||||
colorScheme: root.colorScheme
|
colorScheme: root.colorScheme
|
||||||
|
selectionMode: SelectionMode.ExtendedSelection
|
||||||
|
|
||||||
modifyEl: renameEl
|
modifyEl: renameEl
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ Rectangle {
|
||||||
property var assetProxyModel: Assets.proxyModel;
|
property var assetProxyModel: Assets.proxyModel;
|
||||||
property var assetMappingsModel: Assets.mappingModel;
|
property var assetMappingsModel: Assets.mappingModel;
|
||||||
property var currentDirectory;
|
property var currentDirectory;
|
||||||
|
property var selectedItems: treeView.selection.selectedIndexes.length;
|
||||||
|
|
||||||
Settings {
|
Settings {
|
||||||
category: "Overlay.AssetServer"
|
category: "Overlay.AssetServer"
|
||||||
|
@ -119,11 +120,23 @@ Rectangle {
|
||||||
|
|
||||||
function canAddToWorld(path) {
|
function canAddToWorld(path) {
|
||||||
var supportedExtensions = [/\.fbx\b/i, /\.obj\b/i];
|
var supportedExtensions = [/\.fbx\b/i, /\.obj\b/i];
|
||||||
|
|
||||||
|
if (selectedItems > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return supportedExtensions.reduce(function(total, current) {
|
return supportedExtensions.reduce(function(total, current) {
|
||||||
return total | new RegExp(current).test(path);
|
return total | new RegExp(current).test(path);
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function canRename() {
|
||||||
|
if (treeView.selection.hasSelection && selectedItems == 1) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function clear() {
|
function clear() {
|
||||||
Assets.mappingModel.clear();
|
Assets.mappingModel.clear();
|
||||||
|
@ -300,23 +313,37 @@ Rectangle {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function deleteFile(index) {
|
function deleteFile(index) {
|
||||||
|
var path = [];
|
||||||
|
|
||||||
if (!index) {
|
if (!index) {
|
||||||
index = treeView.selection.currentIndex;
|
for (var i = 0; i < selectedItems; i++) {
|
||||||
|
treeView.selection.setCurrentIndex(treeView.selection.selectedIndexes[i], 0x100);
|
||||||
|
index = treeView.selection.currentIndex;
|
||||||
|
path[i] = assetProxyModel.data(index, 0x100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var path = assetProxyModel.data(index, 0x100);
|
|
||||||
if (!path) {
|
if (!path) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var modalMessage = "";
|
||||||
|
var items = selectedItems.toString();
|
||||||
var isFolder = assetProxyModel.data(treeView.selection.currentIndex, 0x101);
|
var isFolder = assetProxyModel.data(treeView.selection.currentIndex, 0x101);
|
||||||
var typeString = isFolder ? 'folder' : 'file';
|
var typeString = isFolder ? 'folder' : 'file';
|
||||||
|
|
||||||
|
if (selectedItems > 1) {
|
||||||
|
modalMessage = "You are about to delete " + items + " items \nDo you want to continue?";
|
||||||
|
} else {
|
||||||
|
modalMessage = "You are about to delete the following " + typeString + ":\n" + path + "\nDo you want to continue?";
|
||||||
|
}
|
||||||
|
|
||||||
var object = tabletRoot.messageBox({
|
var object = tabletRoot.messageBox({
|
||||||
icon: hifi.icons.question,
|
icon: hifi.icons.question,
|
||||||
buttons: OriginalDialogs.StandardButton.Yes + OriginalDialogs.StandardButton.No,
|
buttons: OriginalDialogs.StandardButton.Yes + OriginalDialogs.StandardButton.No,
|
||||||
defaultButton: OriginalDialogs.StandardButton.Yes,
|
defaultButton: OriginalDialogs.StandardButton.Yes,
|
||||||
title: "Delete",
|
title: "Delete",
|
||||||
text: "You are about to delete the following " + typeString + ":\n" + path + "\nDo you want to continue?"
|
text: modalMessage
|
||||||
});
|
});
|
||||||
object.selected.connect(function(button) {
|
object.selected.connect(function(button) {
|
||||||
if (button === OriginalDialogs.StandardButton.Yes) {
|
if (button === OriginalDialogs.StandardButton.Yes) {
|
||||||
|
@ -469,7 +496,7 @@ Rectangle {
|
||||||
width: 80
|
width: 80
|
||||||
|
|
||||||
onClicked: root.renameFile()
|
onClicked: root.renameFile()
|
||||||
enabled: treeView.selection.hasSelection
|
enabled: canRename()
|
||||||
}
|
}
|
||||||
|
|
||||||
HifiControls.Button {
|
HifiControls.Button {
|
||||||
|
@ -525,6 +552,7 @@ Rectangle {
|
||||||
treeModel: assetProxyModel
|
treeModel: assetProxyModel
|
||||||
canEdit: true
|
canEdit: true
|
||||||
colorScheme: root.colorScheme
|
colorScheme: root.colorScheme
|
||||||
|
selectionMode: SelectionMode.ExtendedSelection
|
||||||
|
|
||||||
modifyEl: renameEl
|
modifyEl: renameEl
|
||||||
|
|
||||||
|
|
|
@ -624,6 +624,7 @@ const float DEFAULT_DESKTOP_TABLET_SCALE_PERCENT = 75.0f;
|
||||||
const bool DEFAULT_DESKTOP_TABLET_BECOMES_TOOLBAR = true;
|
const bool DEFAULT_DESKTOP_TABLET_BECOMES_TOOLBAR = true;
|
||||||
const bool DEFAULT_HMD_TABLET_BECOMES_TOOLBAR = false;
|
const bool DEFAULT_HMD_TABLET_BECOMES_TOOLBAR = false;
|
||||||
const bool DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS = false;
|
const bool DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS = false;
|
||||||
|
const QString DEFAULT_CURSOR_NAME = "DEFAULT";
|
||||||
|
|
||||||
Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bool runningMarkerExisted) :
|
Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bool runningMarkerExisted) :
|
||||||
QApplication(argc, argv),
|
QApplication(argc, argv),
|
||||||
|
@ -643,6 +644,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
_hmdTabletBecomesToolbarSetting("hmdTabletBecomesToolbar", DEFAULT_HMD_TABLET_BECOMES_TOOLBAR),
|
_hmdTabletBecomesToolbarSetting("hmdTabletBecomesToolbar", DEFAULT_HMD_TABLET_BECOMES_TOOLBAR),
|
||||||
_preferAvatarFingerOverStylusSetting("preferAvatarFingerOverStylus", DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS),
|
_preferAvatarFingerOverStylusSetting("preferAvatarFingerOverStylus", DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS),
|
||||||
_constrainToolbarPosition("toolbar/constrainToolbarToCenterX", true),
|
_constrainToolbarPosition("toolbar/constrainToolbarToCenterX", true),
|
||||||
|
_preferredCursor("preferredCursor", DEFAULT_CURSOR_NAME),
|
||||||
_scaleMirror(1.0f),
|
_scaleMirror(1.0f),
|
||||||
_rotateMirror(0.0f),
|
_rotateMirror(0.0f),
|
||||||
_raiseMirror(0.0f),
|
_raiseMirror(0.0f),
|
||||||
|
@ -938,14 +940,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
_glWidget->setFocusPolicy(Qt::StrongFocus);
|
_glWidget->setFocusPolicy(Qt::StrongFocus);
|
||||||
_glWidget->setFocus();
|
_glWidget->setFocus();
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
showCursor(Cursor::Manager::lookupIcon(_preferredCursor.get()));
|
||||||
auto cursorTarget = _window; // OSX doesn't seem to provide for hiding the cursor only on the GL widget
|
|
||||||
#else
|
|
||||||
// On windows and linux, hiding the top level cursor also means it's invisible when hovering over the
|
|
||||||
// window menu, which is a pain, so only hide it for the GL surface
|
|
||||||
auto cursorTarget = _glWidget;
|
|
||||||
#endif
|
|
||||||
cursorTarget->setCursor(Qt::BlankCursor);
|
|
||||||
|
|
||||||
// enable mouse tracking; otherwise, we only get drag events
|
// enable mouse tracking; otherwise, we only get drag events
|
||||||
_glWidget->setMouseTracking(true);
|
_glWidget->setMouseTracking(true);
|
||||||
|
@ -1743,9 +1738,16 @@ void Application::checkChangeCursor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::showCursor(const QCursor& cursor) {
|
void Application::showCursor(const Cursor::Icon& cursor) {
|
||||||
QMutexLocker locker(&_changeCursorLock);
|
QMutexLocker locker(&_changeCursorLock);
|
||||||
_desiredCursor = cursor;
|
|
||||||
|
auto managedCursor = Cursor::Manager::instance().getCursor();
|
||||||
|
auto curIcon = managedCursor->getIcon();
|
||||||
|
if (curIcon != cursor) {
|
||||||
|
managedCursor->setIcon(cursor);
|
||||||
|
curIcon = cursor;
|
||||||
|
}
|
||||||
|
_desiredCursor = cursor == Cursor::Icon::SYSTEM ? Qt::ArrowCursor : Qt::BlankCursor;
|
||||||
_cursorNeedsChanging = true;
|
_cursorNeedsChanging = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2166,9 +2168,11 @@ void Application::initializeUi() {
|
||||||
_window->setMenuBar(new Menu());
|
_window->setMenuBar(new Menu());
|
||||||
|
|
||||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||||
connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, [=] {
|
connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, this, [=] {
|
||||||
if (isHMDMode()) {
|
if (isHMDMode()) {
|
||||||
showCursor(compositorHelper->getAllowMouseCapture() ? Qt::BlankCursor : Qt::ArrowCursor);
|
showCursor(compositorHelper->getAllowMouseCapture() ?
|
||||||
|
Cursor::Manager::lookupIcon(_preferredCursor.get()) :
|
||||||
|
Cursor::Icon::SYSTEM);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2510,6 +2514,12 @@ void Application::setPreferAvatarFingerOverStylus(bool value) {
|
||||||
_preferAvatarFingerOverStylusSetting.set(value);
|
_preferAvatarFingerOverStylusSetting.set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::setPreferredCursor(const QString& cursorName) {
|
||||||
|
qCDebug(interfaceapp) << "setPreferredCursor" << cursorName;
|
||||||
|
_preferredCursor.set(cursorName.isEmpty() ? DEFAULT_CURSOR_NAME : cursorName);
|
||||||
|
showCursor(Cursor::Manager::lookupIcon(_preferredCursor.get()));
|
||||||
|
}
|
||||||
|
|
||||||
void Application::setSettingConstrainToolbarPosition(bool setting) {
|
void Application::setSettingConstrainToolbarPosition(bool setting) {
|
||||||
_constrainToolbarPosition.set(setting);
|
_constrainToolbarPosition.set(setting);
|
||||||
DependencyManager::get<OffscreenUi>()->setConstrainToolbarToCenterX(setting);
|
DependencyManager::get<OffscreenUi>()->setConstrainToolbarToCenterX(setting);
|
||||||
|
@ -3080,9 +3090,13 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
auto cursor = Cursor::Manager::instance().getCursor();
|
auto cursor = Cursor::Manager::instance().getCursor();
|
||||||
auto curIcon = cursor->getIcon();
|
auto curIcon = cursor->getIcon();
|
||||||
if (curIcon == Cursor::Icon::DEFAULT) {
|
if (curIcon == Cursor::Icon::DEFAULT) {
|
||||||
cursor->setIcon(Cursor::Icon::LINK);
|
showCursor(Cursor::Icon::RETICLE);
|
||||||
|
} else if (curIcon == Cursor::Icon::RETICLE) {
|
||||||
|
showCursor(Cursor::Icon::SYSTEM);
|
||||||
|
} else if (curIcon == Cursor::Icon::SYSTEM) {
|
||||||
|
showCursor(Cursor::Icon::LINK);
|
||||||
} else {
|
} else {
|
||||||
cursor->setIcon(Cursor::Icon::DEFAULT);
|
showCursor(Cursor::Icon::DEFAULT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resetSensors(true);
|
resetSensors(true);
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include "BandwidthRecorder.h"
|
#include "BandwidthRecorder.h"
|
||||||
#include "FancyCamera.h"
|
#include "FancyCamera.h"
|
||||||
#include "ConnectionMonitor.h"
|
#include "ConnectionMonitor.h"
|
||||||
|
#include "CursorManager.h"
|
||||||
#include "gpu/Context.h"
|
#include "gpu/Context.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "octree/OctreePacketProcessor.h"
|
#include "octree/OctreePacketProcessor.h"
|
||||||
|
@ -165,7 +166,7 @@ public:
|
||||||
QSize getDeviceSize() const;
|
QSize getDeviceSize() const;
|
||||||
bool hasFocus() const;
|
bool hasFocus() const;
|
||||||
|
|
||||||
void showCursor(const QCursor& cursor);
|
void showCursor(const Cursor::Icon& cursor);
|
||||||
|
|
||||||
bool isThrottleRendering() const;
|
bool isThrottleRendering() const;
|
||||||
|
|
||||||
|
@ -400,6 +401,9 @@ public slots:
|
||||||
void loadDomainConnectionDialog();
|
void loadDomainConnectionDialog();
|
||||||
void showScriptLogs();
|
void showScriptLogs();
|
||||||
|
|
||||||
|
const QString getPreferredCursor() const { return _preferredCursor.get(); }
|
||||||
|
void setPreferredCursor(const QString& cursor);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void showDesktop();
|
void showDesktop();
|
||||||
void clearDomainOctreeDetails();
|
void clearDomainOctreeDetails();
|
||||||
|
@ -567,6 +571,7 @@ private:
|
||||||
Setting::Handle<bool> _hmdTabletBecomesToolbarSetting;
|
Setting::Handle<bool> _hmdTabletBecomesToolbarSetting;
|
||||||
Setting::Handle<bool> _preferAvatarFingerOverStylusSetting;
|
Setting::Handle<bool> _preferAvatarFingerOverStylusSetting;
|
||||||
Setting::Handle<bool> _constrainToolbarPosition;
|
Setting::Handle<bool> _constrainToolbarPosition;
|
||||||
|
Setting::Handle<QString> _preferredCursor;
|
||||||
|
|
||||||
float _scaleMirror;
|
float _scaleMirror;
|
||||||
float _rotateMirror;
|
float _rotateMirror;
|
||||||
|
@ -640,7 +645,7 @@ private:
|
||||||
|
|
||||||
void checkChangeCursor();
|
void checkChangeCursor();
|
||||||
mutable QMutex _changeCursorLock { QMutex::Recursive };
|
mutable QMutex _changeCursorLock { QMutex::Recursive };
|
||||||
QCursor _desiredCursor{ Qt::BlankCursor };
|
Qt::CursorShape _desiredCursor{ Qt::BlankCursor };
|
||||||
bool _cursorNeedsChanging { false };
|
bool _cursorNeedsChanging { false };
|
||||||
|
|
||||||
QThread* _deadlockWatchdogThread;
|
QThread* _deadlockWatchdogThread;
|
||||||
|
|
|
@ -613,7 +613,7 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
MovingEntitiesOperator moveOperator(entityTree);
|
MovingEntitiesOperator moveOperator(entityTree);
|
||||||
forEachDescendant([&](SpatiallyNestablePointer object) {
|
forEachDescendant([&](SpatiallyNestablePointer object) {
|
||||||
// if the queryBox has changed, tell the entity-server
|
// if the queryBox has changed, tell the entity-server
|
||||||
if (object->computePuffedQueryAACube() && object->getNestableType() == NestableType::Entity) {
|
if (object->getNestableType() == NestableType::Entity && object->checkAndMaybeUpdateQueryAACube()) {
|
||||||
EntityItemPointer entity = std::static_pointer_cast<EntityItem>(object);
|
EntityItemPointer entity = std::static_pointer_cast<EntityItem>(object);
|
||||||
bool success;
|
bool success;
|
||||||
AACube newCube = entity->getQueryAACube(success);
|
AACube newCube = entity->getQueryAACube(success);
|
||||||
|
|
|
@ -106,6 +106,12 @@ void setupPreferences() {
|
||||||
auto setter = [](bool value) { qApp->setPreferAvatarFingerOverStylus(value); };
|
auto setter = [](bool value) { qApp->setPreferAvatarFingerOverStylus(value); };
|
||||||
preferences->addPreference(new CheckPreference(UI_CATEGORY, "Prefer Avatar Finger Over Stylus", getter, setter));
|
preferences->addPreference(new CheckPreference(UI_CATEGORY, "Prefer Avatar Finger Over Stylus", getter, setter));
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
static const QString RETICLE_ICON_NAME = { Cursor::Manager::getIconName(Cursor::Icon::RETICLE) };
|
||||||
|
auto getter = []()->bool { return qApp->getPreferredCursor() == RETICLE_ICON_NAME; };
|
||||||
|
auto setter = [](bool value) { qApp->setPreferredCursor(value ? RETICLE_ICON_NAME : QString()); };
|
||||||
|
preferences->addPreference(new CheckPreference(UI_CATEGORY, "Use reticle cursor instead of arrow", getter, setter));
|
||||||
|
}
|
||||||
|
|
||||||
// Snapshots
|
// Snapshots
|
||||||
static const QString SNAPSHOTS { "Snapshots" };
|
static const QString SNAPSHOTS { "Snapshots" };
|
||||||
|
|
|
@ -323,7 +323,7 @@ signals:
|
||||||
private:
|
private:
|
||||||
void cleanupOverlaysToDelete();
|
void cleanupOverlaysToDelete();
|
||||||
|
|
||||||
mutable QMutex _mutex;
|
mutable QMutex _mutex { QMutex::Recursive };
|
||||||
QMap<OverlayID, Overlay::Pointer> _overlaysHUD;
|
QMap<OverlayID, Overlay::Pointer> _overlaysHUD;
|
||||||
QMap<OverlayID, Overlay::Pointer> _overlaysWorld;
|
QMap<OverlayID, Overlay::Pointer> _overlaysWorld;
|
||||||
#if OVERLAY_PANELS
|
#if OVERLAY_PANELS
|
||||||
|
|
|
@ -1355,8 +1355,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lastEditedBy, setLastEditedBy);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lastEditedBy, setLastEditedBy);
|
||||||
|
|
||||||
AACube saveQueryAACube = _queryAACube;
|
AACube saveQueryAACube = _queryAACube;
|
||||||
checkAndAdjustQueryAACube();
|
if (checkAndMaybeUpdateQueryAACube() && saveQueryAACube != _queryAACube) {
|
||||||
if (saveQueryAACube != _queryAACube) {
|
|
||||||
somethingChanged = true;
|
somethingChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1424,26 +1423,20 @@ void EntityItem::setDimensions(const glm::vec3& value) {
|
||||||
///
|
///
|
||||||
AACube EntityItem::getMaximumAACube(bool& success) const {
|
AACube EntityItem::getMaximumAACube(bool& success) const {
|
||||||
if (_recalcMaxAACube) {
|
if (_recalcMaxAACube) {
|
||||||
// * we know that the position is the center of rotation
|
|
||||||
glm::vec3 centerOfRotation = getPosition(success); // also where _registration point is
|
glm::vec3 centerOfRotation = getPosition(success); // also where _registration point is
|
||||||
if (success) {
|
if (success) {
|
||||||
_recalcMaxAACube = false;
|
_recalcMaxAACube = false;
|
||||||
// * we know that the registration point is the center of rotation
|
// we want to compute the furthestExtent that an entity can extend out from its "position"
|
||||||
// * we can calculate the length of the furthest extent from the registration point
|
// to do this we compute the max of these two vec3s: registration and 1-registration
|
||||||
// as the dimensions * max (registrationPoint, (1.0,1.0,1.0) - registrationPoint)
|
// and then scale by dimensions
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 maxExtents = getDimensions() * glm::max(_registrationPoint, glm::vec3(1.0f) - _registrationPoint);
|
||||||
glm::vec3 registrationPoint = (dimensions * _registrationPoint);
|
|
||||||
glm::vec3 registrationRemainder = (dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint));
|
|
||||||
glm::vec3 furthestExtentFromRegistration = glm::max(registrationPoint, registrationRemainder);
|
|
||||||
|
|
||||||
// * we know that if you rotate in any direction you would create a sphere
|
// there exists a sphere that contains maxExtents for all rotations
|
||||||
// that has a radius of the length of furthest extent from registration point
|
float radius = glm::length(maxExtents);
|
||||||
float radius = glm::length(furthestExtentFromRegistration);
|
|
||||||
|
|
||||||
// * we know that the minimum bounding cube of this maximum possible sphere is
|
// put a cube around the sphere
|
||||||
// (center - radius) to (center + radius)
|
// TODO? replace _maxAACube with _boundingSphereRadius
|
||||||
glm::vec3 minimumCorner = centerOfRotation - glm::vec3(radius, radius, radius);
|
glm::vec3 minimumCorner = centerOfRotation - glm::vec3(radius, radius, radius);
|
||||||
|
|
||||||
_maxAACube = AACube(minimumCorner, radius * 2.0f);
|
_maxAACube = AACube(minimumCorner, radius * 2.0f);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1635,6 +1628,8 @@ void EntityItem::updateDimensions(const glm::vec3& value) {
|
||||||
if (getDimensions() != value) {
|
if (getDimensions() != value) {
|
||||||
setDimensions(value);
|
setDimensions(value);
|
||||||
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
||||||
|
_queryAACubeSet = false;
|
||||||
|
dimensionsChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2157,12 +2157,17 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityItemProperties::parentDependentPropertyChanged() const {
|
bool EntityItemProperties::transformChanged() const {
|
||||||
return localPositionChanged() || positionChanged() ||
|
return positionChanged() || rotationChanged() ||
|
||||||
localRotationChanged() || rotationChanged() ||
|
localPositionChanged() || localRotationChanged();
|
||||||
localVelocityChanged() || localAngularVelocityChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityItemProperties::parentRelatedPropertyChanged() const {
|
bool EntityItemProperties::parentRelatedPropertyChanged() const {
|
||||||
return parentDependentPropertyChanged() || parentIDChanged() || parentJointIndexChanged();
|
return positionChanged() || rotationChanged() ||
|
||||||
|
localPositionChanged() || localRotationChanged() ||
|
||||||
|
parentIDChanged() || parentJointIndexChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntityItemProperties::queryAACubeRelatedPropertyChanged() const {
|
||||||
|
return parentRelatedPropertyChanged() || dimensionsChanged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,8 +86,9 @@ public:
|
||||||
|
|
||||||
EntityPropertyFlags getChangedProperties() const;
|
EntityPropertyFlags getChangedProperties() const;
|
||||||
|
|
||||||
bool parentDependentPropertyChanged() const; // was there a changed in a property that requires parent info to interpret?
|
bool transformChanged() const;
|
||||||
bool parentRelatedPropertyChanged() const; // parentDependentPropertyChanged or parentID or parentJointIndex
|
bool parentRelatedPropertyChanged() const;
|
||||||
|
bool queryAACubeRelatedPropertyChanged() const;
|
||||||
|
|
||||||
AABox getAABox() const;
|
AABox getAABox() const;
|
||||||
|
|
||||||
|
|
|
@ -221,7 +221,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
|
||||||
_entityTree->withWriteLock([&] {
|
_entityTree->withWriteLock([&] {
|
||||||
EntityItemPointer entity = _entityTree->addEntity(id, propertiesWithSimID);
|
EntityItemPointer entity = _entityTree->addEntity(id, propertiesWithSimID);
|
||||||
if (entity) {
|
if (entity) {
|
||||||
if (propertiesWithSimID.parentRelatedPropertyChanged()) {
|
if (propertiesWithSimID.queryAACubeRelatedPropertyChanged()) {
|
||||||
// due to parenting, the server may not know where something is in world-space, so include the bounding cube.
|
// due to parenting, the server may not know where something is in world-space, so include the bounding cube.
|
||||||
bool success;
|
bool success;
|
||||||
AACube queryAACube = entity->getQueryAACube(success);
|
AACube queryAACube = entity->getQueryAACube(success);
|
||||||
|
@ -435,7 +435,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
||||||
entity->rememberHasSimulationOwnershipBid();
|
entity->rememberHasSimulationOwnershipBid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (properties.parentRelatedPropertyChanged() && entity->computePuffedQueryAACube()) {
|
if (properties.queryAACubeRelatedPropertyChanged()) {
|
||||||
properties.setQueryAACube(entity->getQueryAACube());
|
properties.setQueryAACube(entity->getQueryAACube());
|
||||||
}
|
}
|
||||||
entity->setLastBroadcast(usecTimestampNow());
|
entity->setLastBroadcast(usecTimestampNow());
|
||||||
|
@ -445,7 +445,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
||||||
// if they've changed.
|
// if they've changed.
|
||||||
entity->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
entity->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
||||||
if (descendant->getNestableType() == NestableType::Entity) {
|
if (descendant->getNestableType() == NestableType::Entity) {
|
||||||
if (descendant->computePuffedQueryAACube()) {
|
if (descendant->checkAndMaybeUpdateQueryAACube()) {
|
||||||
EntityItemPointer entityDescendant = std::static_pointer_cast<EntityItem>(descendant);
|
EntityItemPointer entityDescendant = std::static_pointer_cast<EntityItem>(descendant);
|
||||||
EntityItemProperties newQueryCubeProperties;
|
EntityItemProperties newQueryCubeProperties;
|
||||||
newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube());
|
newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube());
|
||||||
|
|
|
@ -1675,6 +1675,7 @@ QVector<EntityItemID> EntityTree::sendEntities(EntityEditPacketSender* packetSen
|
||||||
addToNeedsParentFixupList(entity);
|
addToNeedsParentFixupList(entity);
|
||||||
}
|
}
|
||||||
entity->forceQueryAACubeUpdate();
|
entity->forceQueryAACubeUpdate();
|
||||||
|
entity->checkAndMaybeUpdateQueryAACube();
|
||||||
moveOperator.addEntityToMoveList(entity, entity->getQueryAACube());
|
moveOperator.addEntityToMoveList(entity, entity->getQueryAACube());
|
||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1693,7 +1694,7 @@ QVector<EntityItemID> EntityTree::sendEntities(EntityEditPacketSender* packetSen
|
||||||
EntityItemPointer entity = localTree->findEntityByEntityItemID(newID);
|
EntityItemPointer entity = localTree->findEntityByEntityItemID(newID);
|
||||||
if (entity) {
|
if (entity) {
|
||||||
// queue the packet to send to the server
|
// queue the packet to send to the server
|
||||||
entity->computePuffedQueryAACube();
|
entity->updateQueryAACube();
|
||||||
EntityItemProperties properties = entity->getProperties();
|
EntityItemProperties properties = entity->getProperties();
|
||||||
properties.markAllChanged(); // so the entire property set is considered new, since we're making a new entity
|
properties.markAllChanged(); // so the entire property set is considered new, since we're making a new entity
|
||||||
packetSender->queueEditEntityMessage(PacketType::EntityAdd, localTree, newID, properties);
|
packetSender->queueEditEntityMessage(PacketType::EntityAdd, localTree, newID, properties);
|
||||||
|
|
|
@ -136,7 +136,7 @@ void SimpleEntitySimulation::sortEntitiesThatMoved() {
|
||||||
SetOfEntities::iterator itemItr = _entitiesToSort.begin();
|
SetOfEntities::iterator itemItr = _entitiesToSort.begin();
|
||||||
while (itemItr != _entitiesToSort.end()) {
|
while (itemItr != _entitiesToSort.end()) {
|
||||||
EntityItemPointer entity = *itemItr;
|
EntityItemPointer entity = *itemItr;
|
||||||
entity->computePuffedQueryAACube();
|
entity->checkAndMaybeUpdateQueryAACube();
|
||||||
++itemItr;
|
++itemItr;
|
||||||
}
|
}
|
||||||
EntitySimulation::sortEntitiesThatMoved();
|
EntitySimulation::sortEntitiesThatMoved();
|
||||||
|
|
|
@ -484,11 +484,7 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_entity->dynamicDataNeedsTransmit()) {
|
if (_entity->dynamicDataNeedsTransmit() || _entity->queryAACubeNeedsUpdate()) {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_entity->queryAABoxNeedsUpdate()) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,9 +573,11 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
||||||
properties.setActionData(_serverActionData);
|
properties.setActionData(_serverActionData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties.parentRelatedPropertyChanged() && _entity->computePuffedQueryAACube()) {
|
if (properties.transformChanged()) {
|
||||||
// due to parenting, the server may not know where something is in world-space, so include the bounding cube.
|
if (_entity->checkAndMaybeUpdateQueryAACube()) {
|
||||||
properties.setQueryAACube(_entity->getQueryAACube());
|
// due to parenting, the server may not know where something is in world-space, so include the bounding cube.
|
||||||
|
properties.setQueryAACube(_entity->getQueryAACube());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the LastEdited of the properties but NOT the entity itself
|
// set the LastEdited of the properties but NOT the entity itself
|
||||||
|
@ -643,7 +641,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
||||||
_entity->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
_entity->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
||||||
if (descendant->getNestableType() == NestableType::Entity) {
|
if (descendant->getNestableType() == NestableType::Entity) {
|
||||||
EntityItemPointer entityDescendant = std::static_pointer_cast<EntityItem>(descendant);
|
EntityItemPointer entityDescendant = std::static_pointer_cast<EntityItem>(descendant);
|
||||||
if (descendant->computePuffedQueryAACube()) {
|
if (descendant->checkAndMaybeUpdateQueryAACube()) {
|
||||||
EntityItemProperties newQueryCubeProperties;
|
EntityItemProperties newQueryCubeProperties;
|
||||||
newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube());
|
newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube());
|
||||||
newQueryCubeProperties.setLastEdited(properties.getLastEdited());
|
newQueryCubeProperties.setLastEdited(properties.getLastEdited());
|
||||||
|
|
|
@ -946,11 +946,35 @@ AACube SpatiallyNestable::getMaximumAACube(bool& success) const {
|
||||||
return AACube(getPosition(success) - glm::vec3(defaultAACubeSize / 2.0f), defaultAACubeSize);
|
return AACube(getPosition(success) - glm::vec3(defaultAACubeSize / 2.0f), defaultAACubeSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpatiallyNestable::checkAndAdjustQueryAACube() {
|
const float PARENTED_EXPANSION_FACTOR = 3.0f;
|
||||||
bool success;
|
|
||||||
|
bool SpatiallyNestable::checkAndMaybeUpdateQueryAACube() {
|
||||||
|
bool success = false;
|
||||||
AACube maxAACube = getMaximumAACube(success);
|
AACube maxAACube = getMaximumAACube(success);
|
||||||
if (success && (!_queryAACubeSet || !_queryAACube.contains(maxAACube))) {
|
if (success) {
|
||||||
setQueryAACube(maxAACube);
|
// maybe update _queryAACube
|
||||||
|
if (!_queryAACubeSet || (_parentID.isNull() && _children.size() == 0) || !_queryAACube.contains(maxAACube)) {
|
||||||
|
if (_parentJointIndex != INVALID_JOINT_INDEX || _children.size() > 0 ) {
|
||||||
|
// make an expanded AACube centered on the object
|
||||||
|
float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale();
|
||||||
|
_queryAACube = AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale);
|
||||||
|
} else {
|
||||||
|
_queryAACube = maxAACube;
|
||||||
|
}
|
||||||
|
|
||||||
|
getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
||||||
|
bool childSuccess;
|
||||||
|
AACube descendantAACube = descendant->getQueryAACube(childSuccess);
|
||||||
|
if (childSuccess) {
|
||||||
|
if (_queryAACube.contains(descendantAACube)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_queryAACube += descendantAACube.getMinimumPoint();
|
||||||
|
_queryAACube += descendantAACube.getMaximumPoint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_queryAACubeSet = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -961,46 +985,34 @@ void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_queryAACube = queryAACube;
|
_queryAACube = queryAACube;
|
||||||
if (queryAACube.getScale() > 0.0f) {
|
_queryAACubeSet = true;
|
||||||
_queryAACubeSet = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpatiallyNestable::queryAABoxNeedsUpdate() const {
|
bool SpatiallyNestable::queryAACubeNeedsUpdate() const {
|
||||||
bool success;
|
if (!_queryAACubeSet) {
|
||||||
AACube currentAACube = getMaximumAACube(success);
|
return true;
|
||||||
if (!success) {
|
|
||||||
qCDebug(shared) << "can't getMaximumAACube for" << getID();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure children are still in their boxes, also.
|
// make sure children are still in their boxes, also.
|
||||||
bool childNeedsUpdate = false;
|
bool childNeedsUpdate = false;
|
||||||
getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
||||||
if (!childNeedsUpdate && descendant->queryAABoxNeedsUpdate()) {
|
if (!childNeedsUpdate && descendant->queryAACubeNeedsUpdate()) {
|
||||||
childNeedsUpdate = true;
|
childNeedsUpdate = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (childNeedsUpdate) {
|
return childNeedsUpdate;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_queryAACubeSet && _queryAACube.contains(currentAACube)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpatiallyNestable::computePuffedQueryAACube() {
|
void SpatiallyNestable::updateQueryAACube() {
|
||||||
if (!queryAABoxNeedsUpdate()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool success;
|
bool success;
|
||||||
AACube currentAACube = getMaximumAACube(success);
|
AACube maxAACube = getMaximumAACube(success);
|
||||||
// make an AACube with edges thrice as long and centered on the object
|
if (_parentJointIndex != INVALID_JOINT_INDEX || _children.size() > 0 ) {
|
||||||
_queryAACube = AACube(currentAACube.getCorner() - glm::vec3(currentAACube.getScale()), currentAACube.getScale() * 3.0f);
|
// make an expanded AACube centered on the object
|
||||||
_queryAACubeSet = true;
|
float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale();
|
||||||
|
_queryAACube = AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale);
|
||||||
|
} else {
|
||||||
|
_queryAACube = maxAACube;
|
||||||
|
}
|
||||||
|
|
||||||
getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
||||||
bool success;
|
bool success;
|
||||||
|
@ -1013,8 +1025,7 @@ bool SpatiallyNestable::computePuffedQueryAACube() {
|
||||||
_queryAACube += descendantAACube.getMaximumPoint();
|
_queryAACube += descendantAACube.getMaximumPoint();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_queryAACubeSet = true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AACube SpatiallyNestable::getQueryAACube(bool& success) const {
|
AACube SpatiallyNestable::getQueryAACube(bool& success) const {
|
||||||
|
|
|
@ -102,11 +102,11 @@ public:
|
||||||
virtual glm::vec3 getParentAngularVelocity(bool& success) const;
|
virtual glm::vec3 getParentAngularVelocity(bool& success) const;
|
||||||
|
|
||||||
virtual AACube getMaximumAACube(bool& success) const;
|
virtual AACube getMaximumAACube(bool& success) const;
|
||||||
virtual bool checkAndAdjustQueryAACube();
|
bool checkAndMaybeUpdateQueryAACube();
|
||||||
virtual bool computePuffedQueryAACube();
|
void updateQueryAACube();
|
||||||
|
|
||||||
virtual void setQueryAACube(const AACube& queryAACube);
|
virtual void setQueryAACube(const AACube& queryAACube);
|
||||||
virtual bool queryAABoxNeedsUpdate() const;
|
virtual bool queryAACubeNeedsUpdate() const;
|
||||||
void forceQueryAACubeUpdate() { _queryAACubeSet = false; }
|
void forceQueryAACubeUpdate() { _queryAACubeSet = false; }
|
||||||
virtual AACube getQueryAACube(bool& success) const;
|
virtual AACube getQueryAACube(bool& success) const;
|
||||||
virtual AACube getQueryAACube() const;
|
virtual AACube getQueryAACube() const;
|
||||||
|
@ -197,7 +197,7 @@ protected:
|
||||||
mutable QHash<QUuid, SpatiallyNestableWeakPointer> _children;
|
mutable QHash<QUuid, SpatiallyNestableWeakPointer> _children;
|
||||||
|
|
||||||
virtual void locationChanged(bool tellPhysics = true); // called when a this object's location has changed
|
virtual void locationChanged(bool tellPhysics = true); // called when a this object's location has changed
|
||||||
virtual void dimensionsChanged() { } // called when a this object's dimensions have changed
|
virtual void dimensionsChanged() { _queryAACubeSet = false; } // called when a this object's dimensions have changed
|
||||||
virtual void parentDeleted() { } // called on children of a deleted parent
|
virtual void parentDeleted() { } // called on children of a deleted parent
|
||||||
|
|
||||||
// _queryAACube is used to decide where something lives in the octree
|
// _queryAACube is used to decide where something lives in the octree
|
||||||
|
|
|
@ -31,12 +31,34 @@ namespace Cursor {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static QMap<uint16_t, QString> ICONS;
|
QMap<uint16_t, QString> Manager::ICON_NAMES {
|
||||||
|
{ Icon::SYSTEM, "SYSTEM", },
|
||||||
|
{ Icon::DEFAULT, "DEFAULT", },
|
||||||
|
{ Icon::LINK, "LINK", },
|
||||||
|
{ Icon::ARROW, "ARROW", },
|
||||||
|
{ Icon::RETICLE, "RETICLE", },
|
||||||
|
};
|
||||||
|
QMap<uint16_t, QString> Manager::ICONS;
|
||||||
static uint16_t _customIconId = Icon::USER_BASE;
|
static uint16_t _customIconId = Icon::USER_BASE;
|
||||||
|
|
||||||
Manager::Manager() {
|
Manager::Manager() {
|
||||||
ICONS[Icon::DEFAULT] = PathUtils::resourcesPath() + "images/arrow.png";
|
ICONS[Icon::SYSTEM] = PathUtils::resourcesPath() + "images/cursor-none.png";
|
||||||
ICONS[Icon::LINK] = PathUtils::resourcesPath() + "images/link.png";
|
ICONS[Icon::DEFAULT] = PathUtils::resourcesPath() + "images/cursor-arrow.png";
|
||||||
|
ICONS[Icon::LINK] = PathUtils::resourcesPath() + "images/cursor-link.png";
|
||||||
|
ICONS[Icon::ARROW] = PathUtils::resourcesPath() + "images/cursor-arrow.png";
|
||||||
|
ICONS[Icon::RETICLE] = PathUtils::resourcesPath() + "images/cursor-reticle.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
Icon Manager::lookupIcon(const QString& name) {
|
||||||
|
for (const auto& kv : ICON_NAMES.toStdMap()) {
|
||||||
|
if (kv.second == name) {
|
||||||
|
return static_cast<Icon>(kv.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Icon::DEFAULT;
|
||||||
|
}
|
||||||
|
const QString& Manager::getIconName(const Icon& icon) {
|
||||||
|
return ICON_NAMES.count(icon) ? ICON_NAMES[icon] : ICON_NAMES[Icon::DEFAULT];
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager& Manager::instance() {
|
Manager& Manager::instance() {
|
||||||
|
|
|
@ -18,16 +18,18 @@ namespace Cursor {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Icon {
|
enum Icon {
|
||||||
|
SYSTEM,
|
||||||
DEFAULT,
|
DEFAULT,
|
||||||
LINK,
|
LINK,
|
||||||
GRAB,
|
GRAB,
|
||||||
|
ARROW,
|
||||||
|
RETICLE,
|
||||||
|
|
||||||
// Add new system cursors here
|
// Add new system cursors here
|
||||||
|
|
||||||
// User cursors will have ids over this value
|
// User cursors will have ids over this value
|
||||||
USER_BASE = 0xFF,
|
USER_BASE = 0xFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Instance {
|
class Instance {
|
||||||
public:
|
public:
|
||||||
virtual Source getType() const = 0;
|
virtual Source getType() const = 0;
|
||||||
|
@ -49,6 +51,11 @@ namespace Cursor {
|
||||||
uint16_t registerIcon(const QString& path);
|
uint16_t registerIcon(const QString& path);
|
||||||
QList<uint16_t> registeredIcons() const;
|
QList<uint16_t> registeredIcons() const;
|
||||||
const QString& getIconImage(uint16_t icon);
|
const QString& getIconImage(uint16_t icon);
|
||||||
|
|
||||||
|
static QMap<uint16_t, QString> ICONS;
|
||||||
|
static QMap<uint16_t, QString> ICON_NAMES;
|
||||||
|
static Icon lookupIcon(const QString& name);
|
||||||
|
static const QString& getIconName(const Icon& icon);
|
||||||
private:
|
private:
|
||||||
float _scale{ 1.0f };
|
float _scale{ 1.0f };
|
||||||
};
|
};
|
||||||
|
|
|
@ -126,15 +126,17 @@ void OculusBaseDisplayPlugin::internalDeactivate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OculusBaseDisplayPlugin::activateStandBySession() {
|
bool OculusBaseDisplayPlugin::activateStandBySession() {
|
||||||
_session = acquireOculusSession();
|
|
||||||
if (!_session) {
|
if (!_session) {
|
||||||
return false;
|
_session = acquireOculusSession();
|
||||||
}
|
}
|
||||||
return true;
|
return _session;
|
||||||
}
|
}
|
||||||
void OculusBaseDisplayPlugin::deactivateSession() {
|
void OculusBaseDisplayPlugin::deactivateSession() {
|
||||||
releaseOculusSession();
|
// FIXME
|
||||||
_session = nullptr;
|
// Switching to Qt 5.9 exposed a race condition or similar issue that caused a crash when putting on an Rift
|
||||||
|
// while already in VR mode. Commenting these out is a workaround.
|
||||||
|
//releaseOculusSession();
|
||||||
|
//_session = nullptr;
|
||||||
}
|
}
|
||||||
void OculusBaseDisplayPlugin::updatePresentPose() {
|
void OculusBaseDisplayPlugin::updatePresentPose() {
|
||||||
//mat4 sensorResetMat;
|
//mat4 sensorResetMat;
|
||||||
|
|
Loading…
Reference in a new issue