mirror of
https://github.com/lubosz/overte.git
synced 2025-04-12 01:22:10 +02:00
Merge with master
This commit is contained in:
commit
a678a38211
30 changed files with 415 additions and 147 deletions
|
@ -1,4 +1,4 @@
|
|||
# If we're running under the gradle build, HIFI_ANDROID will be set here, but
|
||||
# If we're running under the gradle build, HIFI_ANDROID will be set here, but
|
||||
# ANDROID will not be set until after the `project` statement. This is the *ONLY*
|
||||
# place you need to use `HIFI_ANDROID` instead of `ANDROID`
|
||||
if (WIN32 AND NOT HIFI_ANDROID)
|
||||
|
@ -61,8 +61,6 @@ else()
|
|||
endif()
|
||||
option(DISABLE_KTX_CACHE "Disable KTX Cache" OFF)
|
||||
|
||||
|
||||
|
||||
set(PLATFORM_QT_GL OpenGL)
|
||||
|
||||
if (USE_GLES)
|
||||
|
@ -132,8 +130,8 @@ set_packaging_parameters()
|
|||
|
||||
# FIXME hack to work on the proper Android toolchain
|
||||
if (ANDROID)
|
||||
add_subdirectory(android/app)
|
||||
return()
|
||||
add_subdirectory(android/app)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# add subdirectories for all targets
|
||||
|
@ -148,16 +146,14 @@ if (BUILD_SERVER)
|
|||
endif()
|
||||
|
||||
if (BUILD_CLIENT)
|
||||
add_subdirectory(interface)
|
||||
set_target_properties(interface PROPERTIES FOLDER "Apps")
|
||||
if (ANDROID)
|
||||
add_subdirectory(gvr-interface)
|
||||
set_target_properties(gvr-interface PROPERTIES FOLDER "Apps")
|
||||
endif()
|
||||
add_subdirectory(interface)
|
||||
set_target_properties(interface PROPERTIES FOLDER "Apps")
|
||||
|
||||
option(USE_SIXENSE "Build Interface with sixense library/plugin" OFF)
|
||||
endif()
|
||||
|
||||
if (BUILD_CLIENT OR BUILD_SERVER)
|
||||
add_subdirectory(plugins)
|
||||
add_subdirectory(plugins)
|
||||
endif()
|
||||
|
||||
# BUILD_TOOLS option will be handled inside the tools's CMakeLists.txt because 'scribe' tool is required for build anyway
|
||||
|
|
|
@ -17,6 +17,8 @@ To produce an executable installer on Windows, the following are required:
|
|||
- [Nullsoft Scriptable Install System](http://nsis.sourceforge.net/Download) - 3.0b3
|
||||
- [UAC Plug-in for Nullsoft](http://nsis.sourceforge.net/UAC_plug-in) - 0.2.4c
|
||||
- [nsProcess Plug-in for Nullsoft](http://nsis.sourceforge.net/NsProcess_plugin) - 1.6
|
||||
- [Inetc Plug-in for Nullsoft](http://nsis.sourceforge.net/Inetc_plug-in) - 1.0
|
||||
- [NSISpcre Plug-in for Nullsoft](http://nsis.sourceforge.net/NSISpcre_plug-in) - 1.0
|
||||
|
||||
Run the `package` target to create an executable installer using the Nullsoft Scriptable Install System.
|
||||
|
||||
|
|
2
cmake/externals/quazip/CMakeLists.txt
vendored
2
cmake/externals/quazip/CMakeLists.txt
vendored
|
@ -4,7 +4,7 @@ cmake_policy(SET CMP0046 OLD)
|
|||
|
||||
include(ExternalProject)
|
||||
|
||||
set(QUAZIP_CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_NAME_DIR:PATH=<INSTALL_DIR>/lib -DZLIB_ROOT=${ZLIB_ROOT} -DCMAKE_POSITION_INDEPENDENT_CODE=ON)
|
||||
set(QUAZIP_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_NAME_DIR:PATH=<INSTALL_DIR>/lib -DZLIB_ROOT=${ZLIB_ROOT} -DCMAKE_POSITION_INDEPENDENT_CODE=ON)
|
||||
|
||||
if (APPLE)
|
||||
else ()
|
||||
|
|
|
@ -46,9 +46,18 @@ macro(GENERATE_INSTALLERS)
|
|||
set(UNINSTALLER_HEADER_IMAGE "")
|
||||
fix_path_for_nsis(${_UNINSTALLER_HEADER_BAD_PATH} UNINSTALLER_HEADER_IMAGE)
|
||||
|
||||
# grab the latest VC redist (2017) and add it to the installer, our NSIS template
|
||||
# will call it during the install
|
||||
install(CODE "file(DOWNLOAD https://go.microsoft.com/fwlink/?LinkId=746572 \"\${CMAKE_INSTALL_PREFIX}/vcredist_x64.exe\")")
|
||||
# we use external libraries that still need the 120 (VS2013) redistributables
|
||||
# so we include them as well until those external libraries are updated
|
||||
# to use the redistributables that match what we build our applications for
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
|
||||
"C:/Windows/System32/msvcp120.dll"
|
||||
"C:/Windows/System32/msvcr120.dll"
|
||||
)
|
||||
|
||||
set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ${INTERFACE_INSTALL_DIR})
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT ${CLIENT_COMPONENT})
|
||||
include(InstallRequiredSystemLibraries)
|
||||
elseif (APPLE)
|
||||
# produce a drag and drop DMG on OS X
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
|
|
|
@ -39,7 +39,9 @@ macro(PACKAGE_LIBRARIES_FOR_DEPLOYMENT)
|
|||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
POST_BUILD
|
||||
COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND} ${EXTRA_DEPLOY_OPTIONS} $<$<OR:$<CONFIG:Release>,$<CONFIG:MinSizeRel>,$<CONFIG:RelWithDebInfo>>:--release> \"$<TARGET_FILE:${TARGET_NAME}>\""
|
||||
COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND}\
|
||||
${EXTRA_DEPLOY_OPTIONS} $<$<OR:$<CONFIG:Release>,$<CONFIG:MinSizeRel>,$<CONFIG:RelWithDebInfo>>:--release>\
|
||||
--no-compiler-runtime --no-opengl-sw --no-angle -no-system-d3d-compiler \"$<TARGET_FILE:${TARGET_NAME}>\""
|
||||
)
|
||||
|
||||
set(QTAUDIO_PATH "$<TARGET_FILE_DIR:${TARGET_NAME}>/audio")
|
||||
|
|
|
@ -149,6 +149,8 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set(CLIENT_LAUNCH_NOW_REG_KEY "ClientLaunchAfterInstall")
|
||||
set(SERVER_LAUNCH_NOW_REG_KEY "ServerLaunchAfterInstall")
|
||||
set(CUSTOM_INSTALL_REG_KEY "CustomInstall")
|
||||
set(CLIENT_ID_REG_KEY "ClientGUID")
|
||||
set(GA_TRACKING_ID $ENV{GA_TRACKING_ID})
|
||||
endif ()
|
||||
|
||||
# setup component categories for installer
|
||||
|
|
|
@ -41,6 +41,8 @@ set(CONSOLE_STARTUP_REG_KEY "@CONSOLE_STARTUP_REG_KEY@")
|
|||
set(SERVER_LAUNCH_NOW_REG_KEY "@SERVER_LAUNCH_NOW_REG_KEY@")
|
||||
set(CLIENT_LAUNCH_NOW_REG_KEY "@CLIENT_LAUNCH_NOW_REG_KEY@")
|
||||
set(CUSTOM_INSTALL_REG_KEY "@CUSTOM_INSTALL_REG_KEY@")
|
||||
set(GA_TRACKING_ID "@GA_TRACKING_ID@")
|
||||
set(CLIENT_ID_REG_KEY "@CLIENT_ID_REG_KEY@")
|
||||
set(INSTALLER_HEADER_IMAGE "@INSTALLER_HEADER_IMAGE@")
|
||||
set(UNINSTALLER_HEADER_IMAGE "@UNINSTALLER_HEADER_IMAGE@")
|
||||
set(ADD_REMOVE_ICON_PATH "@ADD_REMOVE_ICON_PATH@")
|
||||
|
|
|
@ -319,6 +319,78 @@ Function DownloadFile
|
|||
FunctionEnd
|
||||
!endif
|
||||
|
||||
|
||||
!include NSISpcre.nsh
|
||||
!insertmacro REMatches
|
||||
|
||||
Var CampaignName
|
||||
|
||||
!macro GetCampaignName RetVar
|
||||
Call GetCampaignName
|
||||
Pop ${RetVar}
|
||||
!macroend
|
||||
|
||||
Function GetCampaignName
|
||||
Push $0 ; Stash $0
|
||||
|
||||
; Parse filename out of the path
|
||||
${RECaptureMatches} $0 "([^\\]*\\)*(.*)\.exe" $EXEPATH 0
|
||||
${If} $0 == 2
|
||||
Pop $0 ; Discard Path
|
||||
Pop $0 ; Recover filename
|
||||
; Parse campaign out of the filename
|
||||
${RECaptureMatches} $0 "HighFidelity-([^-]*-)Beta-.*" $0 0
|
||||
${If} $0 == 1
|
||||
Pop $0 ; Recover campaign name
|
||||
StrCpy $0 $0 -1 0 ; Remove trailing - and copy to _RetVar
|
||||
${Else}
|
||||
StrCpy $0 ""
|
||||
${EndIf}
|
||||
${Else}
|
||||
StrCpy $0 ""
|
||||
${EndIf}
|
||||
|
||||
Exch $0 ; Restore $0 and push result
|
||||
FunctionEnd
|
||||
|
||||
!macro CreateGUID RetVar
|
||||
System::Call 'ole32::CoCreateGuid(g .s)'
|
||||
Pop ${RetVar}
|
||||
; Strip opening and closing braces
|
||||
StrCpy ${RetVar} ${RetVar} -1 1
|
||||
!macroend
|
||||
|
||||
Var GAClientID
|
||||
|
||||
!macro InitGAClientID
|
||||
; Generate a new GUID on every run for now
|
||||
!insertmacro CreateGUID $GAClientID
|
||||
!macroend
|
||||
|
||||
!macro GoogleAnalytics Category Action Label Value
|
||||
${If} "@GA_TRACKING_ID@" != ""
|
||||
Push $0
|
||||
Push $1
|
||||
|
||||
StrCpy $0 "https://google-analytics.com/collect?v=1&tid=@GA_TRACKING_ID@"
|
||||
StrCpy $0 "$0&cid=$GAClientID&t=event&ec=${Category}&ea=${Action}"
|
||||
|
||||
${If} "${Label}" != ""
|
||||
StrCpy $0 "$0&el=${Label}"
|
||||
${EndIf}
|
||||
${If} "${Value}" != ""
|
||||
StrCpy $0 "$0&ev=${Value}"
|
||||
${EndIf}
|
||||
|
||||
GetTempFileName $1
|
||||
inetc::get /SILENT $0 $1 /END
|
||||
Delete $1
|
||||
|
||||
Pop $1
|
||||
Pop $0
|
||||
${EndIf}
|
||||
!macroend
|
||||
|
||||
;--------------------------------
|
||||
; Installation types
|
||||
|
||||
|
@ -342,28 +414,32 @@ SectionEnd
|
|||
|
||||
;--------------------------------
|
||||
;Pages
|
||||
!define MUI_CUSTOMFUNCTION_ABORT OnUserAbort
|
||||
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE PageWelcomePre
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE PageLicensePre
|
||||
!insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@"
|
||||
|
||||
Page custom InstallTypesPage ReadInstallTypes
|
||||
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE AbortFunction
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE PageDirectoryPre
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
|
||||
;Start Menu Folder Page Configuration
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
|
||||
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE AbortFunction
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE PageStartMenuPre
|
||||
!insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER
|
||||
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE AbortFunction
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE PageComponentsPre
|
||||
@CPACK_NSIS_PAGE_COMPONENTS@
|
||||
|
||||
Page custom PostInstallOptionsPage ReadPostInstallOptions
|
||||
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE PageInstallFilesPre
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
|
@ -452,8 +528,40 @@ Var CopyFromProductionCheckbox
|
|||
Var ExpressInstallRadioButton
|
||||
Var CustomInstallRadioButton
|
||||
Var InstallTypeDialog
|
||||
Var Express
|
||||
Var CustomInstallTemporaryState
|
||||
Var Express
|
||||
|
||||
!macro MaybeSkipPage
|
||||
; Check if Express is set, if so, abort the post install options page
|
||||
${If} $Express == "1"
|
||||
Abort
|
||||
${EndIf}
|
||||
!macroend
|
||||
|
||||
Function OnUserAbort
|
||||
!insertmacro GoogleAnalytics "Installer" "Abort" "User Abort" ""
|
||||
FunctionEnd
|
||||
Function PageWelcomePre
|
||||
!insertmacro GoogleAnalytics "Installer" "Welcome" "" ""
|
||||
FunctionEnd
|
||||
Function PageLicensePre
|
||||
!insertmacro GoogleAnalytics "Installer" "License" "" ""
|
||||
FunctionEnd
|
||||
Function PageDirectoryPre
|
||||
!insertmacro MaybeSkipPage
|
||||
!insertmacro GoogleAnalytics "Installer" "Directory" "" ""
|
||||
FunctionEnd
|
||||
Function PageStartMenuPre
|
||||
!insertmacro MaybeSkipPage
|
||||
!insertmacro GoogleAnalytics "Installer" "StartMenu" "" ""
|
||||
FunctionEnd
|
||||
Function PageComponentsPre
|
||||
!insertmacro MaybeSkipPage
|
||||
!insertmacro GoogleAnalytics "Installer" "Components" "" ""
|
||||
FunctionEnd
|
||||
Function PageInstallFilesPre
|
||||
!insertmacro GoogleAnalytics "Installer" "Install" "" ""
|
||||
FunctionEnd
|
||||
|
||||
!macro SetInstallOption Checkbox OptionName Default
|
||||
; reads the value for the given install option to the registry
|
||||
|
@ -472,6 +580,8 @@ Var CustomInstallTemporaryState
|
|||
!macroend
|
||||
|
||||
Function InstallTypesPage
|
||||
!insertmacro GoogleAnalytics "Installer" "Install Types" "" ""
|
||||
|
||||
!insertmacro MUI_HEADER_TEXT "Choose Installation Type" "Express or Custom Install"
|
||||
|
||||
nsDialogs::Create 1018
|
||||
|
@ -523,14 +633,10 @@ Function ChangeCustomLabel
|
|||
Pop $R1
|
||||
FunctionEnd
|
||||
|
||||
Function AbortFunction
|
||||
; Check if Express is set, if so, abort the post install options page
|
||||
StrCmp $Express "1" 0 end
|
||||
Abort
|
||||
end:
|
||||
FunctionEnd
|
||||
|
||||
Function PostInstallOptionsPage
|
||||
!insertmacro MaybeSkipPage
|
||||
!insertmacro GoogleAnalytics "Installer" "Post Install Options" "" ""
|
||||
|
||||
!insertmacro MUI_HEADER_TEXT "Setup Options" ""
|
||||
|
||||
nsDialogs::Create 1018
|
||||
|
@ -540,11 +646,6 @@ Function PostInstallOptionsPage
|
|||
Abort
|
||||
${EndIf}
|
||||
|
||||
; Check if Express is set, if so, abort the post install options page
|
||||
StrCmp $Express "1" 0 end
|
||||
Abort
|
||||
end:
|
||||
|
||||
StrCpy $CurrentOffset 0
|
||||
StrCpy $OffsetUnits u
|
||||
|
||||
|
@ -837,9 +938,6 @@ Section "-Core installation"
|
|||
Delete "$INSTDIR\ui_resources_200_percent.pak"
|
||||
Delete "$INSTDIR\vccorlib120.dll"
|
||||
Delete "$INSTDIR\version"
|
||||
Delete "$INSTDIR\msvcr140.dll"
|
||||
Delete "$INSTDIR\msvcp140.dll"
|
||||
Delete "$INSTDIR\vcruntime140.dll"
|
||||
Delete "$INSTDIR\xinput1_3.dll"
|
||||
|
||||
; Delete old desktop shortcuts before they were renamed during Sandbox rename
|
||||
|
@ -858,11 +956,8 @@ Section "-Core installation"
|
|||
; Rename the incorrectly cased Raleway font
|
||||
Rename "$INSTDIR\resources\qml\styles-uit\RalewaySemibold.qml" "$INSTDIR\resources\qml\styles-uit\RalewaySemiBold.qml"
|
||||
|
||||
ExecWait "$INSTDIR\vcredist_x64.exe /install /q /norestart"
|
||||
|
||||
; Remove the Old Interface directory and vcredist_x64.exe (from installs prior to Server Console)
|
||||
RMDir /r "$INSTDIR\Interface"
|
||||
Delete "$INSTDIR\vcredist_x64.exe"
|
||||
|
||||
;Use the entire tree produced by the INSTALL target. Keep the
|
||||
;list of directories here in sync with the RMDir commands below.
|
||||
|
@ -965,6 +1060,7 @@ Section "-Core installation"
|
|||
; Handle whichever post install options were set
|
||||
Call HandlePostInstallOptions
|
||||
|
||||
!insertmacro GoogleAnalytics "Installer" "Done" "" ""
|
||||
SectionEnd
|
||||
|
||||
!include nsProcess.nsh
|
||||
|
@ -979,7 +1075,7 @@ SectionEnd
|
|||
${If} $R0 == 0
|
||||
|
||||
; the process is running, ask the user to close it
|
||||
|
||||
|
||||
${If} "${displayName}" == "@CONSOLE_DISPLAY_NAME@"
|
||||
MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION \
|
||||
"${displayName} cannot be ${action} while ${displayName} is running.$\r$\nPlease close it in the system tray and click Retry to continue." \
|
||||
|
@ -992,6 +1088,8 @@ SectionEnd
|
|||
/SD IDCANCEL IDRETRY Prompt_${UniqueID} IDCANCEL 0
|
||||
${EndIf}
|
||||
|
||||
!insertmacro GoogleAnalytics "Installer" "Abort" "${displayName} Running" ""
|
||||
|
||||
; If the user decided to cancel, stop the current installer/uninstaller
|
||||
Abort
|
||||
|
||||
|
@ -1219,6 +1317,11 @@ Function .onInit
|
|||
Quit
|
||||
!endif
|
||||
|
||||
!insertmacro InitGAClientID
|
||||
!insertmacro GetCampaignName $CampaignName
|
||||
|
||||
!insertmacro GoogleAnalytics "Installer" "Start" "$CampaignName" ""
|
||||
|
||||
; make sure none of the installed applications are still running
|
||||
!insertmacro CheckForRunningApplications "installed" "Installer"
|
||||
${nsProcess::Unload}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <QJsonArray>
|
||||
#include <QProcess>
|
||||
#include <QSharedMemory>
|
||||
#include <QRegularExpression>
|
||||
#include <QStandardPaths>
|
||||
#include <QTimer>
|
||||
#include <QUrlQuery>
|
||||
|
@ -727,7 +728,7 @@ void DomainServer::setupNodeListAndAssignments() {
|
|||
packetReceiver.registerListener(PacketType::OctreeDataPersist, this, "processOctreeDataPersistMessage");
|
||||
|
||||
packetReceiver.registerListener(PacketType::OctreeFileReplacement, this, "handleOctreeFileReplacementRequest");
|
||||
packetReceiver.registerListener(PacketType::OctreeFileReplacementFromUrl, this, "handleOctreeFileReplacementFromURLRequest");
|
||||
packetReceiver.registerListener(PacketType::DomainContentReplacementFromUrl, this, "handleDomainContentReplacementFromURLRequest");
|
||||
|
||||
// set a custom packetVersionMatch as the verify packet operator for the udt::Socket
|
||||
nodeList->setPacketFilterOperator(&DomainServer::isPacketVerified);
|
||||
|
@ -736,7 +737,6 @@ void DomainServer::setupNodeListAndAssignments() {
|
|||
auto assetClient = DependencyManager::set<AssetClient>();
|
||||
assetClient->moveToThread(&_assetClientThread);
|
||||
_assetClientThread.start();
|
||||
|
||||
// add whatever static assignments that have been parsed to the queue
|
||||
addStaticAssignmentsToQueue();
|
||||
}
|
||||
|
@ -2136,7 +2136,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
|||
} else if (url.path().startsWith(URI_API_BACKUPS_ID)) {
|
||||
auto id = url.path().mid(QString(URI_API_BACKUPS_ID).length());
|
||||
auto deferred = makePromise("consolidateBackup");
|
||||
deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) {
|
||||
deferred->then([connectionPtr, JSON_MIME_TYPE, id](QString error, QVariantMap result) {
|
||||
if (!connectionPtr) {
|
||||
return;
|
||||
}
|
||||
|
@ -2147,7 +2147,14 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
|||
auto path = result["backupFilePath"].toString();
|
||||
auto file { std::unique_ptr<QFile>(new QFile(path)) };
|
||||
if (file->open(QIODevice::ReadOnly)) {
|
||||
connectionPtr->respond(HTTPConnection::StatusCode200, std::move(file));
|
||||
constexpr const char* CONTENT_TYPE_ZIP = "application/zip";
|
||||
|
||||
auto downloadedFilename = id;
|
||||
downloadedFilename.replace(QRegularExpression(".zip$"), ".content.zip");
|
||||
auto contentDisposition = "attachment; filename=\"" + downloadedFilename + "\"";
|
||||
connectionPtr->respond(HTTPConnection::StatusCode200, std::move(file), CONTENT_TYPE_ZIP, {
|
||||
{ "Content-Disposition", contentDisposition.toUtf8() }
|
||||
});
|
||||
} else {
|
||||
qCritical(domain_server) << "Unable to load consolidated backup at:" << path << result;
|
||||
connectionPtr->respond(HTTPConnection::StatusCode500, "Error opening backup");
|
||||
|
@ -3429,13 +3436,10 @@ void DomainServer::handleOctreeFileReplacement(QByteArray octreeFile) {
|
|||
}
|
||||
}
|
||||
|
||||
void DomainServer::handleOctreeFileReplacementFromURLRequest(QSharedPointer<ReceivedMessage> message) {
|
||||
void DomainServer::handleDomainContentReplacementFromURLRequest(QSharedPointer<ReceivedMessage> message) {
|
||||
qInfo() << "Received request to replace content from a url";
|
||||
auto node = DependencyManager::get<LimitedNodeList>()->findNodeWithAddr(message->getSenderSockAddr());
|
||||
if (node) {
|
||||
qDebug() << "Found node: " << node->getCanReplaceContent();
|
||||
}
|
||||
if (node->getCanReplaceContent()) {
|
||||
if (node && node->getCanReplaceContent()) {
|
||||
// Convert message data into our URL
|
||||
QString url(message->getMessage());
|
||||
QUrl modelsURL = QUrl(url, QUrl::StrictMode);
|
||||
|
@ -3448,7 +3452,12 @@ void DomainServer::handleOctreeFileReplacementFromURLRequest(QSharedPointer<Rece
|
|||
connect(reply, &QNetworkReply::finished, [this, reply, modelsURL]() {
|
||||
QNetworkReply::NetworkError networkError = reply->error();
|
||||
if (networkError == QNetworkReply::NoError) {
|
||||
handleOctreeFileReplacement(reply->readAll());
|
||||
if (modelsURL.fileName().endsWith(".json.gz")) {
|
||||
handleOctreeFileReplacement(reply->readAll());
|
||||
} else if (modelsURL.fileName().endsWith(".zip")) {
|
||||
auto deferred = makePromise("recoverFromUploadedBackup");
|
||||
_contentManager->recoverFromUploadedBackup(deferred, reply->readAll());
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Error downloading JSON from specified file: " << modelsURL;
|
||||
}
|
||||
|
@ -3456,12 +3465,9 @@ void DomainServer::handleOctreeFileReplacementFromURLRequest(QSharedPointer<Rece
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void DomainServer::handleOctreeFileReplacementRequest(QSharedPointer<ReceivedMessage> message) {
|
||||
auto node = DependencyManager::get<NodeList>()->nodeWithUUID(message->getSourceID());
|
||||
if (node->getCanReplaceContent()) {
|
||||
handleOctreeFileReplacement(message->readAll());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -91,7 +91,7 @@ private slots:
|
|||
void processICEServerHeartbeatDenialPacket(QSharedPointer<ReceivedMessage> message);
|
||||
void processICEServerHeartbeatACK(QSharedPointer<ReceivedMessage> message);
|
||||
|
||||
void handleOctreeFileReplacementFromURLRequest(QSharedPointer<ReceivedMessage> message);
|
||||
void handleDomainContentReplacementFromURLRequest(QSharedPointer<ReceivedMessage> message);
|
||||
void handleOctreeFileReplacementRequest(QSharedPointer<ReceivedMessage> message);
|
||||
void handleOctreeFileReplacement(QByteArray octreeFile);
|
||||
|
||||
|
|
|
@ -191,7 +191,11 @@ add_dependencies(${TARGET_NAME} resources)
|
|||
if (WIN32)
|
||||
# These are external plugins, but we need to do the 'add dependency' here so that their
|
||||
# binary directories get added to the fixup path
|
||||
add_dependency_external_projects(sixense)
|
||||
|
||||
if (USE_SIXENSE)
|
||||
add_dependency_external_projects(sixense)
|
||||
endif ()
|
||||
|
||||
add_dependency_external_projects(sdl2)
|
||||
add_dependency_external_projects(OpenVR)
|
||||
add_dependency_external_projects(neuron)
|
||||
|
@ -327,13 +331,13 @@ if (APPLE)
|
|||
else()
|
||||
# copy the resources files beside the executable
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||
"${RESOURCES_RCC}"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||
"${RESOURCES_RCC}"
|
||||
"$<TARGET_FILE_DIR:interface>"
|
||||
# FIXME, the edit script code loads HTML from the scripts folder
|
||||
# which in turn relies on CSS that refers to the fonts. In theory
|
||||
# we should be able to modify the CSS to reference the QRC path to
|
||||
# the ttf files, but doing so generates a CORS policy violation,
|
||||
# we should be able to modify the CSS to reference the QRC path to
|
||||
# the ttf files, but doing so generates a CORS policy violation,
|
||||
# so we have to retain a copy of the fonts outside of the resources binary
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||
"${PROJECT_SOURCE_DIR}/resources/fonts"
|
||||
|
@ -388,3 +392,6 @@ endif()
|
|||
add_dependency_external_projects(GifCreator)
|
||||
find_package(GifCreator REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${GIFCREATOR_INCLUDE_DIRS})
|
||||
|
||||
# tell CMake to exclude ui_console.h for policy CMP0071
|
||||
set_property(SOURCE ui_console.h PROPERTY SKIP_AUTOMOC ON)
|
||||
|
|
|
@ -351,6 +351,7 @@ static const QString OBJ_EXTENSION = ".obj";
|
|||
static const QString AVA_JSON_EXTENSION = ".ava.json";
|
||||
static const QString WEB_VIEW_TAG = "noDownload=true";
|
||||
static const QString ZIP_EXTENSION = ".zip";
|
||||
static const QString CONTENT_ZIP_EXTENSION = ".content.zip";
|
||||
|
||||
static const float MIRROR_FULLSCREEN_DISTANCE = 0.389f;
|
||||
|
||||
|
@ -378,7 +379,7 @@ static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system";
|
|||
|
||||
static const QString DOMAIN_SPAWNING_POINT = "/0, -10, 0";
|
||||
|
||||
const QHash<QString, Application::AcceptURLMethod> Application::_acceptedExtensions {
|
||||
const std::vector<std::pair<QString, Application::AcceptURLMethod>> Application::_acceptedExtensions {
|
||||
{ SVO_EXTENSION, &Application::importSVOFromURL },
|
||||
{ SVO_JSON_EXTENSION, &Application::importSVOFromURL },
|
||||
{ AVA_JSON_EXTENSION, &Application::askToWearAvatarAttachmentUrl },
|
||||
|
@ -386,6 +387,7 @@ const QHash<QString, Application::AcceptURLMethod> Application::_acceptedExtensi
|
|||
{ JS_EXTENSION, &Application::askToLoadScript },
|
||||
{ FST_EXTENSION, &Application::askToSetAvatarUrl },
|
||||
{ JSON_GZ_EXTENSION, &Application::askToReplaceDomainContent },
|
||||
{ CONTENT_ZIP_EXTENSION, &Application::askToReplaceDomainContent },
|
||||
{ ZIP_EXTENSION, &Application::importFromZIP },
|
||||
{ JPG_EXTENSION, &Application::importImage },
|
||||
{ PNG_EXTENSION, &Application::importImage }
|
||||
|
@ -2709,6 +2711,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
|
|||
|
||||
surfaceContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor());
|
||||
|
||||
surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance());
|
||||
surfaceContext->setContextProperty("Selection", DependencyManager::get<SelectionScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("ContextOverlay", DependencyManager::get<ContextOverlayInterface>().data());
|
||||
surfaceContext->setContextProperty("Wallet", DependencyManager::get<WalletScriptingInterface>().data());
|
||||
|
@ -6185,11 +6188,9 @@ bool Application::canAcceptURL(const QString& urlString) const {
|
|||
} else if (urlString.startsWith(HIFI_URL_SCHEME)) {
|
||||
return true;
|
||||
}
|
||||
QHashIterator<QString, AcceptURLMethod> i(_acceptedExtensions);
|
||||
QString lowerPath = url.path().toLower();
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
if (lowerPath.endsWith(i.key(), Qt::CaseInsensitive)) {
|
||||
for (auto& pair : _acceptedExtensions) {
|
||||
if (lowerPath.endsWith(pair.first, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -6206,12 +6207,10 @@ bool Application::acceptURL(const QString& urlString, bool defaultUpload) {
|
|||
}
|
||||
|
||||
QUrl url(urlString);
|
||||
QHashIterator<QString, AcceptURLMethod> i(_acceptedExtensions);
|
||||
QString lowerPath = url.path().toLower();
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
if (lowerPath.endsWith(i.key(), Qt::CaseInsensitive)) {
|
||||
AcceptURLMethod method = i.value();
|
||||
for (auto& pair : _acceptedExtensions) {
|
||||
if (lowerPath.endsWith(pair.first, Qt::CaseInsensitive)) {
|
||||
AcceptURLMethod method = pair.second;
|
||||
return (this->*method)(urlString);
|
||||
}
|
||||
}
|
||||
|
@ -6398,13 +6397,11 @@ void Application::replaceDomainContent(const QString& url) {
|
|||
QByteArray urlData(url.toUtf8());
|
||||
auto limitedNodeList = DependencyManager::get<NodeList>();
|
||||
const auto& domainHandler = limitedNodeList->getDomainHandler();
|
||||
limitedNodeList->eachMatchingNode([](const SharedNodePointer& node) {
|
||||
return node->getType() == NodeType::EntityServer && node->getActiveSocket();
|
||||
}, [&urlData, limitedNodeList, &domainHandler](const SharedNodePointer& octreeNode) {
|
||||
auto octreeFilePacket = NLPacket::create(PacketType::OctreeFileReplacementFromUrl, urlData.size(), true);
|
||||
octreeFilePacket->write(urlData);
|
||||
limitedNodeList->sendPacket(std::move(octreeFilePacket), domainHandler.getSockAddr());
|
||||
});
|
||||
|
||||
auto octreeFilePacket = NLPacket::create(PacketType::DomainContentReplacementFromUrl, urlData.size(), true);
|
||||
octreeFilePacket->write(urlData);
|
||||
limitedNodeList->sendPacket(std::move(octreeFilePacket), domainHandler.getSockAddr());
|
||||
|
||||
auto addressManager = DependencyManager::get<AddressManager>();
|
||||
addressManager->handleLookupString(DOMAIN_SPAWNING_POINT);
|
||||
QString newHomeAddress = addressManager->getHost() + DOMAIN_SPAWNING_POINT;
|
||||
|
|
|
@ -605,7 +605,7 @@ private:
|
|||
GLCanvas* _glWidget{ nullptr };
|
||||
|
||||
typedef bool (Application::* AcceptURLMethod)(const QString &);
|
||||
static const QHash<QString, AcceptURLMethod> _acceptedExtensions;
|
||||
static const std::vector<std::pair<QString, Application::AcceptURLMethod>> _acceptedExtensions;
|
||||
|
||||
glm::uvec2 _renderResolution;
|
||||
|
||||
|
|
|
@ -63,6 +63,19 @@ static const float OPAQUE_ALPHA_THRESHOLD = 0.99f;
|
|||
|
||||
const QString Web3DOverlay::TYPE = "web3d";
|
||||
const QString Web3DOverlay::QML = "Web3DOverlay.qml";
|
||||
|
||||
static auto qmlSurfaceDeleter = [](OffscreenQmlSurface* surface) {
|
||||
AbstractViewStateInterface::instance()->postLambdaEvent([surface] {
|
||||
if (AbstractViewStateInterface::instance()->isAboutToQuit()) {
|
||||
// WebEngineView may run other threads (wasapi), so they must be deleted for a clean shutdown
|
||||
// if the application has already stopped its event loop, delete must be explicit
|
||||
delete surface;
|
||||
} else {
|
||||
surface->deleteLater();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Web3DOverlay::Web3DOverlay() {
|
||||
_touchDevice.setCapabilities(QTouchDevice::Position);
|
||||
_touchDevice.setType(QTouchDevice::TouchScreen);
|
||||
|
@ -75,7 +88,8 @@ Web3DOverlay::Web3DOverlay() {
|
|||
connect(this, &Web3DOverlay::resizeWebSurface, this, &Web3DOverlay::onResizeWebSurface);
|
||||
|
||||
//need to be intialized before Tablet 1st open
|
||||
_webSurface = DependencyManager::get<OffscreenQmlSurfaceCache>()->acquire(_url);
|
||||
_webSurface = DependencyManager::get<OffscreenQmlSurfaceCache>()->acquire(QML);
|
||||
_cachedWebSurface = true;
|
||||
_webSurface->getSurfaceContext()->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
|
||||
_webSurface->getSurfaceContext()->setContextProperty("GlobalServices", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
|
||||
|
@ -114,6 +128,7 @@ void Web3DOverlay::destroyWebSurface() {
|
|||
if (!_webSurface) {
|
||||
return;
|
||||
}
|
||||
|
||||
QQuickItem* rootItem = _webSurface->getRootItem();
|
||||
|
||||
if (rootItem && rootItem->objectName() == "tabletRoot") {
|
||||
|
@ -135,10 +150,15 @@ void Web3DOverlay::destroyWebSurface() {
|
|||
|
||||
QObject::disconnect(this, &Web3DOverlay::scriptEventReceived, _webSurface.data(), &OffscreenQmlSurface::emitScriptEvent);
|
||||
QObject::disconnect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived);
|
||||
auto offscreenCache = DependencyManager::get<OffscreenQmlSurfaceCache>();
|
||||
// FIXME prevents crash on shutdown, but we shoudln't have to do this check
|
||||
if (offscreenCache) {
|
||||
offscreenCache->release(QML, _webSurface);
|
||||
|
||||
// If the web surface was fetched out of the cache, release it back into the cache
|
||||
if (_cachedWebSurface) {
|
||||
auto offscreenCache = DependencyManager::get<OffscreenQmlSurfaceCache>();
|
||||
// FIXME prevents crash on shutdown, but we shoudln't have to do this check
|
||||
if (offscreenCache) {
|
||||
offscreenCache->release(QML, _webSurface);
|
||||
}
|
||||
_cachedWebSurface = false;
|
||||
}
|
||||
_webSurface.reset();
|
||||
}
|
||||
|
@ -147,6 +167,8 @@ void Web3DOverlay::buildWebSurface() {
|
|||
if (_webSurface) {
|
||||
return;
|
||||
}
|
||||
// FIXME the context save here is most likely unecessary since the QML surfaces now render
|
||||
// off the main thread, and all GL context work is done off the main thread (I *think*)
|
||||
gl::withSavedContext([&] {
|
||||
// FIXME, the max FPS could be better managed by being dynamic (based on the number of current surfaces
|
||||
// and the current rendering load)
|
||||
|
@ -156,10 +178,13 @@ void Web3DOverlay::buildWebSurface() {
|
|||
|
||||
if (isWebContent()) {
|
||||
_webSurface = DependencyManager::get<OffscreenQmlSurfaceCache>()->acquire(QML);
|
||||
_cachedWebSurface = true;
|
||||
_webSurface->getRootItem()->setProperty("url", _url);
|
||||
_webSurface->getRootItem()->setProperty("scriptURL", _scriptURL);
|
||||
} else {
|
||||
_webSurface = DependencyManager::get<OffscreenQmlSurfaceCache>()->acquire(_url);
|
||||
_webSurface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface(), qmlSurfaceDeleter);
|
||||
_webSurface->load(_url);
|
||||
_cachedWebSurface = false;
|
||||
setupQmlSurface();
|
||||
}
|
||||
_webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getWorldPosition()));
|
||||
|
|
|
@ -88,6 +88,7 @@ private:
|
|||
|
||||
InputMode _inputMode { Touch };
|
||||
QSharedPointer<OffscreenQmlSurface> _webSurface;
|
||||
bool _cachedWebSurface{ false };
|
||||
gpu::TexturePointer _texture;
|
||||
QString _url;
|
||||
QString _scriptURL;
|
||||
|
|
|
@ -239,7 +239,7 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
|
|||
}
|
||||
|
||||
bool WebEntityRenderer::hasWebSurface() {
|
||||
return (bool)_webSurface;
|
||||
return (bool)_webSurface && _webSurface->getRootItem();
|
||||
}
|
||||
|
||||
bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) {
|
||||
|
@ -303,7 +303,7 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) {
|
|||
_fadeStartTime = usecTimestampNow();
|
||||
_webSurface->resume();
|
||||
|
||||
return true;
|
||||
return _webSurface->getRootItem();
|
||||
}
|
||||
|
||||
void WebEntityRenderer::destroyWebSurface() {
|
||||
|
|
|
@ -157,7 +157,7 @@ void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool u
|
|||
}
|
||||
|
||||
if (usingUserData) {
|
||||
_parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(getUserData().toUtf8()));
|
||||
_parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(getUserData().toUtf8()), materialURLString);
|
||||
|
||||
// Since our material changed, the current name might not be valid anymore, so we need to update
|
||||
setCurrentMaterialName(_currentMaterialName);
|
||||
|
|
|
@ -20,7 +20,7 @@ void NetworkMaterialResource::downloadFinished(const QByteArray& data) {
|
|||
parsedMaterials.reset();
|
||||
|
||||
if (_url.toString().contains(".json")) {
|
||||
parsedMaterials = parseJSONMaterials(QJsonDocument::fromJson(data));
|
||||
parsedMaterials = parseJSONMaterials(QJsonDocument::fromJson(data), _url);
|
||||
}
|
||||
|
||||
// TODO: parse other material types
|
||||
|
@ -75,7 +75,7 @@ bool NetworkMaterialResource::parseJSONColor(const QJsonValue& array, glm::vec3&
|
|||
* @property {number} materialVersion=1 - The version of the material. <em>Currently not used.</em>
|
||||
* @property {Material|Material[]} materials - The details of the material or materials.
|
||||
*/
|
||||
NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMaterials(const QJsonDocument& materialJSON) {
|
||||
NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMaterials(const QJsonDocument& materialJSON, const QUrl& baseUrl) {
|
||||
ParsedMaterials toReturn;
|
||||
if (!materialJSON.isNull() && materialJSON.isObject()) {
|
||||
QJsonObject materialJSONObject = materialJSON.object();
|
||||
|
@ -91,13 +91,13 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater
|
|||
QJsonArray materials = materialsValue.toArray();
|
||||
for (auto material : materials) {
|
||||
if (!material.isNull() && material.isObject()) {
|
||||
auto parsedMaterial = parseJSONMaterial(material.toObject());
|
||||
auto parsedMaterial = parseJSONMaterial(material.toObject(), baseUrl);
|
||||
toReturn.networkMaterials[parsedMaterial.first] = parsedMaterial.second;
|
||||
toReturn.names.push_back(parsedMaterial.first);
|
||||
}
|
||||
}
|
||||
} else if (materialsValue.isObject()) {
|
||||
auto parsedMaterial = parseJSONMaterial(materialsValue.toObject());
|
||||
auto parsedMaterial = parseJSONMaterial(materialsValue.toObject(), baseUrl);
|
||||
toReturn.networkMaterials[parsedMaterial.first] = parsedMaterial.second;
|
||||
toReturn.names.push_back(parsedMaterial.first);
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater
|
|||
* @property {string} lightMap - URL of light map texture image. <em>Currently not used.</em>
|
||||
*/
|
||||
// Note: See MaterialEntityItem.h for default values used in practice.
|
||||
std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON) {
|
||||
std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl) {
|
||||
std::string name = "";
|
||||
std::shared_ptr<NetworkMaterial> material = std::make_shared<NetworkMaterial>();
|
||||
for (auto& key : materialJSON.keys()) {
|
||||
|
@ -199,57 +199,58 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
|
|||
} else if (key == "albedoMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
QString urlString = value.toString();
|
||||
bool useAlphaChannel = false;
|
||||
auto opacityMap = materialJSON.find("opacityMap");
|
||||
if (opacityMap != materialJSON.end() && opacityMap->isString() && opacityMap->toString() == value.toString()) {
|
||||
if (opacityMap != materialJSON.end() && opacityMap->isString() && opacityMap->toString() == urlString) {
|
||||
useAlphaChannel = true;
|
||||
}
|
||||
material->setAlbedoMap(value.toString(), useAlphaChannel);
|
||||
material->setAlbedoMap(baseUrl.resolved(urlString), useAlphaChannel);
|
||||
}
|
||||
} else if (key == "roughnessMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
material->setRoughnessMap(value.toString(), false);
|
||||
material->setRoughnessMap(baseUrl.resolved(value.toString()), false);
|
||||
}
|
||||
} else if (key == "glossMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
material->setRoughnessMap(value.toString(), true);
|
||||
material->setRoughnessMap(baseUrl.resolved(value.toString()), true);
|
||||
}
|
||||
} else if (key == "metallicMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
material->setMetallicMap(value.toString(), false);
|
||||
material->setMetallicMap(baseUrl.resolved(value.toString()), false);
|
||||
}
|
||||
} else if (key == "specularMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
material->setMetallicMap(value.toString(), true);
|
||||
material->setMetallicMap(baseUrl.resolved(value.toString()), true);
|
||||
}
|
||||
} else if (key == "normalMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
material->setNormalMap(value.toString(), false);
|
||||
material->setNormalMap(baseUrl.resolved(value.toString()), false);
|
||||
}
|
||||
} else if (key == "bumpMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
material->setNormalMap(value.toString(), true);
|
||||
material->setNormalMap(baseUrl.resolved(value.toString()), true);
|
||||
}
|
||||
} else if (key == "occlusionMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
material->setOcclusionMap(value.toString());
|
||||
material->setOcclusionMap(baseUrl.resolved(value.toString()));
|
||||
}
|
||||
} else if (key == "scatteringMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
material->setScatteringMap(value.toString());
|
||||
material->setScatteringMap(baseUrl.resolved(value.toString()));
|
||||
}
|
||||
} else if (key == "lightMap") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
material->setLightmapMap(value.toString());
|
||||
material->setLightmapMap(baseUrl.resolved(value.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ public:
|
|||
|
||||
ParsedMaterials parsedMaterials;
|
||||
|
||||
static ParsedMaterials parseJSONMaterials(const QJsonDocument& materialJSON);
|
||||
static std::pair<std::string, std::shared_ptr<NetworkMaterial>> parseJSONMaterial(const QJsonObject& materialJSON);
|
||||
static ParsedMaterials parseJSONMaterials(const QJsonDocument& materialJSON, const QUrl& baseUrl);
|
||||
static std::pair<std::string, std::shared_ptr<NetworkMaterial>> parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl);
|
||||
|
||||
private:
|
||||
static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB);
|
||||
|
|
|
@ -556,58 +556,58 @@ graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& url, im
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void NetworkMaterial::setAlbedoMap(const QString& url, bool useAlphaChannel) {
|
||||
auto map = fetchTextureMap(QUrl(url), image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
|
||||
void NetworkMaterial::setAlbedoMap(const QUrl& url, bool useAlphaChannel) {
|
||||
auto map = fetchTextureMap(url, image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
|
||||
if (map) {
|
||||
map->setUseAlphaChannel(useAlphaChannel);
|
||||
setTextureMap(MapChannel::ALBEDO_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMaterial::setNormalMap(const QString& url, bool isBumpmap) {
|
||||
auto map = fetchTextureMap(QUrl(url), isBumpmap ? image::TextureUsage::BUMP_TEXTURE : image::TextureUsage::NORMAL_TEXTURE, MapChannel::NORMAL_MAP);
|
||||
void NetworkMaterial::setNormalMap(const QUrl& url, bool isBumpmap) {
|
||||
auto map = fetchTextureMap(url, isBumpmap ? image::TextureUsage::BUMP_TEXTURE : image::TextureUsage::NORMAL_TEXTURE, MapChannel::NORMAL_MAP);
|
||||
if (map) {
|
||||
setTextureMap(MapChannel::NORMAL_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMaterial::setRoughnessMap(const QString& url, bool isGloss) {
|
||||
auto map = fetchTextureMap(QUrl(url), isGloss ? image::TextureUsage::GLOSS_TEXTURE : image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP);
|
||||
void NetworkMaterial::setRoughnessMap(const QUrl& url, bool isGloss) {
|
||||
auto map = fetchTextureMap(url, isGloss ? image::TextureUsage::GLOSS_TEXTURE : image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP);
|
||||
if (map) {
|
||||
setTextureMap(MapChannel::ROUGHNESS_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMaterial::setMetallicMap(const QString& url, bool isSpecular) {
|
||||
auto map = fetchTextureMap(QUrl(url), isSpecular ? image::TextureUsage::SPECULAR_TEXTURE : image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP);
|
||||
void NetworkMaterial::setMetallicMap(const QUrl& url, bool isSpecular) {
|
||||
auto map = fetchTextureMap(url, isSpecular ? image::TextureUsage::SPECULAR_TEXTURE : image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP);
|
||||
if (map) {
|
||||
setTextureMap(MapChannel::METALLIC_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMaterial::setOcclusionMap(const QString& url) {
|
||||
auto map = fetchTextureMap(QUrl(url), image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
|
||||
void NetworkMaterial::setOcclusionMap(const QUrl& url) {
|
||||
auto map = fetchTextureMap(url, image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
|
||||
if (map) {
|
||||
setTextureMap(MapChannel::OCCLUSION_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMaterial::setEmissiveMap(const QString& url) {
|
||||
auto map = fetchTextureMap(QUrl(url), image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP);
|
||||
void NetworkMaterial::setEmissiveMap(const QUrl& url) {
|
||||
auto map = fetchTextureMap(url, image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP);
|
||||
if (map) {
|
||||
setTextureMap(MapChannel::EMISSIVE_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMaterial::setScatteringMap(const QString& url) {
|
||||
auto map = fetchTextureMap(QUrl(url), image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP);
|
||||
void NetworkMaterial::setScatteringMap(const QUrl& url) {
|
||||
auto map = fetchTextureMap(url, image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP);
|
||||
if (map) {
|
||||
setTextureMap(MapChannel::SCATTERING_MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkMaterial::setLightmapMap(const QString& url) {
|
||||
auto map = fetchTextureMap(QUrl(url), image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
|
||||
void NetworkMaterial::setLightmapMap(const QUrl& url) {
|
||||
auto map = fetchTextureMap(url, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
|
||||
if (map) {
|
||||
//map->setTextureTransform(_lightmapTransform);
|
||||
//map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
||||
|
|
|
@ -164,14 +164,14 @@ public:
|
|||
NetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl);
|
||||
NetworkMaterial(const NetworkMaterial& material);
|
||||
|
||||
void setAlbedoMap(const QString& url, bool useAlphaChannel);
|
||||
void setNormalMap(const QString& url, bool isBumpmap);
|
||||
void setRoughnessMap(const QString& url, bool isGloss);
|
||||
void setMetallicMap(const QString& url, bool isSpecular);
|
||||
void setOcclusionMap(const QString& url);
|
||||
void setEmissiveMap(const QString& url);
|
||||
void setScatteringMap(const QString& url);
|
||||
void setLightmapMap(const QString& url);
|
||||
void setAlbedoMap(const QUrl& url, bool useAlphaChannel);
|
||||
void setNormalMap(const QUrl& url, bool isBumpmap);
|
||||
void setRoughnessMap(const QUrl& url, bool isGloss);
|
||||
void setMetallicMap(const QUrl& url, bool isSpecular);
|
||||
void setOcclusionMap(const QUrl& url);
|
||||
void setEmissiveMap(const QUrl& url);
|
||||
void setScatteringMap(const QUrl& url);
|
||||
void setLightmapMap(const QUrl& url);
|
||||
|
||||
protected:
|
||||
friend class Geometry;
|
||||
|
|
|
@ -121,7 +121,7 @@ public:
|
|||
ReplicatedAvatarIdentity,
|
||||
ReplicatedKillAvatar,
|
||||
ReplicatedBulkAvatarData,
|
||||
OctreeFileReplacementFromUrl,
|
||||
DomainContentReplacementFromUrl,
|
||||
ChallengeOwnership,
|
||||
EntityScriptCallMethod,
|
||||
ChallengeOwnershipRequest,
|
||||
|
@ -171,7 +171,7 @@ public:
|
|||
<< PacketTypeEnum::Value::DomainServerPathResponse << PacketTypeEnum::Value::DomainServerAddedNode
|
||||
<< PacketTypeEnum::Value::DomainServerConnectionToken << PacketTypeEnum::Value::DomainSettingsRequest
|
||||
<< PacketTypeEnum::Value::OctreeDataFileRequest << PacketTypeEnum::Value::OctreeDataFileReply
|
||||
<< PacketTypeEnum::Value::OctreeDataPersist << PacketTypeEnum::Value::OctreeFileReplacementFromUrl
|
||||
<< PacketTypeEnum::Value::OctreeDataPersist << PacketTypeEnum::Value::DomainContentReplacementFromUrl
|
||||
<< PacketTypeEnum::Value::DomainSettings << PacketTypeEnum::Value::ICEServerPeerInformation
|
||||
<< PacketTypeEnum::Value::ICEServerQuery << PacketTypeEnum::Value::ICEServerHeartbeat
|
||||
<< PacketTypeEnum::Value::ICEServerHeartbeatACK << PacketTypeEnum::Value::ICEPing
|
||||
|
|
|
@ -8,6 +8,9 @@ include_hifi_library_headers(audio)
|
|||
include_hifi_library_headers(networking)
|
||||
include_hifi_library_headers(octree)
|
||||
|
||||
# tell CMake to exclude qrc_fonts.cpp for policy CMP0071
|
||||
set_property(SOURCE qrc_fonts.cpp PROPERTY SKIP_AUTOMOC ON)
|
||||
|
||||
if (NOT ANDROID)
|
||||
target_nsight()
|
||||
endif ()
|
||||
|
|
|
@ -47,6 +47,8 @@ template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderAr
|
|||
}
|
||||
}
|
||||
|
||||
const graphics::MaterialPointer MeshPartPayload::DEFAULT_MATERIAL = std::make_shared<graphics::Material>();
|
||||
|
||||
MeshPartPayload::MeshPartPayload(const std::shared_ptr<const graphics::Mesh>& mesh, int partIndex, graphics::MaterialPointer material) {
|
||||
updateMeshPart(mesh, partIndex);
|
||||
addMaterial(graphics::MaterialLayer(material, 0));
|
||||
|
@ -99,7 +101,7 @@ void MeshPartPayload::updateKey(bool isVisible, bool isLayered, bool canCastShad
|
|||
builder.withSubMetaCulled();
|
||||
}
|
||||
|
||||
if (_drawMaterials.top().material) {
|
||||
if (topMaterialExists()) {
|
||||
auto matKey = _drawMaterials.top().material->getKey();
|
||||
if (matKey.isTranslucent()) {
|
||||
builder.withTransparent();
|
||||
|
@ -119,7 +121,7 @@ Item::Bound MeshPartPayload::getBound() const {
|
|||
|
||||
ShapeKey MeshPartPayload::getShapeKey() const {
|
||||
graphics::MaterialKey drawMaterialKey;
|
||||
if (_drawMaterials.top().material) {
|
||||
if (topMaterialExists()) {
|
||||
drawMaterialKey = _drawMaterials.top().material->getKey();
|
||||
}
|
||||
|
||||
|
@ -171,7 +173,7 @@ void MeshPartPayload::render(RenderArgs* args) {
|
|||
bindMesh(batch);
|
||||
|
||||
// apply material properties
|
||||
RenderPipelines::bindMaterial(_drawMaterials.top().material, batch, args->_enableTexturing);
|
||||
RenderPipelines::bindMaterial(!_drawMaterials.empty() ? _drawMaterials.top().material : DEFAULT_MATERIAL, batch, args->_enableTexturing);
|
||||
args->_details._materialSwitches++;
|
||||
|
||||
// Draw!
|
||||
|
@ -356,7 +358,7 @@ void ModelMeshPartPayload::updateKey(bool isVisible, bool isLayered, bool canCas
|
|||
builder.withDeformed();
|
||||
}
|
||||
|
||||
if (_drawMaterials.top().material) {
|
||||
if (topMaterialExists()) {
|
||||
auto matKey = _drawMaterials.top().material->getKey();
|
||||
if (matKey.isTranslucent()) {
|
||||
builder.withTransparent();
|
||||
|
@ -387,7 +389,7 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, bool isWireframe
|
|||
}
|
||||
|
||||
graphics::MaterialKey drawMaterialKey;
|
||||
if (_drawMaterials.top().material) {
|
||||
if (topMaterialExists()) {
|
||||
drawMaterialKey = _drawMaterials.top().material->getKey();
|
||||
}
|
||||
|
||||
|
@ -469,7 +471,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
|
|||
bindMesh(batch);
|
||||
|
||||
// apply material properties
|
||||
RenderPipelines::bindMaterial(_drawMaterials.top().material, batch, args->_enableTexturing);
|
||||
RenderPipelines::bindMaterial(!_drawMaterials.empty() ? _drawMaterials.top().material : DEFAULT_MATERIAL, batch, args->_enableTexturing);
|
||||
args->_details._materialSwitches++;
|
||||
|
||||
// Draw!
|
||||
|
|
|
@ -65,15 +65,18 @@ public:
|
|||
graphics::Mesh::Part _drawPart;
|
||||
|
||||
size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; }
|
||||
size_t getMaterialTextureSize() { return _drawMaterials.top().material ? _drawMaterials.top().material->getTextureSize() : 0; }
|
||||
int getMaterialTextureCount() { return _drawMaterials.top().material ? _drawMaterials.top().material->getTextureCount() : 0; }
|
||||
bool hasTextureInfo() const { return _drawMaterials.top().material ? _drawMaterials.top().material->hasTextureInfo() : false; }
|
||||
size_t getMaterialTextureSize() { return topMaterialExists() ? _drawMaterials.top().material->getTextureSize() : 0; }
|
||||
int getMaterialTextureCount() { return topMaterialExists() ? _drawMaterials.top().material->getTextureCount() : 0; }
|
||||
bool hasTextureInfo() const { return topMaterialExists() ? _drawMaterials.top().material->hasTextureInfo() : false; }
|
||||
|
||||
void addMaterial(graphics::MaterialLayer material);
|
||||
void removeMaterial(graphics::MaterialPointer material);
|
||||
|
||||
protected:
|
||||
static const graphics::MaterialPointer DEFAULT_MATERIAL;
|
||||
render::ItemKey _itemKey{ render::ItemKey::Builder::opaqueShape().build() };
|
||||
|
||||
bool topMaterialExists() const { return !_drawMaterials.empty() && _drawMaterials.top().material; }
|
||||
};
|
||||
|
||||
namespace render {
|
||||
|
|
|
@ -1604,7 +1604,8 @@ void Model::createVisibleRenderItemSet() {
|
|||
int numParts = (int)mesh->getNumParts();
|
||||
for (int partIndex = 0; partIndex < numParts; partIndex++) {
|
||||
_modelMeshRenderItems << std::make_shared<ModelMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset);
|
||||
_modelMeshMaterialNames.push_back(getGeometry()->getShapeMaterial(shapeID)->getName());
|
||||
auto material = getGeometry()->getShapeMaterial(shapeID);
|
||||
_modelMeshMaterialNames.push_back(material ? material->getName() : "");
|
||||
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)i });
|
||||
shapeID++;
|
||||
}
|
||||
|
|
|
@ -20,8 +20,12 @@ if (NOT SERVER_ONLY AND NOT ANDROID)
|
|||
add_subdirectory(${DIR})
|
||||
set(DIR "oculusLegacy")
|
||||
add_subdirectory(${DIR})
|
||||
set(DIR "hifiSixense")
|
||||
add_subdirectory(${DIR})
|
||||
|
||||
if (USE_SIXENSE)
|
||||
set(DIR "hifiSixense")
|
||||
add_subdirectory(${DIR})
|
||||
endif()
|
||||
|
||||
set(DIR "hifiSpacemouse")
|
||||
add_subdirectory(${DIR})
|
||||
set(DIR "hifiNeuron")
|
||||
|
|
|
@ -19,7 +19,7 @@ if (WIN32 AND (NOT USE_GLES))
|
|||
set(TARGET_NAME oculus)
|
||||
setup_hifi_plugin(Multimedia)
|
||||
link_hifi_libraries(
|
||||
shared task gl gpu gpu-gl controllers ui qml
|
||||
shared task gl gpu ${PLATFORM_GL_BACKEND} controllers ui qml
|
||||
plugins ui-plugins display-plugins input-plugins
|
||||
audio-client networking render-utils
|
||||
${PLATFORM_GL_BACKEND}
|
||||
|
|
102
scripts/developer/tests/webOverlayTool.js
Normal file
102
scripts/developer/tests/webOverlayTool.js
Normal file
|
@ -0,0 +1,102 @@
|
|||
// webSpawnTool.js
|
||||
//
|
||||
// Stress tests the rendering of web surfaces over time
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
SPAWNER = function (properties) {
|
||||
properties = properties || {};
|
||||
var RADIUS = properties.radius || 5.0; // Spawn within this radius (square)
|
||||
var SPAWN_COUNT = properties.count || 10000; // number of entities to spawn
|
||||
var SPAWN_LIMIT = properties.spawnLimit || 1;
|
||||
var SPAWN_INTERVAL = properties.spawnInterval || properties.interval || 2;
|
||||
var SPAWN_LIFETIME = properties.lifetime || 10; // Entity timeout (when/if we crash, we need the entities to delete themselves)
|
||||
|
||||
function randomPositionXZ(center, radius) {
|
||||
return {
|
||||
x: center.x + (Math.random() * radius * 2.0) - radius,
|
||||
y: center.y,
|
||||
z: center.z + (Math.random() * radius * 2.0) - radius
|
||||
};
|
||||
}
|
||||
|
||||
function makeObject(properties) {
|
||||
|
||||
var overlay = Overlays.addOverlay("web3d", {
|
||||
name: "Web",
|
||||
url: "https://www.reddit.com/r/random",
|
||||
localPosition: randomPositionXZ( { x: 0, y: 0, z: -1 }, 1),
|
||||
localRotation: Quat.angleAxis(180, Vec3.Y_AXIS),
|
||||
dimensions: {x: .8, y: .45, z: 0.1},
|
||||
color: { red: 255, green: 255, blue: 255 },
|
||||
alpha: 1.0,
|
||||
showKeyboardFocusHighlight: false,
|
||||
visible: true
|
||||
});
|
||||
|
||||
var now = Date.now();
|
||||
|
||||
return {
|
||||
destroy: function () {
|
||||
Overlays.deleteOverlay(overlay)
|
||||
},
|
||||
getAge: function () {
|
||||
return (Date.now() - now) / 1000.0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
var items = [];
|
||||
var toCreate = 0;
|
||||
var spawned = 0;
|
||||
var spawnTimer = 0.0;
|
||||
var keepAliveTimer = 0.0;
|
||||
|
||||
function clear () {
|
||||
}
|
||||
|
||||
function create() {
|
||||
toCreate = SPAWN_COUNT;
|
||||
Script.update.connect(spawn);
|
||||
}
|
||||
|
||||
function spawn(dt) {
|
||||
if (toCreate <= 0) {
|
||||
Script.update.disconnect(spawn);
|
||||
print("Finished spawning");
|
||||
}
|
||||
else if ((spawnTimer -= dt) < 0.0){
|
||||
spawnTimer = SPAWN_INTERVAL;
|
||||
|
||||
var n = Math.min(toCreate, SPAWN_LIMIT);
|
||||
print("Spawning " + n + " items (" + (spawned += n) + ")");
|
||||
|
||||
toCreate -= n;
|
||||
for (; n > 0; --n) {
|
||||
items.push(makeObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function despawn() {
|
||||
print("despawning");
|
||||
items.forEach(function (item) {
|
||||
item.destroy();
|
||||
});
|
||||
item = [];
|
||||
}
|
||||
|
||||
function init () {
|
||||
Script.update.disconnect(init);
|
||||
Script.scriptEnding.connect(despawn);
|
||||
clear();
|
||||
create();
|
||||
}
|
||||
|
||||
Script.update.connect(init);
|
||||
};
|
||||
|
||||
SPAWNER();
|
|
@ -13,8 +13,8 @@ set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/")
|
|||
|
||||
# link in the shared libraries
|
||||
link_hifi_libraries(
|
||||
shared task workload networking animation
|
||||
ktx image octree gl gpu gpu-gl
|
||||
shared task networking animation
|
||||
ktx image octree gl gpu ${PLATFORM_GL_BACKEND}
|
||||
render render-utils
|
||||
graphics fbx model-networking graphics-scripting
|
||||
entities entities-renderer audio avatars script-engine
|
||||
|
|
Loading…
Reference in a new issue