mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 09:33:45 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into flag/shadows
This commit is contained in:
commit
dee8e0ba9d
298 changed files with 9616 additions and 6908 deletions
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -25,3 +25,4 @@
|
|||
*.svg binary
|
||||
*.ttf binary
|
||||
*.wav binary
|
||||
*.rsrc binary
|
||||
|
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -36,7 +36,7 @@ interface/external/*/*
|
|||
# Ignore interfaceCache for Linux users
|
||||
interface/interfaceCache/
|
||||
|
||||
# ignore audio-client externals
|
||||
# ignore audio-client externals
|
||||
libraries/audio-client/external/*/*
|
||||
!libraries/audio-client/external/*/readme.txt
|
||||
|
||||
|
@ -46,3 +46,7 @@ gvr-interface/libs/*
|
|||
# ignore files for various dev environments
|
||||
TAGS
|
||||
*.swp
|
||||
|
||||
# ignore node files for the console
|
||||
node_modules
|
||||
npm-debug.log
|
||||
|
|
|
@ -15,7 +15,7 @@ endif ()
|
|||
|
||||
if (POLICY CMP0043)
|
||||
cmake_policy(SET CMP0043 OLD)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (POLICY CMP0042)
|
||||
cmake_policy(SET CMP0042 OLD)
|
||||
|
@ -26,24 +26,32 @@ set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets")
|
|||
|
||||
project(hifi)
|
||||
add_definitions(-DGLM_FORCE_RADIANS)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
|
||||
|
||||
if (WIN32)
|
||||
add_definitions(-DNOMINMAX -D_CRT_SECURE_NO_WARNINGS)
|
||||
# set path for Microsoft SDKs
|
||||
# if get build error about missing 'glu32' this path is likely wrong
|
||||
# Uncomment the line with 8.1 if running Windows 8.1
|
||||
|
||||
if (NOT WINDOW_SDK_PATH)
|
||||
set(DEBUG_DISCOVERED_SDK_PATH TRUE)
|
||||
endif()
|
||||
|
||||
# sets path for Microsoft SDKs
|
||||
# if you get build error about missing 'glu32' this path is likely wrong
|
||||
if (MSVC10)
|
||||
set(WINDOW_SDK_PATH "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1 ")
|
||||
set(WINDOW_SDK_PATH "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1 " CACHE PATH "Windows SDK PATH")
|
||||
elseif (MSVC12)
|
||||
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(WINDOW_SDK_FOLDER "x64")
|
||||
set(WINDOW_SDK_FOLDER "x64")
|
||||
else()
|
||||
set(WINDOW_SDK_FOLDER "x86")
|
||||
set(WINDOW_SDK_FOLDER "x86")
|
||||
endif()
|
||||
set(WINDOW_SDK_PATH "C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\${WINDOW_SDK_FOLDER}")
|
||||
set(WINDOW_SDK_PATH "C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\${WINDOW_SDK_FOLDER}" CACHE PATH "Windows SDK PATH")
|
||||
endif ()
|
||||
message (WINDOW_SDK_PATH= ${WINDOW_SDK_PATH})
|
||||
|
||||
if (DEBUG_DISCOVERED_SDK_PATH)
|
||||
message(STATUS "The discovered Windows SDK path is ${WINDOW_SDK_PATH}")
|
||||
endif ()
|
||||
|
||||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${WINDOW_SDK_PATH})
|
||||
# /wd4351 disables warning C4351: new behavior: elements of array will be default initialized
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /wd4351")
|
||||
|
@ -75,7 +83,7 @@ if ((NOT MSVC12) AND (NOT MSVC14))
|
|||
endif()
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
if (APPLE)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++0x")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --stdlib=libc++")
|
||||
|
@ -85,16 +93,16 @@ if (NOT ANDROID_LIB_DIR)
|
|||
set(ANDROID_LIB_DIR $ENV{ANDROID_LIB_DIR})
|
||||
endif ()
|
||||
|
||||
if (ANDROID)
|
||||
if (ANDROID)
|
||||
if (NOT ANDROID_QT_CMAKE_PREFIX_PATH)
|
||||
set(QT_CMAKE_PREFIX_PATH ${ANDROID_LIB_DIR}/Qt/5.4/android_armv7/lib/cmake)
|
||||
else ()
|
||||
set(QT_CMAKE_PREFIX_PATH ${ANDROID_QT_CMAKE_PREFIX_PATH})
|
||||
endif ()
|
||||
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
|
||||
|
||||
if (ANDROID_LIB_DIR)
|
||||
list(APPEND CMAKE_FIND_ROOT_PATH ${ANDROID_LIB_DIR})
|
||||
endif ()
|
||||
|
@ -107,6 +115,8 @@ else ()
|
|||
endif ()
|
||||
endif ()
|
||||
|
||||
set(QT_DIR $ENV{QT_DIR})
|
||||
|
||||
if (WIN32)
|
||||
if (NOT EXISTS ${QT_CMAKE_PREFIX_PATH})
|
||||
message(FATAL_ERROR "Could not determine QT_CMAKE_PREFIX_PATH.")
|
||||
|
@ -119,34 +129,34 @@ get_filename_component(QT_DIR "${QT_CMAKE_PREFIX_PATH}/../../" ABSOLUTE)
|
|||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT_CMAKE_PREFIX_PATH})
|
||||
|
||||
if (APPLE)
|
||||
|
||||
|
||||
exec_program(sw_vers ARGS -productVersion OUTPUT_VARIABLE OSX_VERSION)
|
||||
string(REGEX MATCH "^[0-9]+\\.[0-9]+" OSX_VERSION ${OSX_VERSION})
|
||||
message(STATUS "Detected OS X version = ${OSX_VERSION}")
|
||||
|
||||
|
||||
set(OSX_SDK "${OSX_VERSION}" CACHE String "OS X SDK version to look for inside Xcode bundle or at OSX_SDK_PATH")
|
||||
|
||||
|
||||
# set our OS X deployment target
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8)
|
||||
|
||||
|
||||
# find the SDK path for the desired SDK
|
||||
find_path(
|
||||
_OSX_DESIRED_SDK_PATH
|
||||
NAME MacOSX${OSX_SDK}.sdk
|
||||
_OSX_DESIRED_SDK_PATH
|
||||
NAME MacOSX${OSX_SDK}.sdk
|
||||
HINTS ${OSX_SDK_PATH}
|
||||
PATHS /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
|
||||
/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
|
||||
)
|
||||
|
||||
|
||||
if (NOT _OSX_DESIRED_SDK_PATH)
|
||||
message(STATUS "Could not find OS X ${OSX_SDK} SDK. Will fall back to default. If you want a specific SDK, please pass OSX_SDK and optionally OSX_SDK_PATH to CMake.")
|
||||
else ()
|
||||
message(STATUS "Found OS X ${OSX_SDK} SDK at ${_OSX_DESIRED_SDK_PATH}/MacOSX${OSX_SDK}.sdk")
|
||||
|
||||
|
||||
# set that as the SDK to use
|
||||
set(CMAKE_OSX_SYSROOT ${_OSX_DESIRED_SDK_PATH}/MacOSX${OSX_SDK}.sdk)
|
||||
endif ()
|
||||
|
||||
|
||||
endif ()
|
||||
|
||||
# Hide automoc folders (for IDEs)
|
||||
|
@ -170,9 +180,9 @@ else ()
|
|||
set(UPPER_CMAKE_BUILD_TYPE DEBUG)
|
||||
endif ()
|
||||
|
||||
set(HIFI_CMAKE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
set(MACRO_DIR "${HIFI_CMAKE_DIR}/macros")
|
||||
set(EXTERNAL_PROJECT_DIR "${HIFI_CMAKE_DIR}/externals")
|
||||
set(HF_CMAKE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
set(MACRO_DIR "${HF_CMAKE_DIR}/macros")
|
||||
set(EXTERNAL_PROJECT_DIR "${HF_CMAKE_DIR}/externals")
|
||||
|
||||
file(GLOB HIFI_CUSTOM_MACROS "cmake/macros/*.cmake")
|
||||
foreach(CUSTOM_MACRO ${HIFI_CUSTOM_MACROS})
|
||||
|
@ -198,9 +208,11 @@ if (WIN32)
|
|||
endif ()
|
||||
|
||||
if (NOT DEFINED SERVER_ONLY)
|
||||
set(SERVER_ONLY 0)
|
||||
set(SERVER_ONLY 0)
|
||||
endif()
|
||||
|
||||
set_packaging_parameters()
|
||||
|
||||
# add subdirectories for all targets
|
||||
if (NOT ANDROID)
|
||||
add_subdirectory(assignment-client)
|
||||
|
@ -209,8 +221,7 @@ if (NOT ANDROID)
|
|||
set_target_properties(domain-server PROPERTIES FOLDER "Apps")
|
||||
add_subdirectory(ice-server)
|
||||
set_target_properties(ice-server PROPERTIES FOLDER "Apps")
|
||||
add_subdirectory(stack-manager)
|
||||
set_target_properties(stack-manager PROPERTIES FOLDER "Apps")
|
||||
add_subdirectory(server-console)
|
||||
if (NOT SERVER_ONLY)
|
||||
add_subdirectory(interface)
|
||||
set_target_properties(interface PROPERTIES FOLDER "Apps")
|
||||
|
@ -233,5 +244,4 @@ if (HIFI_MEMORY_DEBUGGING)
|
|||
endif (UNIX)
|
||||
endif ()
|
||||
|
||||
include_application_version()
|
||||
generate_installers()
|
||||
generate_installers()
|
||||
|
|
25
INSTALL.md
Normal file
25
INSTALL.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
Follow the [build guide](BUILD.md) to figure out how to build High Fidelity for your platform.
|
||||
|
||||
During generation, CMake should produce an `install` target and a `package` target.
|
||||
|
||||
###Install
|
||||
|
||||
The `install` target will copy the High Fidelity targets and their dependencies to your `CMAKE_INSTALL_PREFIX`.
|
||||
|
||||
###Packaging
|
||||
|
||||
To produce an installer, run the `package` target.
|
||||
|
||||
####Windows
|
||||
|
||||
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
|
||||
|
||||
Run the `package` target to create an executable installer using the Nullsoft Scriptable Install System.
|
||||
|
||||
####OS X
|
||||
|
||||
Run the `package` target to create an Apple Disk Image (.dmg).
|
25
LICENSE
25
LICENSE
|
@ -1,13 +1,12 @@
|
|||
Copyright 2014 High Fidelity, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Copyright (c) 2013-2016, High Fidelity, Inc.
|
||||
All rights reserved.
|
||||
licensing@highfidelity.io
|
||||
|
||||
Licensed under the Apache License version 2.0 (the "License");
|
||||
You may not use this software except in compliance with the License.
|
||||
You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
This software includes third-party software.
|
||||
Please see each individual software license for additional details.
|
||||
|
||||
This software is distributed "as-is" without any warranties, conditions, or representations whether express or implied, including without limitation the implied warranties and conditions of merchantability, merchantable quality, fitness for a particular purpose, performance, durability, title, non-infringement, and those arising from statute or from custom or usage of trade or course of dealing.
|
||||
|
|
|
@ -3,12 +3,14 @@ set(TARGET_NAME assignment-client)
|
|||
setup_hifi_project(Core Gui Network Script Quick Widgets WebSockets)
|
||||
|
||||
# link in the shared libraries
|
||||
link_hifi_libraries(
|
||||
audio avatars octree environment gpu model fbx entities
|
||||
link_hifi_libraries(
|
||||
audio avatars octree gpu model fbx entities
|
||||
networking animation recording shared script-engine embedded-webserver
|
||||
controllers physics
|
||||
)
|
||||
|
||||
include_application_version()
|
||||
package_libraries_for_deployment()
|
||||
consolidate_stack_components()
|
||||
if (WIN32)
|
||||
package_libraries_for_deployment()
|
||||
endif()
|
||||
|
||||
install_beside_console()
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <QCommandLineParser>
|
||||
#include <QThread>
|
||||
|
||||
#include <ApplicationVersion.h>
|
||||
#include <BuildInfo.h>
|
||||
#include <LogHandler.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <HifiConfigVariantMap.h>
|
||||
|
@ -22,15 +22,13 @@
|
|||
#include "AssignmentClient.h"
|
||||
#include "AssignmentClientMonitor.h"
|
||||
#include "AssignmentClientApp.h"
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QStandardPaths>
|
||||
|
||||
|
||||
AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
||||
QCoreApplication(argc, argv)
|
||||
{
|
||||
// to work around the Qt constant wireless scanning, set the env for polling interval very high
|
||||
const QByteArray EXTREME_BEARER_POLL_TIMEOUT = QString::number(INT_MAX).toLocal8Bit();
|
||||
qputenv("QT_BEARER_POLL_TIMEOUT", EXTREME_BEARER_POLL_TIMEOUT);
|
||||
|
||||
# ifndef WIN32
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
# endif
|
||||
|
@ -42,10 +40,10 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
|||
ShutdownEventListener::getInstance();
|
||||
# endif
|
||||
|
||||
setOrganizationName("High Fidelity");
|
||||
setOrganizationName(BuildInfo::MODIFIED_ORGANIZATION);
|
||||
setOrganizationDomain("highfidelity.io");
|
||||
setApplicationName("assignment-client");
|
||||
setApplicationName(BUILD_VERSION);
|
||||
setApplicationVersion(BuildInfo::VERSION);
|
||||
|
||||
// use the verbose message handler in Logging
|
||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||
|
@ -63,7 +61,7 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
|||
|
||||
const QCommandLineOption poolOption(ASSIGNMENT_POOL_OPTION, "set assignment pool", "pool-name");
|
||||
parser.addOption(poolOption);
|
||||
|
||||
|
||||
const QCommandLineOption portOption(ASSIGNMENT_CLIENT_LISTEN_PORT_OPTION,
|
||||
"UDP port for this assignment client (or monitor)", "port");
|
||||
parser.addOption(portOption);
|
||||
|
@ -92,6 +90,12 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
|||
const QCommandLineOption monitorPortOption(ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION, "assignment-client monitor port", "port");
|
||||
parser.addOption(monitorPortOption);
|
||||
|
||||
const QCommandLineOption httpStatusPortOption(ASSIGNMENT_HTTP_STATUS_PORT, "http status server port", "http-status-port");
|
||||
parser.addOption(httpStatusPortOption);
|
||||
|
||||
const QCommandLineOption logDirectoryOption(ASSIGNMENT_LOG_DIRECTORY, "directory to store logs", "log-directory");
|
||||
parser.addOption(logDirectoryOption);
|
||||
|
||||
if (!parser.parse(QCoreApplication::arguments())) {
|
||||
qCritical() << parser.errorText() << endl;
|
||||
parser.showHelp();
|
||||
|
@ -130,6 +134,18 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
|||
numForks = minForks;
|
||||
}
|
||||
|
||||
quint16 httpStatusPort { 0 };
|
||||
if (parser.isSet(httpStatusPortOption)) {
|
||||
httpStatusPort = parser.value(httpStatusPortOption).toUShort();
|
||||
}
|
||||
|
||||
QDir logDirectory { "." };
|
||||
if (parser.isSet(logDirectoryOption)) {
|
||||
logDirectory = parser.value(logDirectoryOption);
|
||||
} else {
|
||||
logDirectory = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||
}
|
||||
|
||||
Assignment::Type requestAssignmentType = Assignment::AllTypes;
|
||||
if (argumentVariantMap.contains(ASSIGNMENT_TYPE_OVERRIDE_OPTION)) {
|
||||
requestAssignmentType = (Assignment::Type) argumentVariantMap.value(ASSIGNMENT_TYPE_OVERRIDE_OPTION).toInt();
|
||||
|
@ -168,11 +184,11 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
|||
if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) {
|
||||
assignmentServerPort = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toUInt();
|
||||
}
|
||||
|
||||
|
||||
if (parser.isSet(assignmentServerPortOption)) {
|
||||
assignmentServerPort = parser.value(assignmentServerPortOption).toInt();
|
||||
}
|
||||
|
||||
|
||||
// check for an overidden listen port
|
||||
quint16 listenPort = 0;
|
||||
if (argumentVariantMap.contains(ASSIGNMENT_CLIENT_LISTEN_PORT_OPTION)) {
|
||||
|
@ -200,7 +216,7 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
|||
AssignmentClientMonitor* monitor = new AssignmentClientMonitor(numForks, minForks, maxForks,
|
||||
requestAssignmentType, assignmentPool,
|
||||
listenPort, walletUUID, assignmentServerHostname,
|
||||
assignmentServerPort);
|
||||
assignmentServerPort, httpStatusPort, logDirectory);
|
||||
monitor->setParent(this);
|
||||
connect(this, &QCoreApplication::aboutToQuit, monitor, &AssignmentClientMonitor::aboutToQuit);
|
||||
} else {
|
||||
|
|
|
@ -25,6 +25,8 @@ const QString ASSIGNMENT_NUM_FORKS_OPTION = "n";
|
|||
const QString ASSIGNMENT_MIN_FORKS_OPTION = "min";
|
||||
const QString ASSIGNMENT_MAX_FORKS_OPTION = "max";
|
||||
const QString ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION = "monitor-port";
|
||||
const QString ASSIGNMENT_HTTP_STATUS_PORT = "http-status-port";
|
||||
const QString ASSIGNMENT_LOG_DIRECTORY = "log-directory";
|
||||
|
||||
class AssignmentClientApp : public QCoreApplication {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include <memory>
|
||||
#include <signal.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include <AddressManager.h>
|
||||
#include <LogHandler.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
|
@ -20,6 +23,7 @@
|
|||
#include "AssignmentClientApp.h"
|
||||
#include "AssignmentClientChildData.h"
|
||||
#include "SharedUtil.h"
|
||||
#include <QtCore/QJsonDocument>
|
||||
|
||||
const QString ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME = "assignment-client-monitor";
|
||||
const int WAIT_FOR_CHILD_MSECS = 1000;
|
||||
|
@ -29,7 +33,9 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen
|
|||
const unsigned int maxAssignmentClientForks,
|
||||
Assignment::Type requestAssignmentType, QString assignmentPool,
|
||||
quint16 listenPort, QUuid walletUUID, QString assignmentServerHostname,
|
||||
quint16 assignmentServerPort) :
|
||||
quint16 assignmentServerPort, quint16 httpStatusServerPort, QDir logDirectory) :
|
||||
_logDirectory(logDirectory),
|
||||
_httpManager(QHostAddress::LocalHost, httpStatusServerPort, "", this),
|
||||
_numAssignmentClientForks(numAssignmentClientForks),
|
||||
_minAssignmentClientForks(minAssignmentClientForks),
|
||||
_maxAssignmentClientForks(maxAssignmentClientForks),
|
||||
|
@ -38,6 +44,7 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen
|
|||
_walletUUID(walletUUID),
|
||||
_assignmentServerHostname(assignmentServerHostname),
|
||||
_assignmentServerPort(assignmentServerPort)
|
||||
|
||||
{
|
||||
qDebug() << "_requestAssignmentType =" << _requestAssignmentType;
|
||||
|
||||
|
@ -80,24 +87,21 @@ void AssignmentClientMonitor::simultaneousWaitOnChildren(int waitMsecs) {
|
|||
}
|
||||
}
|
||||
|
||||
void AssignmentClientMonitor::childProcessFinished() {
|
||||
QProcess* childProcess = qobject_cast<QProcess*>(sender());
|
||||
qint64 processID = _childProcesses.key(childProcess);
|
||||
|
||||
if (processID > 0) {
|
||||
qDebug() << "Child process" << processID << "has finished. Removing from internal map.";
|
||||
_childProcesses.remove(processID);
|
||||
void AssignmentClientMonitor::childProcessFinished(qint64 pid) {
|
||||
if (_childProcesses.remove(pid)) {
|
||||
qDebug() << "Child process" << pid << "has finished. Removed from internal map.";
|
||||
}
|
||||
}
|
||||
|
||||
void AssignmentClientMonitor::stopChildProcesses() {
|
||||
qDebug() << "Stopping child processes";
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
// ask child processes to terminate
|
||||
foreach(QProcess* childProcess, _childProcesses) {
|
||||
if (childProcess->processId() > 0) {
|
||||
qDebug() << "Attempting to terminate child process" << childProcess->processId();
|
||||
childProcess->terminate();
|
||||
for (auto& ac : _childProcesses) {
|
||||
if (ac.process->processId() > 0) {
|
||||
qDebug() << "Attempting to terminate child process" << ac.process->processId();
|
||||
ac.process->terminate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,10 +109,10 @@ void AssignmentClientMonitor::stopChildProcesses() {
|
|||
|
||||
if (_childProcesses.size() > 0) {
|
||||
// ask even more firmly
|
||||
foreach(QProcess* childProcess, _childProcesses) {
|
||||
if (childProcess->processId() > 0) {
|
||||
qDebug() << "Attempting to kill child process" << childProcess->processId();
|
||||
childProcess->kill();
|
||||
for (auto& ac : _childProcesses) {
|
||||
if (ac.process->processId() > 0) {
|
||||
qDebug() << "Attempting to kill child process" << ac.process->processId();
|
||||
ac.process->kill();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,18 +159,61 @@ void AssignmentClientMonitor::spawnChildClient() {
|
|||
_childArguments.append("--" + ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION);
|
||||
_childArguments.append(QString::number(DependencyManager::get<NodeList>()->getLocalSockAddr().getPort()));
|
||||
|
||||
// Setup log files
|
||||
const QString DATETIME_FORMAT = "yyyyMMdd.hh.mm.ss.zzz";
|
||||
|
||||
if (!_logDirectory.exists()) {
|
||||
qDebug() << "Log directory (" << _logDirectory.absolutePath() << ") does not exist, creating.";
|
||||
_logDirectory.mkpath(_logDirectory.absolutePath());
|
||||
}
|
||||
|
||||
auto nowString = QDateTime::currentDateTime().toString(DATETIME_FORMAT);
|
||||
auto stdoutFilenameTemp = QString("ac-%1-stdout.txt").arg(nowString);
|
||||
auto stderrFilenameTemp = QString("ac-%1-stderr.txt").arg(nowString);
|
||||
QString stdoutPathTemp = _logDirectory.absoluteFilePath(stdoutFilenameTemp);
|
||||
QString stderrPathTemp = _logDirectory.absoluteFilePath(stderrFilenameTemp);
|
||||
|
||||
// reset our output and error files
|
||||
assignmentClient->setStandardOutputFile(stdoutPathTemp);
|
||||
assignmentClient->setStandardErrorFile(stderrPathTemp);
|
||||
|
||||
// make sure that the output from the child process appears in our output
|
||||
assignmentClient->setProcessChannelMode(QProcess::ForwardedChannels);
|
||||
|
||||
assignmentClient->start(QCoreApplication::applicationFilePath(), _childArguments);
|
||||
|
||||
|
||||
// Update log path to use PID in filename
|
||||
auto stdoutFilename = QString("ac-%1_%2-stdout.txt").arg(nowString).arg(assignmentClient->processId());
|
||||
auto stderrFilename = QString("ac-%1_%2-stderr.txt").arg(nowString).arg(assignmentClient->processId());
|
||||
QString stdoutPath = _logDirectory.absoluteFilePath(stdoutFilename);
|
||||
QString stderrPath = _logDirectory.absoluteFilePath(stderrFilename);
|
||||
|
||||
qDebug() << "Renaming " << stdoutPathTemp << " to " << stdoutPath;
|
||||
if (!_logDirectory.rename(stdoutFilenameTemp, stdoutFilename)) {
|
||||
qDebug() << "Failed to rename " << stdoutFilenameTemp;
|
||||
stdoutPath = stdoutPathTemp;
|
||||
stdoutFilename = stdoutFilenameTemp;
|
||||
}
|
||||
|
||||
qDebug() << "Renaming " << stderrPathTemp << " to " << stderrPath;
|
||||
if (!QFile::rename(stderrPathTemp, stderrPath)) {
|
||||
qDebug() << "Failed to rename " << stderrFilenameTemp;
|
||||
stderrPath = stderrPathTemp;
|
||||
stderrFilename = stderrFilenameTemp;
|
||||
}
|
||||
|
||||
qDebug() << "Child stdout being written to: " << stdoutFilename;
|
||||
qDebug() << "Child stderr being written to: " << stderrFilename;
|
||||
|
||||
if (assignmentClient->processId() > 0) {
|
||||
auto pid = assignmentClient->processId();
|
||||
// make sure we hear that this process has finished when it does
|
||||
connect(assignmentClient, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(childProcessFinished()));
|
||||
|
||||
connect(assignmentClient, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
||||
this, [this, pid]() { childProcessFinished(pid); });
|
||||
|
||||
qDebug() << "Spawned a child client with PID" << assignmentClient->processId();
|
||||
_childProcesses.insert(assignmentClient->processId(), assignmentClient);
|
||||
}
|
||||
_childProcesses.insert(assignmentClient->processId(), { assignmentClient, stdoutPath, stderrPath });
|
||||
}
|
||||
}
|
||||
|
||||
void AssignmentClientMonitor::checkSpares() {
|
||||
|
@ -222,12 +269,12 @@ void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer<ReceivedMes
|
|||
// The parent only expects to be talking with prorams running on this same machine.
|
||||
if (senderSockAddr.getAddress() == QHostAddress::LocalHost ||
|
||||
senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) {
|
||||
|
||||
|
||||
if (!senderID.isNull()) {
|
||||
// We don't have this node yet - we should add it
|
||||
matchingNode = DependencyManager::get<LimitedNodeList>()->addOrUpdateNode
|
||||
(senderID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false);
|
||||
|
||||
|
||||
auto childData = std::unique_ptr<AssignmentClientChildData>
|
||||
{ new AssignmentClientChildData(Assignment::Type::AllTypes) };
|
||||
matchingNode->setLinkedData(std::move(childData));
|
||||
|
@ -252,10 +299,39 @@ void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer<ReceivedMes
|
|||
// get child's assignment type out of the packet
|
||||
quint8 assignmentType;
|
||||
message->readPrimitive(&assignmentType);
|
||||
|
||||
childData->setChildType((Assignment::Type) assignmentType);
|
||||
|
||||
|
||||
childData->setChildType(Assignment::Type(assignmentType));
|
||||
|
||||
// note when this child talked
|
||||
matchingNode->setLastHeardMicrostamp(usecTimestampNow());
|
||||
}
|
||||
}
|
||||
|
||||
bool AssignmentClientMonitor::handleHTTPRequest(HTTPConnection* connection, const QUrl& url, bool skipSubHandler) {
|
||||
if (url.path() == "/status") {
|
||||
QByteArray response;
|
||||
|
||||
QJsonObject status;
|
||||
QJsonObject servers;
|
||||
for (auto& ac : _childProcesses) {
|
||||
QJsonObject server;
|
||||
|
||||
server["pid"] = ac.process->processId();
|
||||
server["logStdout"] = ac.logStdoutPath;
|
||||
server["logStderr"] = ac.logStderrPath;
|
||||
|
||||
servers[QString::number(ac.process->processId())] = server;
|
||||
}
|
||||
|
||||
status["servers"] = servers;
|
||||
|
||||
QJsonDocument document { status };
|
||||
|
||||
connection->respond(HTTPConnection::StatusCode200, document.toJson());
|
||||
} else {
|
||||
connection->respond(HTTPConnection::StatusCode404);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -16,28 +16,39 @@
|
|||
#include <QtCore/qpointer.h>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QDir>
|
||||
|
||||
#include <Assignment.h>
|
||||
|
||||
#include "AssignmentClientChildData.h"
|
||||
#include <HTTPManager.h>
|
||||
#include <HTTPConnection.h>
|
||||
|
||||
extern const char* NUM_FORKS_PARAMETER;
|
||||
|
||||
class AssignmentClientMonitor : public QObject {
|
||||
struct ACProcess {
|
||||
QProcess* process; // looks like a dangling pointer, but is parented by the AssignmentClientMonitor
|
||||
QString logStdoutPath;
|
||||
QString logStderrPath;
|
||||
};
|
||||
|
||||
class AssignmentClientMonitor : public QObject, public HTTPRequestHandler {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AssignmentClientMonitor(const unsigned int numAssignmentClientForks, const unsigned int minAssignmentClientForks,
|
||||
const unsigned int maxAssignmentClientForks, Assignment::Type requestAssignmentType,
|
||||
QString assignmentPool, quint16 listenPort, QUuid walletUUID, QString assignmentServerHostname,
|
||||
quint16 assignmentServerPort);
|
||||
quint16 assignmentServerPort, quint16 httpStatusServerPort, QDir logDirectory);
|
||||
~AssignmentClientMonitor();
|
||||
|
||||
void stopChildProcesses();
|
||||
private slots:
|
||||
void checkSpares();
|
||||
void childProcessFinished();
|
||||
void childProcessFinished(qint64 pid);
|
||||
void handleChildStatusPacket(QSharedPointer<ReceivedMessage> message);
|
||||
|
||||
|
||||
bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url, bool skipSubHandler = false) override;
|
||||
|
||||
public slots:
|
||||
void aboutToQuit();
|
||||
|
||||
|
@ -47,6 +58,10 @@ private:
|
|||
|
||||
QTimer _checkSparesTimer; // every few seconds see if it need fewer or more spare children
|
||||
|
||||
QDir _logDirectory;
|
||||
|
||||
HTTPManager _httpManager;
|
||||
|
||||
const unsigned int _numAssignmentClientForks;
|
||||
const unsigned int _minAssignmentClientForks;
|
||||
const unsigned int _maxAssignmentClientForks;
|
||||
|
@ -57,7 +72,7 @@ private:
|
|||
QString _assignmentServerHostname;
|
||||
quint16 _assignmentServerPort;
|
||||
|
||||
QMap<qint64, QProcess*> _childProcesses;
|
||||
QMap<qint64, ACProcess> _childProcesses;
|
||||
};
|
||||
|
||||
#endif // hifi_AssignmentClientMonitor_h
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "NodeType.h"
|
||||
#include "SendAssetTask.h"
|
||||
#include "UploadAssetTask.h"
|
||||
#include <ServerPathUtils.h>
|
||||
|
||||
const QString ASSET_SERVER_LOGGING_TARGET_NAME = "asset-server";
|
||||
|
||||
|
@ -49,10 +50,42 @@ void AssetServer::run() {
|
|||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
||||
|
||||
_resourcesDirectory = QDir(QCoreApplication::applicationDirPath()).filePath("resources/assets");
|
||||
if (!_resourcesDirectory.exists()) {
|
||||
qDebug() << "Creating resources directory";
|
||||
_resourcesDirectory.mkpath(".");
|
||||
const QString RESOURCES_PATH = "assets";
|
||||
|
||||
_resourcesDirectory = QDir(ServerPathUtils::getDataDirectory()).filePath(RESOURCES_PATH);
|
||||
|
||||
qDebug() << "Creating resources directory";
|
||||
_resourcesDirectory.mkpath(".");
|
||||
|
||||
bool noExistingAssets = !_resourcesDirectory.exists() \
|
||||
|| _resourcesDirectory.entryList(QDir::Files).size() == 0;
|
||||
|
||||
if (noExistingAssets) {
|
||||
qDebug() << "Asset resources directory not found, searching for existing asset resources";
|
||||
QString oldDataDirectory = QCoreApplication::applicationDirPath();
|
||||
auto oldResourcesDirectory = QDir(oldDataDirectory).filePath("resources/" + RESOURCES_PATH);
|
||||
|
||||
|
||||
if (QDir(oldResourcesDirectory).exists()) {
|
||||
qDebug() << "Existing assets found in " << oldResourcesDirectory << ", copying to " << _resourcesDirectory;
|
||||
|
||||
|
||||
QDir resourcesParentDirectory = _resourcesDirectory.filePath("..");
|
||||
if (!resourcesParentDirectory.exists()) {
|
||||
qDebug() << "Creating data directory " << resourcesParentDirectory.absolutePath();
|
||||
resourcesParentDirectory.mkpath(".");
|
||||
}
|
||||
|
||||
auto files = QDir(oldResourcesDirectory).entryList(QDir::Files);
|
||||
|
||||
for (auto& file : files) {
|
||||
auto from = oldResourcesDirectory + QDir::separator() + file;
|
||||
auto to = _resourcesDirectory.absoluteFilePath(file);
|
||||
qDebug() << "\tCopying from " << from << " to " << to;
|
||||
QFile::copy(from, to);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
qDebug() << "Serving files from: " << _resourcesDirectory.path();
|
||||
|
||||
|
|
|
@ -827,7 +827,12 @@ void AudioMixer::broadcastMixes() {
|
|||
}
|
||||
|
||||
usecToSleep = (++nextFrame * AudioConstants::NETWORK_FRAME_USECS) - timer.nsecsElapsed() / 1000; // ns to us
|
||||
|
||||
|
||||
if (usecToSleep > int(USECS_PER_SECOND)) {
|
||||
qDebug() << "DANGER: amount to sleep is" << usecToSleep;
|
||||
qDebug() << "NextFrame is" << nextFrame << "and timer nsecs elapsed is" << timer.nsecsElapsed();
|
||||
}
|
||||
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
}
|
||||
|
|
|
@ -9,11 +9,15 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "AssignmentClientApp.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "AssignmentClientApp.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
disableQtBearerPoll(); // Fixes wifi ping spikes
|
||||
|
||||
AssignmentClientApp app(argc, argv);
|
||||
|
||||
int acReturn = app.exec();
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
|
||||
#include "OctreeQueryNode.h"
|
||||
#include "OctreeServerConsts.h"
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <ServerPathUtils.h>
|
||||
#include <QtCore/QDir>
|
||||
|
||||
int OctreeServer::_clientCount = 0;
|
||||
const int MOVING_AVERAGE_SAMPLE_COUNTS = 1000000;
|
||||
|
@ -280,10 +283,10 @@ OctreeServer::~OctreeServer() {
|
|||
void OctreeServer::initHTTPManager(int port) {
|
||||
// setup the embedded web server
|
||||
|
||||
QString documentRoot = QString("%1/resources/web").arg(QCoreApplication::applicationDirPath());
|
||||
QString documentRoot = QString("%1/web").arg(ServerPathUtils::getDataDirectory());
|
||||
|
||||
// setup an httpManager with us as the request handler and the parent
|
||||
_httpManager = new HTTPManager(port, documentRoot, this, this);
|
||||
_httpManager = new HTTPManager(QHostAddress::AnyIPv4, port, documentRoot, this, this);
|
||||
}
|
||||
|
||||
bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url, bool skipSubHandler) {
|
||||
|
@ -1031,6 +1034,7 @@ void OctreeServer::readConfiguration() {
|
|||
if (!readOptionString(QString("persistFilename"), settingsSectionObject, persistFilename)) {
|
||||
persistFilename = getMyDefaultPersistFilename();
|
||||
}
|
||||
|
||||
strcpy(_persistFilename, qPrintable(persistFilename));
|
||||
qDebug("persistFilename=%s", _persistFilename);
|
||||
|
||||
|
@ -1096,7 +1100,7 @@ void OctreeServer::run() {
|
|||
_tree->setIsServer(true);
|
||||
|
||||
qDebug() << "Waiting for connection to domain to request settings from domain-server.";
|
||||
|
||||
|
||||
// wait until we have the domain-server settings, otherwise we bail
|
||||
DomainHandler& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
|
||||
connect(&domainHandler, &DomainHandler::settingsReceived, this, &OctreeServer::domainSettingsRequestComplete);
|
||||
|
@ -1139,9 +1143,52 @@ void OctreeServer::domainSettingsRequestComplete() {
|
|||
|
||||
// if we want Persistence, set up the local file and persist thread
|
||||
if (_wantPersist) {
|
||||
// If persist filename does not exist, let's see if there is one beside the application binary
|
||||
// If there is, let's copy it over to our target persist directory
|
||||
auto persistPath = ServerPathUtils::getDataFilePath("entities/" + QString(_persistFilename));
|
||||
if (!QFile::exists(persistPath)) {
|
||||
qDebug() << "Persist file does not exist, checking for existence of persist file next to application";
|
||||
|
||||
static const QString OLD_DEFAULT_PERSIST_FILENAME = "resources/models.json.gz";
|
||||
QString oldResourcesDirectory = QCoreApplication::applicationDirPath();
|
||||
|
||||
// This is the old persist path, based on the current persist filename, which could
|
||||
// be a custom filename set by the user.
|
||||
auto oldPersistPath = QDir(oldResourcesDirectory).absoluteFilePath(_persistFilename);
|
||||
|
||||
// This is the old default persist path.
|
||||
auto oldDefaultPersistPath = QDir(oldResourcesDirectory).absoluteFilePath(OLD_DEFAULT_PERSIST_FILENAME);
|
||||
|
||||
qDebug() << "Checking for existing persist file at " << oldPersistPath << " and " << oldDefaultPersistPath;
|
||||
|
||||
QString pathToCopyFrom;
|
||||
bool shouldCopy = false;
|
||||
|
||||
if (QFile::exists(oldPersistPath)) {
|
||||
shouldCopy = true;
|
||||
pathToCopyFrom = oldPersistPath;
|
||||
} else if (QFile::exists(oldDefaultPersistPath)) {
|
||||
shouldCopy = true;
|
||||
pathToCopyFrom = oldDefaultPersistPath;
|
||||
}
|
||||
|
||||
if (shouldCopy) {
|
||||
qDebug() << "Old persist file found, copying from " << pathToCopyFrom << " to " << persistPath;
|
||||
|
||||
QDir persistFileDirectory = QDir(persistPath).filePath("..");
|
||||
|
||||
if (!persistFileDirectory.exists()) {
|
||||
qDebug() << "Creating data directory " << persistFileDirectory.path();
|
||||
persistFileDirectory.mkpath(".");
|
||||
}
|
||||
QFile::copy(pathToCopyFrom, persistPath);
|
||||
} else {
|
||||
qDebug() << "No existing persist file found";
|
||||
}
|
||||
}
|
||||
|
||||
// now set up PersistThread
|
||||
_persistThread = new OctreePersistThread(_tree, _persistFilename, _persistInterval,
|
||||
_persistThread = new OctreePersistThread(_tree, persistPath, _persistInterval,
|
||||
_wantBackup, _settings, _debugTimestampNow, _persistAsFileType);
|
||||
_persistThread->initialize(true);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <HTTPManager.h>
|
||||
|
||||
#include <ThreadedAssignment.h>
|
||||
#include <EnvironmentData.h>
|
||||
|
||||
#include "OctreePersistThread.h"
|
||||
#include "OctreeSendThread.h"
|
||||
|
|
21
cmake/externals/faceshift/CMakeLists.txt
vendored
21
cmake/externals/faceshift/CMakeLists.txt
vendored
|
@ -21,10 +21,23 @@ ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
|||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE FILEPATH "Path to Faceshift include directory")
|
||||
|
||||
set(LIBRARY_DEBUG_PATH "lib/Debug")
|
||||
set(LIBRARY_RELEASE_PATH "lib/Release")
|
||||
|
||||
if (WIN32)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/faceshift.lib CACHE FILEPATH "Faceshift libraries")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/faceshift.lib CACHE FILEPATH "Faceshift libraries")
|
||||
set(LIBRARY_PREFIX "")
|
||||
set(LIBRARY_EXT "lib")
|
||||
elseif (APPLE)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/libfaceshift.a CACHE FILEPATH "Faceshift libraries")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/libfaceshift.a CACHE FILEPATH "Faceshift libraries")
|
||||
set(LIBRARY_EXT "a")
|
||||
set(LIBRARY_PREFIX "lib")
|
||||
|
||||
if (CMAKE_GENERATOR STREQUAL "Unix Makefiles")
|
||||
set(LIBRARY_DEBUG_PATH "build")
|
||||
set(LIBRARY_RELEASE_PATH "build")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG
|
||||
${INSTALL_DIR}/${LIBRARY_DEBUG_PATH}/${LIBRARY_PREFIX}faceshift.${LIBRARY_EXT} CACHE FILEPATH "Faceshift libraries")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE
|
||||
${INSTALL_DIR}/${LIBRARY_RELEASE_PATH}/${LIBRARY_PREFIX}faceshift.${LIBRARY_EXT} CACHE FILEPATH "Faceshift libraries")
|
||||
|
|
52
cmake/externals/quazip/CMakeLists.txt
vendored
52
cmake/externals/quazip/CMakeLists.txt
vendored
|
@ -1,52 +0,0 @@
|
|||
set(EXTERNAL_NAME quazip)
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
cmake_policy(SET CMP0046 OLD)
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
if (WIN32)
|
||||
# windows shell does not like backslashes expanded on the command line,
|
||||
# so convert all backslashes in the QT path to forward slashes
|
||||
string(REPLACE \\ / QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH})
|
||||
elseif ($ENV{QT_CMAKE_PREFIX_PATH})
|
||||
set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH})
|
||||
endif ()
|
||||
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL http://s3-us-west-1.amazonaws.com/hifi-production/dependencies/quazip-0.6.2.zip
|
||||
URL_MD5 514851970f1a14d815bdc3ad6267af4d
|
||||
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
|
||||
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}
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
)
|
||||
|
||||
add_dependencies(quazip zlib)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES
|
||||
FOLDER "hidden/externals"
|
||||
INSTALL_NAME_DIR ${INSTALL_DIR}/lib
|
||||
BUILD_WITH_INSTALL_RPATH True)
|
||||
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${INSTALL_DIR}/include CACHE PATH "List of QuaZip include directories")
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${${EXTERNAL_NAME_UPPER}_INCLUDE_DIR} CACHE PATH "List of QuaZip include directories")
|
||||
set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${INSTALL_DIR}/lib CACHE FILEPATH "Location of QuaZip DLL")
|
||||
|
||||
if (APPLE)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/libquazip.1.0.0.dylib CACHE FILEPATH "Location of QuaZip release library")
|
||||
elseif (WIN32)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/quazip.lib CACHE FILEPATH "Location of QuaZip release library")
|
||||
else ()
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/libquazip.so CACHE FILEPATH "Location of QuaZip release library")
|
||||
endif ()
|
||||
|
||||
include(SelectLibraryConfigurations)
|
||||
select_library_configurations(${EXTERNAL_NAME_UPPER})
|
||||
|
||||
# Force selected libraries into the cache
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY ${${EXTERNAL_NAME_UPPER}_LIBRARY} CACHE FILEPATH "Location of QuaZip libraries")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Location of QuaZip libraries")
|
1634
cmake/installer/install-folder.rsrc
Normal file
1634
cmake/installer/install-folder.rsrc
Normal file
File diff suppressed because it is too large
Load diff
BIN
cmake/installer/installer-header.bmp
Normal file
BIN
cmake/installer/installer-header.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
BIN
cmake/installer/installer.ico
Normal file
BIN
cmake/installer/installer.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 153 KiB |
BIN
cmake/installer/uninstaller-header.bmp
Normal file
BIN
cmake/installer/uninstaller-header.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
|
@ -1,28 +0,0 @@
|
|||
macro(CONSOLIDATE_STACK_COMPONENTS)
|
||||
|
||||
if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE)
|
||||
if (WIN32)
|
||||
# Copy all the output for this target into the common deployment location
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory $<TARGET_FILE_DIR:${TARGET_NAME}> ${CMAKE_BINARY_DIR}/full-stack-deployment
|
||||
)
|
||||
|
||||
# Copy icon files for interface and stack manager
|
||||
if (TARGET_NAME STREQUAL "interface" OR TARGET_NAME STREQUAL "stack-manager")
|
||||
if (TARGET_NAME STREQUAL "interface")
|
||||
set (ICON_FILE_PATH "${PROJECT_SOURCE_DIR}/icon/interface.ico")
|
||||
set (ICON_DESTINATION_NAME "interface.ico")
|
||||
elseif (TARGET_NAME STREQUAL "stack-manager")
|
||||
set (ICON_FILE_PATH "${PROJECT_SOURCE_DIR}/assets/icon.ico")
|
||||
set (ICON_DESTINATION_NAME "stack-manager.ico")
|
||||
endif ()
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy ${ICON_FILE_PATH} ${CMAKE_BINARY_DIR}/full-stack-deployment/${ICON_DESTINATION_NAME}
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
endmacro()
|
16
cmake/macros/FixPathForNSIS.cmake
Normal file
16
cmake/macros/FixPathForNSIS.cmake
Normal file
|
@ -0,0 +1,16 @@
|
|||
#
|
||||
# FixPathForNSIS.cmake
|
||||
#
|
||||
# Created by Sam Gateau on 1/14/16.
|
||||
# Copyright 2016 High Fidelity, Inc.
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
macro(fix_path_for_nsis INITIAL_PATH RESULTING_PATH)
|
||||
# replace forward slash with backslash
|
||||
string(REPLACE "/" "\\\\" _BACKSLASHED_PATH ${INITIAL_PATH})
|
||||
# set the resulting path variable
|
||||
set(${RESULTING_PATH} ${_BACKSLASHED_PATH})
|
||||
endmacro()
|
58
cmake/macros/FixupInterface.cmake
Normal file
58
cmake/macros/FixupInterface.cmake
Normal file
|
@ -0,0 +1,58 @@
|
|||
#
|
||||
# FixupInterface.cmake
|
||||
# cmake/macros
|
||||
#
|
||||
# Copyright 2016 High Fidelity, Inc.
|
||||
# Created by Stephen Birarda on January 6th, 2016
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
macro(fixup_interface)
|
||||
if (APPLE)
|
||||
|
||||
string(REPLACE " " "\\ " ESCAPED_BUNDLE_NAME ${INTERFACE_BUNDLE_NAME})
|
||||
string(REPLACE " " "\\ " ESCAPED_INSTALL_PATH ${INTERFACE_INSTALL_DIR})
|
||||
set(_INTERFACE_INSTALL_PATH "${ESCAPED_INSTALL_PATH}/${ESCAPED_BUNDLE_NAME}.app")
|
||||
|
||||
# install QtWebProcess from Qt to the application bundle
|
||||
# since it is missed by macdeployqt
|
||||
# https://bugreports.qt.io/browse/QTBUG-35211
|
||||
set(LIBEXEC_PATH "${_INTERFACE_INSTALL_PATH}/Contents/libexec")
|
||||
install(
|
||||
PROGRAMS "${QT_DIR}/libexec/QtWebProcess"
|
||||
DESTINATION ${LIBEXEC_PATH}
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
)
|
||||
|
||||
set(QTWEBPROCESS_PATH "\${CMAKE_INSTALL_PREFIX}/${LIBEXEC_PATH}")
|
||||
|
||||
# we also need a qt.conf in the directory of QtWebProcess
|
||||
install(CODE "
|
||||
file(WRITE ${QTWEBPROCESS_PATH}/qt.conf
|
||||
\"[Paths]\nPlugins = ../PlugIns\nImports = ../Resources/qml\nQml2Imports = ../Resources/qml\"
|
||||
)"
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
)
|
||||
|
||||
find_program(MACDEPLOYQT_COMMAND macdeployqt PATHS "${QT_DIR}/bin" NO_DEFAULT_PATH)
|
||||
|
||||
if (NOT MACDEPLOYQT_COMMAND AND (PRODUCTION_BUILD OR PR_BUILD))
|
||||
message(FATAL_ERROR "Could not find macdeployqt at ${QT_DIR}/bin.\
|
||||
It is required to produce an relocatable interface application.\
|
||||
Check that the environment variable QT_DIR points to your Qt installation.\
|
||||
")
|
||||
endif ()
|
||||
|
||||
install(CODE "
|
||||
execute_process(COMMAND ${MACDEPLOYQT_COMMAND}\
|
||||
\${CMAKE_INSTALL_PREFIX}/${_INTERFACE_INSTALL_PATH}/\
|
||||
-verbose=2 -qmldir=${CMAKE_SOURCE_DIR}/interface/resources/qml/\
|
||||
-executable=\${CMAKE_INSTALL_PREFIX}/${_INTERFACE_INSTALL_PATH}/Contents/libexec/QtWebProcess\
|
||||
)"
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
)
|
||||
|
||||
endif ()
|
||||
endmacro()
|
|
@ -1,30 +1,78 @@
|
|||
#
|
||||
# GenerateInstallers.cmake
|
||||
# cmake/macros
|
||||
#
|
||||
# Created by Leonardo Murillo on 12/16/2015.
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
macro(GENERATE_INSTALLERS)
|
||||
if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE AND WIN32)
|
||||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/full-stack-deployment")
|
||||
find_program(MAKENSIS_COMMAND makensis PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\NSIS])
|
||||
if (NOT MAKENSIS_COMMAND)
|
||||
message(FATAL_ERROR "The Nullsoft Scriptable Install Systems is required for generating packaged installers on Windows (http://nsis.sourceforge.net/)")
|
||||
endif ()
|
||||
add_custom_target(
|
||||
build-package ALL
|
||||
DEPENDS interface assignment-client domain-server stack-manager
|
||||
COMMAND set INSTALLER_SOURCE_DIR=${CMAKE_BINARY_DIR}/full-stack-deployment
|
||||
COMMAND set INSTALLER_NAME=${CMAKE_BINARY_DIR}/${INSTALLER_NAME}
|
||||
COMMAND set INSTALLER_SCRIPTS_DIR=${CMAKE_SOURCE_DIR}/examples
|
||||
COMMAND set INSTALLER_COMPANY=${INSTALLER_COMPANY}
|
||||
COMMAND set INSTALLER_DIRECTORY=${INSTALLER_DIRECTORY}
|
||||
COMMAND CMD /C "\"${MAKENSIS_COMMAND}\" ${CMAKE_SOURCE_DIR}/tools/nsis/release.nsi"
|
||||
)
|
||||
endif ()
|
||||
endmacro()
|
||||
#
|
||||
# GenerateInstallers.cmake
|
||||
# cmake/macros
|
||||
#
|
||||
# Created by Leonardo Murillo on 12/16/2015.
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
macro(GENERATE_INSTALLERS)
|
||||
include(CPackComponent)
|
||||
|
||||
set(CPACK_MODULE_PATH ${CPACK_MODULE_PATH} "${HF_CMAKE_DIR}/templates")
|
||||
|
||||
set(_DISPLAY_NAME ${BUILD_ORGANIZATION})
|
||||
|
||||
set(CPACK_PACKAGE_NAME ${_DISPLAY_NAME})
|
||||
set(CPACK_PACKAGE_VENDOR "High Fidelity")
|
||||
set(CPACK_PACKAGE_VERSION ${BUILD_VERSION})
|
||||
set(CPACK_PACKAGE_FILE_NAME "HighFidelity-Alpha-${BUILD_VERSION}")
|
||||
set(CPACK_NSIS_DISPLAY_NAME ${_DISPLAY_NAME})
|
||||
set(CPACK_NSIS_PACKAGE_NAME ${_DISPLAY_NAME})
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${_DISPLAY_NAME})
|
||||
|
||||
if (WIN32)
|
||||
set(CPACK_NSIS_MUI_ICON "${HF_CMAKE_DIR}/installer/installer.ico")
|
||||
|
||||
# install and reference the Add/Remove icon
|
||||
set(ADD_REMOVE_ICON_NAME "installer.ico")
|
||||
set(ADD_REMOVE_ICON_BAD_PATH "${HF_CMAKE_DIR}/installer/${ADD_REMOVE_ICON_NAME}")
|
||||
fix_path_for_nsis(${ADD_REMOVE_ICON_BAD_PATH} ADD_REMOVE_ICON_PATH)
|
||||
set(CPACK_NSIS_INSTALLED_ICON_NAME ${ADD_REMOVE_ICON_NAME})
|
||||
|
||||
# use macro to put backslashes in header image path since nsis requires them
|
||||
set(_INSTALLER_HEADER_BAD_PATH "${HF_CMAKE_DIR}/installer/installer-header.bmp")
|
||||
set(INSTALLER_HEADER_IMAGE "")
|
||||
fix_path_for_nsis(${_INSTALLER_HEADER_BAD_PATH} INSTALLER_HEADER_IMAGE)
|
||||
|
||||
set(_UNINSTALLER_HEADER_BAD_PATH "${HF_CMAKE_DIR}/installer/uninstaller-header.bmp")
|
||||
set(UNINSTALLER_HEADER_IMAGE "")
|
||||
fix_path_for_nsis(${_UNINSTALLER_HEADER_BAD_PATH} UNINSTALLER_HEADER_IMAGE)
|
||||
elseif (APPLE)
|
||||
# produce a drag and drop DMG on OS X
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "/")
|
||||
set(CPACK_PACKAGING_INSTALL_PREFIX /)
|
||||
set(CPACK_OSX_PACKAGE_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})
|
||||
|
||||
# make sure a High Fidelity directory exists, in case this hits prior to other installs
|
||||
install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${DMG_SUBFOLDER_NAME}\")")
|
||||
|
||||
# add the resource file to the Icon file inside the folder
|
||||
install(CODE
|
||||
"execute_process(COMMAND Rez -append ${DMG_SUBFOLDER_ICON} -o \${CMAKE_INSTALL_PREFIX}/${ESCAPED_DMG_SUBFOLDER_NAME}/Icon\\r)"
|
||||
)
|
||||
|
||||
# modify the folder to use that custom icon
|
||||
install(CODE "execute_process(COMMAND SetFile -a C \${CMAKE_INSTALL_PREFIX}/${ESCAPED_DMG_SUBFOLDER_NAME})")
|
||||
|
||||
# hide the special Icon? file
|
||||
install(CODE "execute_process(COMMAND SetFile -a V \${CMAKE_INSTALL_PREFIX}/${ESCAPED_DMG_SUBFOLDER_NAME}/Icon\\r)")
|
||||
endif ()
|
||||
|
||||
# configure a cpack properties file for custom variables in template
|
||||
set(CPACK_CONFIGURED_PROP_FILE "${CMAKE_CURRENT_BINARY_DIR}/CPackCustomProperties.cmake")
|
||||
configure_file("${HF_CMAKE_DIR}/templates/CPackProperties.cmake.in" ${CPACK_CONFIGURED_PROP_FILE})
|
||||
set(CPACK_PROPERTIES_FILE ${CPACK_CONFIGURED_PROP_FILE})
|
||||
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
||||
|
||||
cpack_add_component(${CLIENT_COMPONENT} DISPLAY_NAME "High Fidelity Client")
|
||||
cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "High Fidelity Server")
|
||||
|
||||
include(CPack)
|
||||
endmacro()
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
#
|
||||
# IncludeApplicationVersion.cmake
|
||||
# cmake/macros
|
||||
#
|
||||
# Created by Leonardo Murillo on 07/14/2015.
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
macro(INCLUDE_APPLICATION_VERSION)
|
||||
#
|
||||
# We are relying on Jenkins defined environment variables to determine the origin of this build
|
||||
# and will only package if this is a PR or Release build
|
||||
if (DEFINED ENV{JOB_ID})
|
||||
set(DEPLOY_PACKAGE 1)
|
||||
set(BUILD_SEQ $ENV{JOB_ID})
|
||||
set(INSTALLER_COMPANY "High Fidelity")
|
||||
set(INSTALLER_DIRECTORY "${INSTALLER_COMPANY}")
|
||||
set(INSTALLER_NAME "interface-win64-${BUILD_SEQ}.exe")
|
||||
elseif (DEFINED ENV{ghprbPullId})
|
||||
set(DEPLOY_PACKAGE 1)
|
||||
set(BUILD_SEQ "PR-$ENV{ghprbPullId}")
|
||||
set(INSTALLER_COMPANY "High Fidelity - PR")
|
||||
set(INSTALLER_DIRECTORY "${INSTALLER_COMPANY}\\${BUILD_SEQ}")
|
||||
set(INSTALLER_NAME "pr-interface-win64-${BUILD_SEQ}.exe")
|
||||
else ()
|
||||
set(BUILD_SEQ "dev")
|
||||
set(INSTALLER_COMPANY "High Fidelity - Dev")
|
||||
set(INSTALLER_DIRECTORY "${INSTALLER_COMPANY}")
|
||||
set(INSTALLER_NAME "dev-interface-win64.exe")
|
||||
endif ()
|
||||
configure_file("${MACRO_DIR}/ApplicationVersion.h.in" "${PROJECT_BINARY_DIR}/includes/ApplicationVersion.h")
|
||||
include_directories("${PROJECT_BINARY_DIR}/includes")
|
||||
endmacro(INCLUDE_APPLICATION_VERSION)
|
72
cmake/macros/InstallBesideConsole.cmake
Normal file
72
cmake/macros/InstallBesideConsole.cmake
Normal file
|
@ -0,0 +1,72 @@
|
|||
#
|
||||
# InstallBesideConsole.cmake
|
||||
# cmake/macros
|
||||
#
|
||||
# Copyright 2016 High Fidelity, Inc.
|
||||
# Created by Stephen Birarda on January 5th, 2016
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
macro(install_beside_console)
|
||||
if (WIN32 OR APPLE)
|
||||
# install this component beside the installed server-console executable
|
||||
if (APPLE)
|
||||
set(CONSOLE_APP_CONTENTS "${CONSOLE_INSTALL_APP_PATH}/Contents")
|
||||
set(COMPONENT_DESTINATION "${CONSOLE_APP_CONTENTS}/MacOS/Components.app/Contents/MacOS")
|
||||
else ()
|
||||
set(COMPONENT_DESTINATION ${CONSOLE_INSTALL_DIR})
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
install(
|
||||
TARGETS ${TARGET_NAME}
|
||||
RUNTIME DESTINATION ${COMPONENT_DESTINATION}
|
||||
COMPONENT ${SERVER_COMPONENT}
|
||||
)
|
||||
else ()
|
||||
# setup install of executable and things copied by fixup/windeployqt
|
||||
install(
|
||||
FILES "$<TARGET_FILE_DIR:${TARGET_NAME}>/"
|
||||
DESTINATION ${COMPONENT_DESTINATION}
|
||||
COMPONENT ${SERVER_COMPONENT}
|
||||
)
|
||||
|
||||
# on windows for PR and production builds, sign the executable
|
||||
set(EXECUTABLE_COMPONENT ${SERVER_COMPONENT})
|
||||
optional_win_executable_signing()
|
||||
endif ()
|
||||
|
||||
if (TARGET_NAME STREQUAL domain-server)
|
||||
if (APPLE)
|
||||
set(RESOURCES_DESTINATION ${COMPONENT_DESTINATION})
|
||||
else ()
|
||||
set(RESOURCES_DESTINATION ${CONSOLE_INSTALL_DIR})
|
||||
endif ()
|
||||
|
||||
# install the resources folder for the domain-server where its executable will be
|
||||
install(
|
||||
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/resources
|
||||
DESTINATION ${RESOURCES_DESTINATION}
|
||||
USE_SOURCE_PERMISSIONS
|
||||
COMPONENT ${SERVER_COMPONENT}
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
# during the install phase, call fixup to drop the shared libraries for these components in the right place
|
||||
set(EXECUTABLE_NEEDING_FIXUP "\${CMAKE_INSTALL_PREFIX}/${COMPONENT_DESTINATION}/${TARGET_NAME}")
|
||||
install(CODE "
|
||||
include(BundleUtilities)
|
||||
fixup_bundle(\"${EXECUTABLE_NEEDING_FIXUP}\" \"\" \"${FIXUP_LIBS}\")
|
||||
" COMPONENT ${SERVER_COMPONENT})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# set variables used by manual ssleay library copy
|
||||
set(TARGET_INSTALL_DIR ${COMPONENT_DESTINATION})
|
||||
set(TARGET_INSTALL_COMPONENT ${SERVER_COMPONENT})
|
||||
manually_install_ssl_eay()
|
||||
|
||||
endmacro()
|
28
cmake/macros/ManuallyInstallSSLEay.cmake
Normal file
28
cmake/macros/ManuallyInstallSSLEay.cmake
Normal file
|
@ -0,0 +1,28 @@
|
|||
#
|
||||
# ManuallyInstallSSLEay.cmake
|
||||
#
|
||||
# Created by Stephen Birarda on 1/15/16.
|
||||
# Copyright 2014 High Fidelity, Inc.
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
macro(manually_install_ssl_eay)
|
||||
|
||||
# on windows we have had issues with targets missing ssleay library
|
||||
# not convinced we actually need it (I assume it would show up in the dependency tree)
|
||||
# but to be safe we install it manually beside the current target
|
||||
if (WIN32)
|
||||
# we need to find SSL_EAY_LIBRARY_* so we can install it beside this target
|
||||
# so we have to call find_package(OpenSSL) here even though this target may not specifically need it
|
||||
find_package(OpenSSL REQUIRED)
|
||||
|
||||
install(
|
||||
FILES "${OPENSSL_DLL_PATH}/ssleay32.dll"
|
||||
DESTINATION ${TARGET_INSTALL_DIR}
|
||||
COMPONENT ${TARGET_INSTALL_COMPONENT}
|
||||
)
|
||||
endif()
|
||||
|
||||
endmacro()
|
34
cmake/macros/OptionalWinExecutableSigning.cmake
Normal file
34
cmake/macros/OptionalWinExecutableSigning.cmake
Normal file
|
@ -0,0 +1,34 @@
|
|||
#
|
||||
# OptionalWinExecutableSigning.cmake
|
||||
# cmake/macros
|
||||
#
|
||||
# Copyright 2016 High Fidelity, Inc.
|
||||
# Created by Stephen Birarda on January 12, 2016
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
macro(optional_win_executable_signing)
|
||||
if (WIN32 AND PRODUCTION_BUILD)
|
||||
if (DEFINED ENV{HF_PFX_FILE})
|
||||
if (DEFINED ENV{HF_PFX_PASSPHRASE})
|
||||
message(STATUS "Executable for ${TARGET_NAME} will be signed with SignTool.")
|
||||
|
||||
if (NOT EXECUTABLE_PATH)
|
||||
set(EXECUTABLE_PATH "$<TARGET_FILE:${TARGET_NAME}>")
|
||||
endif ()
|
||||
|
||||
# setup a post build command to sign the executable
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND ${SIGNTOOL_EXECUTABLE} sign /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://tsa.starfieldtech.com /td SHA256 ${EXECUTABLE_PATH}
|
||||
)
|
||||
else ()
|
||||
message(FATAL_ERROR "HF_PFX_PASSPHRASE must be set for executables to be signed.")
|
||||
endif ()
|
||||
else ()
|
||||
message(WARNING "Creating a production build but not code signing since HF_PFX_FILE is not set.")
|
||||
endif ()
|
||||
endif ()
|
||||
endmacro()
|
|
@ -1,25 +1,24 @@
|
|||
#
|
||||
#
|
||||
# PackageLibrariesForDeployment.cmake
|
||||
# cmake/macros
|
||||
#
|
||||
#
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
# Created by Stephen Birarda on February 17, 2014
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
#
|
||||
|
||||
macro(PACKAGE_LIBRARIES_FOR_DEPLOYMENT)
|
||||
|
||||
if (WIN32)
|
||||
configure_file(
|
||||
${HIFI_CMAKE_DIR}/templates/FixupBundlePostBuild.cmake.in
|
||||
${HF_CMAKE_DIR}/templates/FixupBundlePostBuild.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/FixupBundlePostBuild.cmake
|
||||
@ONLY
|
||||
)
|
||||
|
||||
|
||||
set(PLUGIN_PATH "plugins")
|
||||
|
||||
|
||||
# add a post-build command to copy DLLs beside the executable
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
|
@ -29,31 +28,18 @@ macro(PACKAGE_LIBRARIES_FOR_DEPLOYMENT)
|
|||
-DBUNDLE_PLUGIN_DIR=$<TARGET_FILE_DIR:${TARGET_NAME}>/${PLUGIN_PATH}
|
||||
-P ${CMAKE_CURRENT_BINARY_DIR}/FixupBundlePostBuild.cmake
|
||||
)
|
||||
|
||||
|
||||
find_program(WINDEPLOYQT_COMMAND windeployqt PATHS ${QT_DIR}/bin NO_DEFAULT_PATH)
|
||||
|
||||
|
||||
if (NOT WINDEPLOYQT_COMMAND)
|
||||
message(FATAL_ERROR "Could not find windeployqt at ${QT_DIR}/bin. windeployqt is required.")
|
||||
endif ()
|
||||
|
||||
|
||||
# add a post-build command to call windeployqt to copy Qt plugins
|
||||
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}>"
|
||||
)
|
||||
elseif (DEFINED BUILD_BUNDLE AND BUILD_BUNDLE AND APPLE)
|
||||
find_program(MACDEPLOYQT_COMMAND macdeployqt PATHS ${QT_DIR}/bin NO_DEFAULT_PATH)
|
||||
|
||||
if (NOT MACDEPLOYQT_COMMAND)
|
||||
message(FATAL_ERROR "Could not find macdeployqt at ${QT_DIR}/bin. macdeployqt is required.")
|
||||
endif ()
|
||||
|
||||
# add a post-build command to call macdeployqt to copy Qt plugins
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
POST_BUILD
|
||||
COMMAND ${MACDEPLOYQT_COMMAND} ${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}/${TARGET_NAME}.app -verbose 0
|
||||
)
|
||||
endif ()
|
||||
endmacro()
|
||||
|
|
109
cmake/macros/SetPackagingParameters.cmake
Normal file
109
cmake/macros/SetPackagingParameters.cmake
Normal file
|
@ -0,0 +1,109 @@
|
|||
#
|
||||
# SetPackagingParameters.cmake
|
||||
# cmake/macros
|
||||
#
|
||||
# Created by Leonardo Murillo on 07/14/2015.
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
# This macro checks some Jenkins defined environment variables to determine the origin of this build
|
||||
# and decides how targets should be packaged.
|
||||
|
||||
macro(SET_PACKAGING_PARAMETERS)
|
||||
set(PR_BUILD 0)
|
||||
set(PRODUCTION_BUILD 0)
|
||||
set(DEV_BUILD 0)
|
||||
|
||||
set(RELEASE_TYPE $ENV{RELEASE_TYPE})
|
||||
set(RELEASE_NUMBER $ENV{RELEASE_NUMBER})
|
||||
|
||||
if (RELEASE_TYPE STREQUAL "PRODUCTION")
|
||||
set(DEPLOY_PACKAGE TRUE)
|
||||
set(PRODUCTION_BUILD 1)
|
||||
set(BUILD_VERSION ${RELEASE_NUMBER})
|
||||
set(BUILD_ORGANIZATION "High Fidelity")
|
||||
set(HIGH_FIDELITY_PROTOCOL "hifi")
|
||||
set(INTERFACE_BUNDLE_NAME "High Fidelity")
|
||||
set(INTERFACE_ICON_PREFIX "interface")
|
||||
elseif (RELEASE_TYPE STREQUAL "PR")
|
||||
set(DEPLOY_PACKAGE TRUE)
|
||||
set(PR_BUILD 1)
|
||||
set(BUILD_VERSION "PR${RELEASE_NUMBER}")
|
||||
set(BUILD_ORGANIZATION "High Fidelity - ${BUILD_VERSION}")
|
||||
set(INTERFACE_BUNDLE_NAME "High Fidelity")
|
||||
set(INTERFACE_ICON_PREFIX "interface-beta")
|
||||
else ()
|
||||
set(DEV_BUILD 1)
|
||||
set(BUILD_VERSION "dev")
|
||||
set(BUILD_ORGANIZATION "High Fidelity - ${BUILD_VERSION}")
|
||||
set(INTERFACE_BUNDLE_NAME "Interface")
|
||||
set(INTERFACE_ICON_PREFIX "interface-beta")
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
set(DMG_SUBFOLDER_NAME "${BUILD_ORGANIZATION}")
|
||||
|
||||
set(ESCAPED_DMG_SUBFOLDER_NAME "")
|
||||
string(REPLACE " " "\\ " ESCAPED_DMG_SUBFOLDER_NAME ${DMG_SUBFOLDER_NAME})
|
||||
|
||||
set(DMG_SUBFOLDER_ICON "${HF_CMAKE_DIR}/installer/install-folder.rsrc")
|
||||
|
||||
set(CONSOLE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
||||
set(INTERFACE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
||||
else ()
|
||||
set(CONSOLE_INSTALL_DIR ".")
|
||||
set(INTERFACE_INSTALL_DIR ".")
|
||||
endif ()
|
||||
|
||||
if (WIN32)
|
||||
set(INTERFACE_EXEC_PREFIX "interface")
|
||||
set(INTERFACE_ICON_FILENAME "${INTERFACE_ICON_PREFIX}.ico")
|
||||
|
||||
set(CONSOLE_EXEC_NAME "server-console.exe")
|
||||
|
||||
set(DS_EXEC_NAME "domain-server.exe")
|
||||
set(AC_EXEC_NAME "assignment-client.exe")
|
||||
|
||||
# start menu shortcuts
|
||||
set(INTERFACE_SM_SHORTCUT_NAME "High Fidelity")
|
||||
set(CONSOLE_SM_SHORTCUT_NAME "Server Console")
|
||||
|
||||
# check if we need to find signtool
|
||||
if (PRODUCTION_BUILD OR PR_BUILD)
|
||||
find_program(SIGNTOOL_EXECUTABLE signtool PATHS "C:/Program Files (x86)/Windows Kits/8.1" PATH_SUFFIXES "bin/x64")
|
||||
|
||||
if (NOT SIGNTOOL_EXECUTABLE)
|
||||
message(FATAL_ERROR "Code signing of executables was requested but signtool.exe could not be found.")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(GENERATED_UNINSTALLER_EXEC_NAME "Uninstall.exe")
|
||||
set(REGISTRY_HKLM_INSTALL_ROOT "Software")
|
||||
set(POST_INSTALL_OPTIONS_REG_GROUP "PostInstallOptions")
|
||||
set(CLIENT_DESKTOP_SHORTCUT_REG_KEY "ClientDesktopShortcut")
|
||||
set(CONSOLE_DESKTOP_SHORTCUT_REG_KEY "ConsoleDesktopShortcut")
|
||||
set(CONSOLE_STARTUP_REG_KEY "ConsoleStartupShortcut")
|
||||
set(LAUNCH_NOW_REG_KEY "LaunchAfterInstall")
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
|
||||
set(CONSOLE_EXEC_NAME "Server Console.app")
|
||||
set(CONSOLE_INSTALL_APP_PATH "${CONSOLE_INSTALL_DIR}/${CONSOLE_EXEC_NAME}")
|
||||
|
||||
set(INTERFACE_INSTALL_APP_PATH "${CONSOLE_INSTALL_DIR}/${INTERFACE_BUNDLE_NAME}.app")
|
||||
set(INTERFACE_ICON_FILENAME "${INTERFACE_ICON_PREFIX}.icns")
|
||||
endif()
|
||||
|
||||
# setup component categories for installer
|
||||
set(DDE_COMPONENT dde)
|
||||
set(CLIENT_COMPONENT client)
|
||||
set(SERVER_COMPONENT server)
|
||||
|
||||
# create a header file our targets can use to find out the application version
|
||||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/includes")
|
||||
configure_file("${HF_CMAKE_DIR}/templates/BuildInfo.h.in" "${CMAKE_BINARY_DIR}/includes/BuildInfo.h")
|
||||
|
||||
endmacro(SET_PACKAGING_PARAMETERS)
|
|
@ -12,12 +12,12 @@ macro(SETUP_HIFI_PLUGIN)
|
|||
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Plugins")
|
||||
|
||||
if (APPLE)
|
||||
set(PLUGIN_PATH "interface.app/Contents/MacOS/plugins")
|
||||
set(PLUGIN_PATH "${INTERFACE_BUNDLE_NAME}.app/Contents/PlugIns")
|
||||
else()
|
||||
set(PLUGIN_PATH "plugins")
|
||||
endif()
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_GENERATOR STREQUAL "Unix Makefiles")
|
||||
set(PLUGIN_FULL_PATH "${CMAKE_BINARY_DIR}/interface/${PLUGIN_PATH}/")
|
||||
else()
|
||||
set(PLUGIN_FULL_PATH "${CMAKE_BINARY_DIR}/interface/$<CONFIGURATION>/${PLUGIN_PATH}/")
|
||||
|
@ -35,5 +35,4 @@ macro(SETUP_HIFI_PLUGIN)
|
|||
"$<TARGET_FILE:${TARGET_NAME}>"
|
||||
${PLUGIN_FULL_PATH}
|
||||
)
|
||||
|
||||
endmacro()
|
||||
|
|
|
@ -1,36 +1,35 @@
|
|||
#
|
||||
#
|
||||
# SetupHifiProject.cmake
|
||||
#
|
||||
#
|
||||
# Copyright 2013 High Fidelity, Inc.
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
#
|
||||
|
||||
macro(SETUP_HIFI_PROJECT)
|
||||
project(${TARGET_NAME})
|
||||
|
||||
|
||||
# grab the implemenation and header files
|
||||
file(GLOB TARGET_SRCS src/*)
|
||||
|
||||
|
||||
file(GLOB SRC_SUBDIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/src/*)
|
||||
|
||||
|
||||
foreach(DIR ${SRC_SUBDIRS})
|
||||
if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src/${DIR}")
|
||||
file(GLOB DIR_CONTENTS "src/${DIR}/*")
|
||||
set(TARGET_SRCS ${TARGET_SRCS} "${DIR_CONTENTS}")
|
||||
endif ()
|
||||
endforeach()
|
||||
|
||||
if (DEFINED BUILD_BUNDLE AND BUILD_BUNDLE AND APPLE)
|
||||
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${TARGET_SRCS} ${AUTOMTC_SRC} ${AUTOSCRIBE_SHADER_LIB_SRC})
|
||||
else ()
|
||||
add_executable(${TARGET_NAME} ${TARGET_SRCS} ${AUTOMTC_SRC} ${AUTOSCRIBE_SHADER_LIB_SRC})
|
||||
endif()
|
||||
|
||||
add_executable(${TARGET_NAME} ${TARGET_SRCS} ${AUTOMTC_SRC} ${AUTOSCRIBE_SHADER_LIB_SRC})
|
||||
|
||||
# include the generated application version header
|
||||
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/includes")
|
||||
|
||||
set(${TARGET_NAME}_DEPENDENCY_QT_MODULES ${ARGN})
|
||||
list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES Core)
|
||||
|
||||
|
||||
# find these Qt modules and link them to our own target
|
||||
find_package(Qt5 COMPONENTS ${${TARGET_NAME}_DEPENDENCY_QT_MODULES} REQUIRED)
|
||||
|
||||
|
@ -44,7 +43,7 @@ macro(SETUP_HIFI_PROJECT)
|
|||
foreach(QT_MODULE ${${TARGET_NAME}_DEPENDENCY_QT_MODULES})
|
||||
target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE})
|
||||
endforeach()
|
||||
|
||||
|
||||
target_glm()
|
||||
|
||||
|
||||
endmacro()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# CopyDirectoryBesideTarget.cmake
|
||||
# CopyDirectoryBesideTarget.cmake
|
||||
# cmake/macros
|
||||
#
|
||||
# Created by Stephen Birarda on 04/30/15.
|
||||
|
@ -10,22 +10,22 @@
|
|||
#
|
||||
|
||||
macro(SYMLINK_OR_COPY_DIRECTORY_BESIDE_TARGET _SHOULD_SYMLINK _DIRECTORY _DESTINATION)
|
||||
|
||||
|
||||
# remove the current directory
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E remove_directory $<TARGET_FILE_DIR:${TARGET_NAME}>/${_DESTINATION}
|
||||
)
|
||||
|
||||
|
||||
if (${_SHOULD_SYMLINK})
|
||||
|
||||
|
||||
# first create the destination
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory
|
||||
$<TARGET_FILE_DIR:${TARGET_NAME}>/${_DESTINATION}
|
||||
)
|
||||
|
||||
|
||||
# the caller wants a symlink, so just add a command to symlink all contents of _DIRECTORY
|
||||
# in the destination - we can't simply create a symlink for _DESTINATION
|
||||
# because the remove_directory call above would delete the original files
|
||||
|
@ -35,20 +35,20 @@ macro(SYMLINK_OR_COPY_DIRECTORY_BESIDE_TARGET _SHOULD_SYMLINK _DIRECTORY _DESTIN
|
|||
foreach(_ITEM ${_DIR_ITEMS})
|
||||
# get the filename for this item
|
||||
get_filename_component(_ITEM_FILENAME ${_ITEM} NAME)
|
||||
|
||||
|
||||
# add the command to symlink this item
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E create_symlink
|
||||
${_ITEM}
|
||||
$<TARGET_FILE_DIR:${TARGET_NAME}>/${_DESTINATION}/${_ITEM_FILENAME}
|
||||
)
|
||||
endforeach()
|
||||
)
|
||||
endforeach()
|
||||
else ()
|
||||
# copy the directory
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${_DIRECTORY}
|
||||
TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${_DIRECTORY}
|
||||
$<TARGET_FILE_DIR:${TARGET_NAME}>/${_DESTINATION}
|
||||
)
|
||||
endif ()
|
||||
|
|
|
@ -1,20 +1,28 @@
|
|||
#
|
||||
#
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
# Created by Bradley Austin Davis on 2015/10/10
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
#
|
||||
macro(TARGET_NSIGHT)
|
||||
if (WIN32)
|
||||
if (USE_NSIGHT)
|
||||
if (WIN32 AND USE_NSIGHT)
|
||||
|
||||
# grab the global CHECKED_FOR_NSIGHT_ONCE property
|
||||
get_property(NSIGHT_CHECKED GLOBAL PROPERTY CHECKED_FOR_NSIGHT_ONCE)
|
||||
|
||||
if (NOT NSIGHT_CHECKED)
|
||||
# try to find the Nsight package and add it to the build if we find it
|
||||
find_package(NSIGHT)
|
||||
if (NSIGHT_FOUND)
|
||||
include_directories(${NSIGHT_INCLUDE_DIRS})
|
||||
add_definitions(-DNSIGHT_FOUND)
|
||||
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
|
||||
endif ()
|
||||
endif()
|
||||
endif (WIN32)
|
||||
endmacro()
|
||||
|
||||
# set the global CHECKED_FOR_NSIGHT_ONCE property so that we only debug that we couldn't find it once
|
||||
set_property(GLOBAL PROPERTY CHECKED_FOR_NSIGHT_ONCE TRUE)
|
||||
endif ()
|
||||
|
||||
if (NSIGHT_FOUND)
|
||||
include_directories(${NSIGHT_INCLUDE_DIRS})
|
||||
add_definitions(-DNSIGHT_FOUND)
|
||||
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
|
||||
endif ()
|
||||
endif ()
|
||||
endmacro()
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
#
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
# Created by Leonardo Murillo on 2015/11/20
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
macro(TARGET_QUAZIP)
|
||||
add_dependency_external_projects(quazip)
|
||||
find_package(QuaZip REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${QUAZIP_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${QUAZIP_LIBRARIES})
|
||||
if (WIN32)
|
||||
add_paths_to_fixup_libs(${QUAZIP_DLL_PATH})
|
||||
endif ()
|
||||
endmacro()
|
|
@ -1,14 +1,14 @@
|
|||
#
|
||||
#
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
# Created by Bradley Austin Davis on 2015/10/10
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
#
|
||||
macro(TARGET_SIXENSE)
|
||||
add_dependency_external_projects(sixense)
|
||||
find_package(Sixense REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${SIXENSE_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${SIXENSE_LIBRARIES})
|
||||
add_definitions(-DHAVE_SIXENSE)
|
||||
endmacro()
|
||||
endmacro()
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
# OPENSSL_INCLUDE_DIR - the OpenSSL include directory
|
||||
# OPENSSL_LIBRARIES - The libraries needed to use OpenSSL
|
||||
# OPENSSL_VERSION - This is set to $major.$minor.$revision$path (eg. 0.9.8s)
|
||||
#
|
||||
#
|
||||
# Modified on 7/16/2014 by Stephen Birarda
|
||||
# This is an adapted version of the FindOpenSSL.cmake module distributed with Cmake 2.8.12.2
|
||||
# The original license for that file is displayed below.
|
||||
#
|
||||
#
|
||||
#=============================================================================
|
||||
# Copyright 2006-2009 Kitware, Inc.
|
||||
# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
|
||||
|
@ -50,18 +50,18 @@ if (WIN32)
|
|||
)
|
||||
set(_OPENSSL_ROOT_PATHS "${_programfiles}/OpenSSL" "${_programfiles}/OpenSSL-Win32" "C:/OpenSSL/" "C:/OpenSSL-Win32/")
|
||||
endif()
|
||||
|
||||
|
||||
unset(_programfiles)
|
||||
set(_OPENSSL_ROOT_HINTS_AND_PATHS HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS})
|
||||
|
||||
|
||||
else ()
|
||||
include("${MACRO_DIR}/HifiLibrarySearchHints.cmake")
|
||||
hifi_library_search_hints("openssl")
|
||||
|
||||
|
||||
set(_OPENSSL_ROOT_HINTS_AND_PATHS ${OPENSSL_SEARCH_DIRS})
|
||||
endif ()
|
||||
|
||||
find_path(OPENSSL_INCLUDE_DIR NAMES openssl/ssl.h HINTS ${_OPENSSL_ROOT_HINTS_AND_PATHS} ${_OPENSSL_INCLUDEDIR}
|
||||
find_path(OPENSSL_INCLUDE_DIR NAMES openssl/ssl.h HINTS ${_OPENSSL_ROOT_HINTS_AND_PATHS} ${_OPENSSL_INCLUDEDIR}
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
|
||||
|
@ -81,15 +81,15 @@ if (WIN32 AND NOT CYGWIN)
|
|||
# We are using the libraries located in the VC subdir instead of the parent directory eventhough :
|
||||
# libeay32MD.lib is identical to ../libeay32.lib, and
|
||||
# ssleay32MD.lib is identical to ../ssleay32.lib
|
||||
find_library(LIB_EAY_DEBUG NAMES libeay32MDd libeay32d
|
||||
find_library(LIB_EAY_DEBUG NAMES libeay32MDd libeay32d
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS} PATH_SUFFIXES "lib" "VC" "lib/VC"
|
||||
)
|
||||
|
||||
find_library(LIB_EAY_RELEASE NAMES libeay32MD libeay32
|
||||
find_library(LIB_EAY_RELEASE NAMES libeay32MD libeay32
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS} PATH_SUFFIXES "lib" "VC" "lib/VC"
|
||||
)
|
||||
|
||||
find_library(SSL_EAY_DEBUG NAMES ssleay32MDd ssleay32d
|
||||
find_library(SSL_EAY_DEBUG NAMES ssleay32MDd ssleay32d
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS} PATH_SUFFIXES "lib" "VC" "lib/VC"
|
||||
)
|
||||
|
||||
|
@ -109,22 +109,22 @@ if (WIN32 AND NOT CYGWIN)
|
|||
set(OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY})
|
||||
|
||||
find_path(OPENSSL_DLL_PATH NAMES ssleay32.dll PATH_SUFFIXES "bin" ${_OPENSSL_ROOT_HINTS_AND_PATHS})
|
||||
|
||||
|
||||
elseif (MINGW)
|
||||
# same player, for MinGW
|
||||
set(LIB_EAY_NAMES libeay32)
|
||||
set(SSL_EAY_NAMES ssleay32)
|
||||
|
||||
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
list(APPEND LIB_EAY_NAMES crypto)
|
||||
list(APPEND SSL_EAY_NAMES ssl)
|
||||
endif ()
|
||||
|
||||
|
||||
find_library(LIB_EAY NAMES ${LIB_EAY_NAMES}
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS} PATH_SUFFIXES "lib" "lib/MinGW"
|
||||
)
|
||||
|
||||
find_library(SSL_EAY NAMES ${SSL_EAY_NAMES}
|
||||
find_library(SSL_EAY NAMES ${SSL_EAY_NAMES}
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS} PATH_SUFFIXES "lib" "lib/MinGW"
|
||||
)
|
||||
|
||||
|
@ -147,7 +147,7 @@ else()
|
|||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
find_library(OPENSSL_CRYPTO_LIBRARY NAMES crypto HINTS ${_OPENSSL_ROOT_HINTS_AND_PATHS} ${_OPENSSL_LIBDIR}
|
||||
find_library(OPENSSL_CRYPTO_LIBRARY NAMES crypto HINTS ${_OPENSSL_ROOT_HINTS_AND_PATHS} ${_OPENSSL_LIBDIR}
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
|
@ -196,7 +196,7 @@ if (OPENSSL_INCLUDE_DIR)
|
|||
if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h")
|
||||
file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str
|
||||
REGEX "^#[ ]?define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*")
|
||||
|
||||
|
||||
# The version number is encoded as 0xMNNFFPPS: major minor fix patch status
|
||||
# The status gives if this is a developer or prerelease and is ignored here.
|
||||
# Major, minor, and fix directly translate into the version numbers shown in
|
||||
|
@ -252,15 +252,6 @@ endif ()
|
|||
|
||||
if (WIN32)
|
||||
add_paths_to_fixup_libs(${OPENSSL_DLL_PATH})
|
||||
#
|
||||
# For some reason fixup misses the following DLL and only copies libeay32. There's gotta be a better way to handle this
|
||||
# but for now resorting to the following interm solution
|
||||
if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE)
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy ${OPENSSL_DLL_PATH}/ssleay32.dll ${CMAKE_BINARY_DIR}/full-stack-deployment/
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES OPENSSL_SEARCH_DIRS)
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
#
|
||||
# FindQuaZip.h
|
||||
# StackManagerQt/cmake/modules
|
||||
#
|
||||
# Created by Mohammed Nafees.
|
||||
# Copyright (c) 2014 High Fidelity. All rights reserved.
|
||||
#
|
||||
|
||||
# QUAZIP_FOUND - QuaZip library was found
|
||||
# QUAZIP_INCLUDE_DIR - Path to QuaZip include dir
|
||||
# QUAZIP_INCLUDE_DIRS - Path to QuaZip and zlib include dir (combined from QUAZIP_INCLUDE_DIR + ZLIB_INCLUDE_DIR)
|
||||
# QUAZIP_LIBRARIES - List of QuaZip libraries
|
||||
# QUAZIP_ZLIB_INCLUDE_DIR - The include dir of zlib headers
|
||||
|
||||
include("${MACRO_DIR}/HifiLibrarySearchHints.cmake")
|
||||
hifi_library_search_hints("quazip")
|
||||
|
||||
if (WIN32)
|
||||
find_path(QUAZIP_INCLUDE_DIRS quazip.h PATH_SUFFIXES include/quazip HINTS ${QUAZIP_SEARCH_DIRS})
|
||||
elseif (APPLE)
|
||||
find_path(QUAZIP_INCLUDE_DIRS quazip.h PATH_SUFFIXES include/quazip HINTS ${QUAZIP_SEARCH_DIRS})
|
||||
else ()
|
||||
find_path(QUAZIP_INCLUDE_DIRS quazip.h PATH_SUFFIXES quazip HINTS ${QUAZIP_SEARCH_DIRS})
|
||||
endif ()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(QUAZIP DEFAULT_MSG QUAZIP_INCLUDE_DIRS)
|
||||
|
||||
mark_as_advanced(QUAZIP_INCLUDE_DIRS QUAZIP_SEARCH_DIRS)
|
|
@ -1,12 +1,15 @@
|
|||
//
|
||||
// ApplicationVersion.h.in
|
||||
// BuildInfo.h.in
|
||||
// cmake/macros
|
||||
//
|
||||
// Created by Leonardo Murillo on 8/13/15.
|
||||
// Created by Stephen Birarda on 1/14/16.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
const QString BUILD_VERSION = "@BUILD_SEQ@";
|
||||
namespace BuildInfo {
|
||||
const QString MODIFIED_ORGANIZATION = "@BUILD_ORGANIZATION@";
|
||||
const QString VERSION = "@BUILD_VERSION@";
|
||||
}
|
35
cmake/templates/CPackProperties.cmake.in
Normal file
35
cmake/templates/CPackProperties.cmake.in
Normal file
|
@ -0,0 +1,35 @@
|
|||
#
|
||||
# CPackProperties.cmake.in
|
||||
# cmake/templates
|
||||
#
|
||||
# Copyright 2016 High Fidelity, Inc.
|
||||
# Created by Stephen Birarda on January 11, 2016
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
set(INTERFACE_SHORTCUT_NAME "@INTERFACE_SM_SHORTCUT_NAME@")
|
||||
set(INTERFACE_WIN_EXEC_NAME "@INTERFACE_EXEC_PREFIX@.exe")
|
||||
set(CONSOLE_SHORTCUT_NAME "@CONSOLE_SM_SHORTCUT_NAME@")
|
||||
set(CONSOLE_WIN_EXEC_NAME "@CONSOLE_EXEC_NAME@")
|
||||
set(DS_EXEC_NAME "@DS_EXEC_NAME@")
|
||||
set(AC_EXEC_NAME "@AC_EXEC_NAME@")
|
||||
set(HIGH_FIDELITY_PROTOCOL "@HIGH_FIDELITY_PROTOCOL@")
|
||||
set(PRODUCTION_BUILD "@PRODUCTION_BUILD@")
|
||||
set(PR_BUILD "@PR_BUILD@")
|
||||
set(BUILD_ORGANIZATION "@BUILD_ORGANIZATION@")
|
||||
set(POST_INSTALL_OPTIONS_PATH "@POST_INSTALL_OPTIONS_PATH@")
|
||||
set(CLIENT_COMPONENT_NAME "@CLIENT_COMPONENT@")
|
||||
set(SERVER_COMPONENT_NAME "@SERVER_COMPONENT@")
|
||||
set(SIGNTOOL_EXECUTABLE "@SIGNTOOL_EXECUTABLE@")
|
||||
set(UNINSTALLER_NAME "@GENERATED_UNINSTALLER_EXEC_NAME@")
|
||||
set(REGISTRY_HKLM_INSTALL_ROOT "@REGISTRY_HKLM_INSTALL_ROOT@")
|
||||
set(POST_INSTALL_OPTIONS_REG_GROUP "@POST_INSTALL_OPTIONS_REG_GROUP@")
|
||||
set(CLIENT_DESKTOP_SHORTCUT_REG_KEY "@CLIENT_DESKTOP_SHORTCUT_REG_KEY@")
|
||||
set(CONSOLE_DESKTOP_SHORTCUT_REG_KEY "@CONSOLE_DESKTOP_SHORTCUT_REG_KEY@")
|
||||
set(CONSOLE_STARTUP_REG_KEY "@CONSOLE_STARTUP_REG_KEY@")
|
||||
set(LAUNCH_NOW_REG_KEY "@LAUNCH_NOW_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@")
|
|
@ -1,56 +1,54 @@
|
|||
#
|
||||
#
|
||||
# FixupBundlePostBuild.cmake.in
|
||||
# cmake/templates
|
||||
#
|
||||
#
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
# Created by Stephen Birarda on February 13, 2014
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
#
|
||||
|
||||
include(BundleUtilities)
|
||||
|
||||
|
||||
# replace copy_resolved_item_into_bundle
|
||||
# replace copy_resolved_item_into_bundle
|
||||
#
|
||||
# The official version of copy_resolved_item_into_bundle will print out a "warning:" when
|
||||
# the resolved item matches the resolved embedded item. This not not really an issue that
|
||||
# should rise to the level of a "warning" so we replace this message with a "status:"
|
||||
#
|
||||
function(copy_resolved_item_into_bundle resolved_item resolved_embedded_item)
|
||||
if(WIN32)
|
||||
# ignore case on Windows
|
||||
string(TOLOWER "${resolved_item}" resolved_item_compare)
|
||||
string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare)
|
||||
else()
|
||||
set(resolved_item_compare "${resolved_item}")
|
||||
set(resolved_embedded_item_compare "${resolved_embedded_item}")
|
||||
endif()
|
||||
if (WIN32)
|
||||
# ignore case on Windows
|
||||
string(TOLOWER "${resolved_item}" resolved_item_compare)
|
||||
string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare)
|
||||
else()
|
||||
set(resolved_item_compare "${resolved_item}")
|
||||
set(resolved_embedded_item_compare "${resolved_embedded_item}")
|
||||
endif()
|
||||
|
||||
if("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}")
|
||||
# this is our only change from the original version
|
||||
message(STATUS "status: resolved_item == resolved_embedded_item - not copying...")
|
||||
else()
|
||||
#message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
|
||||
if(UNIX AND NOT APPLE)
|
||||
file(RPATH_REMOVE FILE "${resolved_embedded_item}")
|
||||
endif()
|
||||
if ("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}")
|
||||
# this is our only change from the original version
|
||||
message(STATUS "status: resolved_item == resolved_embedded_item - not copying...")
|
||||
else()
|
||||
#message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
|
||||
if(UNIX AND NOT APPLE)
|
||||
file(RPATH_REMOVE FILE "${resolved_embedded_item}")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
message(STATUS "FIXUP_LIBS for fixup_bundle called for bundle ${BUNDLE_EXECUTABLE} are @FIXUP_LIBS@")
|
||||
|
||||
message(STATUS "Scanning for plugins from ${BUNDLE_PLUGIN_DIR}")
|
||||
|
||||
if (APPLE)
|
||||
set(PLUGIN_EXTENSION "dylib")
|
||||
elseif (WIN32)
|
||||
set(PLUGIN_EXTENSION "dll")
|
||||
else()
|
||||
set(PLUGIN_EXTENSION "so")
|
||||
set(PLUGIN_EXTENSION "dylib")
|
||||
elseif (WIN32)
|
||||
set(PLUGIN_EXTENSION "dll")
|
||||
else()
|
||||
set(PLUGIN_EXTENSION "so")
|
||||
endif()
|
||||
|
||||
file(GLOB RUNTIME_PLUGINS "${BUNDLE_PLUGIN_DIR}/*.${PLUGIN_EXTENSION}")
|
||||
fixup_bundle("${BUNDLE_EXECUTABLE}" "${RUNTIME_PLUGINS}" "@FIXUP_LIBS@")
|
||||
file(GLOB EXTRA_PLUGINS "${BUNDLE_PLUGIN_DIR}/*.${PLUGIN_EXTENSION}")
|
||||
fixup_bundle("${BUNDLE_EXECUTABLE}" "${EXTRA_PLUGINS}" "@FIXUP_LIBS@")
|
||||
|
|
1
cmake/templates/Icon.rc.in
Normal file
1
cmake/templates/Icon.rc.in
Normal file
|
@ -0,0 +1 @@
|
|||
IDI_ICON1 ICON DISCARDABLE "@CONFIGURE_ICON_PATH@"
|
1364
cmake/templates/NSIS.template.in
Normal file
1364
cmake/templates/NSIS.template.in
Normal file
File diff suppressed because it is too large
Load diff
4
cmake/templates/console-build-info.json.in
Normal file
4
cmake/templates/console-build-info.json.in
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"releaseType": "@RELEASE_TYPE@",
|
||||
"buildIdentifier": "@BUILD_VERSION@"
|
||||
}
|
|
@ -34,8 +34,10 @@ target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES})
|
|||
# libcrypto uses dlopen in libdl
|
||||
if (UNIX)
|
||||
target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS})
|
||||
endif (UNIX)
|
||||
endif ()
|
||||
|
||||
include_application_version()
|
||||
package_libraries_for_deployment()
|
||||
consolidate_stack_components()
|
||||
if (WIN32)
|
||||
package_libraries_for_deployment()
|
||||
endif ()
|
||||
|
||||
install_beside_console()
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
{
|
||||
"name": "viewpoint",
|
||||
"label": "Viewpoint",
|
||||
"placeholder": "/512,512,512"
|
||||
"placeholder": "/0,0,0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -308,7 +308,7 @@
|
|||
"type": "checkbox",
|
||||
"label": "Dynamic Jitter Buffers",
|
||||
"help": "Dynamically buffer client audio based on perceived jitter in packet receipt timing",
|
||||
"default": false,
|
||||
"default": true,
|
||||
"advanced": true
|
||||
},
|
||||
{
|
||||
|
@ -386,8 +386,8 @@
|
|||
"name": "persistFilename",
|
||||
"label": "Entities Filename",
|
||||
"help": "the path to the file entities are stored in. Make sure the path exists.",
|
||||
"placeholder": "resources/models.json.gz",
|
||||
"default": "resources/models.json.gz",
|
||||
"placeholder": "models.json.gz",
|
||||
"default": "models.json.gz",
|
||||
"advanced": true
|
||||
},
|
||||
{
|
||||
|
|
|
@ -126,6 +126,20 @@ var viewHelpers = {
|
|||
}
|
||||
}
|
||||
|
||||
var qs = (function(a) {
|
||||
if (a == "") return {};
|
||||
var b = {};
|
||||
for (var i = 0; i < a.length; ++i)
|
||||
{
|
||||
var p=a[i].split('=', 2);
|
||||
if (p.length == 1)
|
||||
b[p[0]] = "";
|
||||
else
|
||||
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
|
||||
}
|
||||
return b;
|
||||
})(window.location.search.substr(1).split('&'));
|
||||
|
||||
$(document).ready(function(){
|
||||
/*
|
||||
* Clamped-width.
|
||||
|
@ -272,9 +286,80 @@ $(document).ready(function(){
|
|||
|
||||
// $('body').scrollspy({ target: '#setup-sidebar'})
|
||||
|
||||
reloadSettings();
|
||||
reloadSettings(function(success){
|
||||
if (success) {
|
||||
handleAction();
|
||||
} else {
|
||||
swal({
|
||||
title: '',
|
||||
type: 'error',
|
||||
text: "There was a problem loading the domain settings.\nPlease refresh the page to try again.",
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function handleAction() {
|
||||
// check if we were passed an action to handle
|
||||
var action = qs["action"];
|
||||
|
||||
if (action == "share") {
|
||||
// figure out if we already have a stored domain ID
|
||||
if (Settings.data.values.metaverse.id.length > 0) {
|
||||
// we need to ask the API what a shareable name for this domain is
|
||||
getDomainFromAPI(function(data){
|
||||
// check if we have owner_places (for a real domain) or a name (for a temporary domain)
|
||||
if (data && data.status == "success") {
|
||||
var shareName;
|
||||
if (data.domain.owner_places) {
|
||||
shareName = data.domain.owner_places[0].name
|
||||
} else if (data.domain.name) {
|
||||
shareName = data.domain.name;
|
||||
}
|
||||
|
||||
var shareLink = "hifi://" + shareName;
|
||||
|
||||
console.log(shareLink);
|
||||
|
||||
// show a dialog with a copiable share URL
|
||||
swal({
|
||||
title: "Share",
|
||||
type: "input",
|
||||
inputPlaceholder: shareLink,
|
||||
inputValue: shareLink,
|
||||
text: "Copy this URL to invite friends to your domain.",
|
||||
closeOnConfirm: true
|
||||
});
|
||||
|
||||
$('.sweet-alert input').select();
|
||||
|
||||
} else {
|
||||
// show an error alert
|
||||
swal({
|
||||
title: '',
|
||||
type: 'error',
|
||||
text: "There was a problem retreiving domain information from High Fidelity API.",
|
||||
confirmButtonText: 'Try again',
|
||||
showCancelButton: true,
|
||||
closeOnConfirm: false
|
||||
}, function(isConfirm){
|
||||
if (isConfirm) {
|
||||
// they want to try getting domain share info again
|
||||
showSpinnerAlert("Requesting domain information...")
|
||||
handleAction();
|
||||
} else {
|
||||
swal.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// no domain ID present, just show the share dialog
|
||||
createTemporaryDomain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dynamicButton(button_id, text) {
|
||||
return $("<button type='button' id='" + button_id + "' class='btn btn-primary'>" + text + "</button>");
|
||||
}
|
||||
|
@ -577,29 +662,33 @@ function placeTableRowForPlaceObject(place) {
|
|||
return placeTableRow(place.name, placePathOrIndex, false);
|
||||
}
|
||||
|
||||
function reloadPlacesOrTemporaryName() {
|
||||
function getDomainFromAPI(callback) {
|
||||
// we only need to do this if we have a current domain ID
|
||||
var domainID = Settings.data.values.metaverse.id;
|
||||
if (domainID.length > 0) {
|
||||
var domainURL = Settings.METAVERSE_URL + "/api/v1/domains/" + domainID;
|
||||
|
||||
$.getJSON(domainURL, function(data){
|
||||
// check if we have owner_places (for a real domain) or a name (for a temporary domain)
|
||||
if (data.status == "success") {
|
||||
if (data.domain.owner_places) {
|
||||
// add a table row for each of these names
|
||||
_.each(data.domain.owner_places, function(place){
|
||||
$('#' + Settings.PLACES_TABLE_ID + " tbody").append(placeTableRowForPlaceObject(place));
|
||||
});
|
||||
} else if (data.domain.name) {
|
||||
// add a table row for this temporary domain name
|
||||
$('#' + Settings.PLACES_TABLE_ID + " tbody").append(placeTableRow(data.domain.name, '/', true));
|
||||
}
|
||||
}
|
||||
});
|
||||
$.getJSON(domainURL, callback).fail(callback);
|
||||
}
|
||||
}
|
||||
|
||||
function reloadPlacesOrTemporaryName() {
|
||||
getDomainFromAPI(function(data){
|
||||
// check if we have owner_places (for a real domain) or a name (for a temporary domain)
|
||||
if (data.status == "success") {
|
||||
if (data.domain.owner_places) {
|
||||
// add a table row for each of these names
|
||||
_.each(data.domain.owner_places, function(place){
|
||||
$('#' + Settings.PLACES_TABLE_ID + " tbody").append(placeTableRowForPlaceObject(place));
|
||||
});
|
||||
} else if (data.domain.name) {
|
||||
// add a table row for this temporary domain name
|
||||
$('#' + Settings.PLACES_TABLE_ID + " tbody").append(placeTableRow(data.domain.name, '/', true));
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function appendDomainIDButtons() {
|
||||
var domainIDInput = $(Settings.DOMAIN_ID_SELECTOR);
|
||||
|
||||
|
@ -728,7 +817,7 @@ function createTemporaryDomain() {
|
|||
});
|
||||
}
|
||||
|
||||
function reloadSettings() {
|
||||
function reloadSettings(callback) {
|
||||
$.getJSON('/settings.json', function(data){
|
||||
_.extend(data, viewHelpers)
|
||||
|
||||
|
@ -757,6 +846,12 @@ function reloadSettings() {
|
|||
placement: 'right',
|
||||
title: 'This setting is in the master config file and cannot be changed'
|
||||
});
|
||||
|
||||
// call the callback now that settings are loaded
|
||||
callback(true);
|
||||
}).fail(function() {
|
||||
// call the failure object since settings load faild
|
||||
callback(false)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -24,7 +24,7 @@
|
|||
#include <QUrlQuery>
|
||||
|
||||
#include <AccountManager.h>
|
||||
#include <ApplicationVersion.h>
|
||||
#include <BuildInfo.h>
|
||||
#include <HifiConfigVariantMap.h>
|
||||
#include <HTTPConnection.h>
|
||||
#include <LogUtils.h>
|
||||
|
@ -35,6 +35,7 @@
|
|||
#include <ShutdownEventListener.h>
|
||||
#include <UUID.h>
|
||||
#include <LogHandler.h>
|
||||
#include <ServerPathUtils.h>
|
||||
|
||||
#include "DomainServerNodeData.h"
|
||||
#include "NodeConnectionData.h"
|
||||
|
@ -46,7 +47,7 @@ const QString ICE_SERVER_DEFAULT_HOSTNAME = "ice.highfidelity.io";
|
|||
DomainServer::DomainServer(int argc, char* argv[]) :
|
||||
QCoreApplication(argc, argv),
|
||||
_gatekeeper(this),
|
||||
_httpManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this),
|
||||
_httpManager(QHostAddress::AnyIPv4, DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this),
|
||||
_httpsManager(NULL),
|
||||
_allAssignments(),
|
||||
_unfulfilledAssignments(),
|
||||
|
@ -64,24 +65,22 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
|
||||
LogUtils::init();
|
||||
Setting::init();
|
||||
|
||||
// to work around the Qt constant wireless scanning, set the env for polling interval very high
|
||||
const QByteArray EXTREME_BEARER_POLL_TIMEOUT = QString::number(INT_MAX).toLocal8Bit();
|
||||
qputenv("QT_BEARER_POLL_TIMEOUT", EXTREME_BEARER_POLL_TIMEOUT);
|
||||
|
||||
connect(this, &QCoreApplication::aboutToQuit, this, &DomainServer::aboutToQuit);
|
||||
|
||||
setOrganizationName("High Fidelity");
|
||||
setOrganizationName(BuildInfo::MODIFIED_ORGANIZATION);
|
||||
setOrganizationDomain("highfidelity.io");
|
||||
setApplicationName("domain-server");
|
||||
setApplicationVersion(BUILD_VERSION);
|
||||
setApplicationVersion(BuildInfo::VERSION);
|
||||
QSettings::setDefaultFormat(QSettings::IniFormat);
|
||||
|
||||
// make sure we have a fresh AccountManager instance
|
||||
// (need this since domain-server can restart itself and maintain static variables)
|
||||
AccountManager::getInstance(true);
|
||||
|
||||
_settingsManager.setupConfigMap(arguments());
|
||||
auto args = arguments();
|
||||
|
||||
_settingsManager.setupConfigMap(args);
|
||||
|
||||
// setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us
|
||||
#ifdef _WIN32
|
||||
|
@ -110,6 +109,8 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
|
||||
// preload some user public keys so they can connect on first request
|
||||
_gatekeeper.preloadAllowedUserPublicKeys();
|
||||
|
||||
optionallyGetTemporaryName(args);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,7 +158,7 @@ bool DomainServer::optionallyReadX509KeyAndCertificate() {
|
|||
QSslCertificate sslCertificate(&certFile);
|
||||
QSslKey privateKey(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, keyPassphraseString.toUtf8());
|
||||
|
||||
_httpsManager = new HTTPSManager(DOMAIN_SERVER_HTTPS_PORT, sslCertificate, privateKey, QString(), this, this);
|
||||
_httpsManager = new HTTPSManager(QHostAddress::AnyIPv4, DOMAIN_SERVER_HTTPS_PORT, sslCertificate, privateKey, QString(), this, this);
|
||||
|
||||
qDebug() << "TCP server listening for HTTPS connections on" << DOMAIN_SERVER_HTTPS_PORT;
|
||||
|
||||
|
@ -209,6 +210,80 @@ bool DomainServer::optionallySetupOAuth() {
|
|||
return true;
|
||||
}
|
||||
|
||||
static const QString METAVERSE_DOMAIN_ID_KEY_PATH = "metaverse.id";
|
||||
|
||||
void DomainServer::optionallyGetTemporaryName(const QStringList& arguments) {
|
||||
// check for the temporary name parameter
|
||||
const QString GET_TEMPORARY_NAME_SWITCH = "--get-temp-name";
|
||||
|
||||
if (arguments.contains(GET_TEMPORARY_NAME_SWITCH)) {
|
||||
|
||||
// make sure we don't already have a domain ID
|
||||
const QVariant* idValueVariant = valueForKeyPath(_settingsManager.getSettingsMap(), METAVERSE_DOMAIN_ID_KEY_PATH);
|
||||
if (idValueVariant) {
|
||||
qWarning() << "Temporary domain name requested but a domain ID is already present in domain-server settings."
|
||||
<< "Will not request temporary name.";
|
||||
return;
|
||||
}
|
||||
|
||||
// we've been asked to grab a temporary name from the API
|
||||
// so fire off that request now
|
||||
auto& accountManager = AccountManager::getInstance();
|
||||
|
||||
// ask our auth endpoint for our balance
|
||||
JSONCallbackParameters callbackParameters;
|
||||
callbackParameters.jsonCallbackReceiver = this;
|
||||
callbackParameters.jsonCallbackMethod = "handleTempDomainSuccess";
|
||||
callbackParameters.errorCallbackReceiver = this;
|
||||
callbackParameters.errorCallbackMethod = "handleTempDomainError";
|
||||
|
||||
accountManager.sendRequest("/api/v1/domains/temporary", AccountManagerAuth::None,
|
||||
QNetworkAccessManager::PostOperation, callbackParameters);
|
||||
}
|
||||
}
|
||||
|
||||
void DomainServer::handleTempDomainSuccess(QNetworkReply& requestReply) {
|
||||
QJsonObject jsonObject = QJsonDocument::fromJson(requestReply.readAll()).object();
|
||||
|
||||
// grab the information for the new domain
|
||||
static const QString DATA_KEY = "data";
|
||||
static const QString DOMAIN_KEY = "domain";
|
||||
static const QString ID_KEY = "id";
|
||||
static const QString NAME_KEY = "name";
|
||||
|
||||
auto domainObject = jsonObject[DATA_KEY].toObject()[DOMAIN_KEY].toObject();
|
||||
if (!domainObject.isEmpty()) {
|
||||
auto id = domainObject[ID_KEY].toString();
|
||||
auto name = domainObject[NAME_KEY].toString();
|
||||
|
||||
qInfo() << "Received new temporary domain name" << name;
|
||||
qDebug() << "The temporary domain ID is" << id;
|
||||
|
||||
// store the new domain ID and auto network setting immediately
|
||||
QString newSettingsJSON = QString("{\"metaverse\": { \"id\": \"%1\", \"automatic_networking\": \"full\"}}").arg(id);
|
||||
auto settingsDocument = QJsonDocument::fromJson(newSettingsJSON.toUtf8());
|
||||
_settingsManager.recurseJSONObjectAndOverwriteSettings(settingsDocument.object());
|
||||
|
||||
// store the new ID and auto networking setting on disk
|
||||
_settingsManager.persistToFile();
|
||||
|
||||
// change our domain ID immediately
|
||||
DependencyManager::get<LimitedNodeList>()->setSessionUUID(QUuid { id });
|
||||
|
||||
// change our automatic networking settings so that we're communicating with the ICE server
|
||||
setupICEHeartbeatForFullNetworking();
|
||||
|
||||
} else {
|
||||
qWarning() << "There were problems parsing the API response containing a temporary domain name. Please try again"
|
||||
<< "via domain-server relaunch or from the domain-server settings.";
|
||||
}
|
||||
}
|
||||
|
||||
void DomainServer::handleTempDomainError(QNetworkReply& requestReply) {
|
||||
qWarning() << "A temporary name was requested but there was an error creating one. Please try again via domain-server relaunch"
|
||||
<< "or from the domain-server settings.";
|
||||
}
|
||||
|
||||
const QString DOMAIN_CONFIG_ID_KEY = "id";
|
||||
|
||||
const QString METAVERSE_AUTOMATIC_NETWORKING_KEY_PATH = "metaverse.automatic_networking";
|
||||
|
@ -259,7 +334,6 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) {
|
|||
|
||||
// set our LimitedNodeList UUID to match the UUID from our config
|
||||
// nodes will currently use this to add resources to data-web that relate to our domain
|
||||
const QString METAVERSE_DOMAIN_ID_KEY_PATH = "metaverse.id";
|
||||
const QVariant* idValueVariant = valueForKeyPath(settingsMap, METAVERSE_DOMAIN_ID_KEY_PATH);
|
||||
if (idValueVariant) {
|
||||
nodeList->setSessionUUID(idValueVariant->toString());
|
||||
|
@ -372,19 +446,7 @@ void DomainServer::setupAutomaticNetworking() {
|
|||
_settingsManager.valueOrDefaultValueForKeyPath(METAVERSE_AUTOMATIC_NETWORKING_KEY_PATH).toString();
|
||||
|
||||
if (_automaticNetworkingSetting == FULL_AUTOMATIC_NETWORKING_VALUE) {
|
||||
// call our sendHeartbeatToIceServer immediately anytime a local or public socket changes
|
||||
connect(nodeList.data(), &LimitedNodeList::localSockAddrChanged,
|
||||
this, &DomainServer::sendHeartbeatToIceServer);
|
||||
connect(nodeList.data(), &LimitedNodeList::publicSockAddrChanged,
|
||||
this, &DomainServer::sendHeartbeatToIceServer);
|
||||
|
||||
// we need this DS to know what our public IP is - start trying to figure that out now
|
||||
nodeList->startSTUNPublicSocketUpdate();
|
||||
|
||||
// setup a timer to heartbeat with the ice-server every so often
|
||||
QTimer* iceHeartbeatTimer = new QTimer(this);
|
||||
connect(iceHeartbeatTimer, &QTimer::timeout, this, &DomainServer::sendHeartbeatToIceServer);
|
||||
iceHeartbeatTimer->start(ICE_HEARBEAT_INTERVAL_MSECS);
|
||||
setupICEHeartbeatForFullNetworking();
|
||||
}
|
||||
|
||||
if (!didSetupAccountManagerWithAccessToken()) {
|
||||
|
@ -434,6 +496,26 @@ void DomainServer::setupAutomaticNetworking() {
|
|||
dataHeartbeatTimer->start(DOMAIN_SERVER_DATA_WEB_HEARTBEAT_MSECS);
|
||||
}
|
||||
|
||||
void DomainServer::setupICEHeartbeatForFullNetworking() {
|
||||
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
|
||||
|
||||
// call our sendHeartbeatToIceServer immediately anytime a local or public socket changes
|
||||
connect(limitedNodeList.data(), &LimitedNodeList::localSockAddrChanged,
|
||||
this, &DomainServer::sendHeartbeatToIceServer);
|
||||
connect(limitedNodeList.data(), &LimitedNodeList::publicSockAddrChanged,
|
||||
this, &DomainServer::sendHeartbeatToIceServer);
|
||||
|
||||
// we need this DS to know what our public IP is - start trying to figure that out now
|
||||
limitedNodeList->startSTUNPublicSocketUpdate();
|
||||
|
||||
if (!_iceHeartbeatTimer) {
|
||||
// setup a timer to heartbeat with the ice-server every so often
|
||||
_iceHeartbeatTimer = new QTimer { this };
|
||||
connect(_iceHeartbeatTimer, &QTimer::timeout, this, &DomainServer::sendHeartbeatToIceServer);
|
||||
_iceHeartbeatTimer->start(ICE_HEARBEAT_INTERVAL_MSECS);
|
||||
}
|
||||
}
|
||||
|
||||
void DomainServer::loginFailed() {
|
||||
qDebug() << "Login to data server has failed. domain-server will now quit";
|
||||
QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection);
|
||||
|
@ -1068,7 +1150,7 @@ QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
|
|||
|
||||
const char ASSIGNMENT_SCRIPT_HOST_LOCATION[] = "resources/web/assignment";
|
||||
QString pathForAssignmentScript(const QUuid& assignmentUUID) {
|
||||
QString newPath(ASSIGNMENT_SCRIPT_HOST_LOCATION);
|
||||
QString newPath { ServerPathUtils::getDataDirectory() + "/" + QString(ASSIGNMENT_SCRIPT_HOST_LOCATION) };
|
||||
newPath += "/scripts/";
|
||||
// append the UUID for this script as the new filename, remove the curly braces
|
||||
newPath += uuidStringWithoutCurlyBraces(assignmentUUID);
|
||||
|
@ -1786,16 +1868,25 @@ void DomainServer::processPathQueryPacket(QSharedPointer<ReceivedMessage> messag
|
|||
|
||||
const QString PATHS_SETTINGS_KEYPATH_FORMAT = "%1.%2";
|
||||
const QString PATH_VIEWPOINT_KEY = "viewpoint";
|
||||
const QString INDEX_PATH = "/";
|
||||
|
||||
// check out paths in the _configMap to see if we have a match
|
||||
const QVariant* pathMatch = valueForKeyPath(_settingsManager.getSettingsMap(),
|
||||
QString(PATHS_SETTINGS_KEYPATH_FORMAT).arg(SETTINGS_PATHS_KEY)
|
||||
.arg(pathQuery));
|
||||
if (pathMatch) {
|
||||
auto keypath = QString(PATHS_SETTINGS_KEYPATH_FORMAT).arg(SETTINGS_PATHS_KEY).arg(pathQuery);
|
||||
const QVariant* pathMatch = valueForKeyPath(_settingsManager.getSettingsMap(), keypath);
|
||||
|
||||
if (pathMatch || pathQuery == INDEX_PATH) {
|
||||
// we got a match, respond with the resulting viewpoint
|
||||
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
||||
|
||||
QString responseViewpoint = pathMatch->toMap()[PATH_VIEWPOINT_KEY].toString();
|
||||
QString responseViewpoint;
|
||||
|
||||
// if we didn't match the path BUT this is for the index path then send back our default
|
||||
if (pathMatch) {
|
||||
responseViewpoint = pathMatch->toMap()[PATH_VIEWPOINT_KEY].toString();
|
||||
} else {
|
||||
const QString DEFAULT_INDEX_PATH = "/0,0,0/0,0,0,1";
|
||||
responseViewpoint = DEFAULT_INDEX_PATH;
|
||||
}
|
||||
|
||||
if (!responseViewpoint.isEmpty()) {
|
||||
QByteArray viewpointUTF8 = responseViewpoint.toUtf8();
|
||||
|
|
|
@ -74,6 +74,9 @@ private slots:
|
|||
void sendHeartbeatToIceServer();
|
||||
|
||||
void handleConnectedNode(SharedNodePointer newNode);
|
||||
|
||||
void handleTempDomainSuccess(QNetworkReply& requestReply);
|
||||
void handleTempDomainError(QNetworkReply& requestReply);
|
||||
|
||||
private:
|
||||
void setupNodeListAndAssignments(const QUuid& sessionUUID = QUuid::createUuid());
|
||||
|
@ -81,10 +84,13 @@ private:
|
|||
bool optionallyReadX509KeyAndCertificate();
|
||||
bool optionallySetupAssignmentPayment();
|
||||
|
||||
void optionallyGetTemporaryName(const QStringList& arguments);
|
||||
|
||||
bool didSetupAccountManagerWithAccessToken();
|
||||
bool resetAccountManagerAccessToken();
|
||||
|
||||
void setupAutomaticNetworking();
|
||||
void setupICEHeartbeatForFullNetworking();
|
||||
void sendHeartbeatToDataServer(const QString& networkAddress);
|
||||
|
||||
unsigned int countConnectedUsers();
|
||||
|
@ -144,6 +150,8 @@ private:
|
|||
DomainServerSettingsManager _settingsManager;
|
||||
|
||||
HifiSockAddr _iceServerSocket;
|
||||
|
||||
QTimer* _iceHeartbeatTimer { nullptr }; // this looks like it dangles when created but it's parented to the DomainServer
|
||||
|
||||
friend class DomainGatekeeper;
|
||||
};
|
||||
|
|
|
@ -193,7 +193,7 @@ bool DomainServerSettingsManager::handleAuthenticatedHTTPRequest(HTTPConnection
|
|||
qDebug() << "DomainServerSettingsManager postedObject -" << postedObject;
|
||||
|
||||
// we recurse one level deep below each group for the appropriate setting
|
||||
recurseJSONObjectAndOverwriteSettings(postedObject, _configMap.getUserConfig());
|
||||
recurseJSONObjectAndOverwriteSettings(postedObject);
|
||||
|
||||
// store whatever the current _settingsMap is to file
|
||||
persistToFile();
|
||||
|
@ -407,8 +407,9 @@ QJsonObject DomainServerSettingsManager::settingDescriptionFromGroup(const QJson
|
|||
return QJsonObject();
|
||||
}
|
||||
|
||||
void DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJsonObject& postedObject,
|
||||
QVariantMap& settingsVariant) {
|
||||
void DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJsonObject& postedObject) {
|
||||
auto& settingsVariant = _configMap.getUserConfig();
|
||||
|
||||
// Iterate on the setting groups
|
||||
foreach(const QString& rootKey, postedObject.keys()) {
|
||||
QJsonValue rootValue = postedObject[rootKey];
|
||||
|
@ -481,6 +482,9 @@ void DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJ
|
|||
settingsVariant.remove(rootKey);
|
||||
}
|
||||
}
|
||||
|
||||
// re-merge the user and master configs after a settings change
|
||||
_configMap.mergeMasterAndUserConfigs();
|
||||
}
|
||||
|
||||
void DomainServerSettingsManager::persistToFile() {
|
||||
|
|
|
@ -46,7 +46,7 @@ private slots:
|
|||
|
||||
private:
|
||||
QJsonObject responseObjectForType(const QString& typeValue, bool isAuthenticated = false);
|
||||
void recurseJSONObjectAndOverwriteSettings(const QJsonObject& postedObject, QVariantMap& settingsVariant);
|
||||
void recurseJSONObjectAndOverwriteSettings(const QJsonObject& postedObject);
|
||||
|
||||
void updateSetting(const QString& key, const QJsonValue& newValue, QVariantMap& settingMap,
|
||||
const QJsonObject& settingDescription);
|
||||
|
@ -56,6 +56,8 @@ private:
|
|||
double _descriptionVersion;
|
||||
QJsonArray _descriptionArray;
|
||||
HifiConfigVariantMap _configMap;
|
||||
|
||||
friend class DomainServer;
|
||||
};
|
||||
|
||||
#endif // hifi_DomainServerSettingsManager_h
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "DomainServer.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
disableQtBearerPoll(); // Fixes wifi ping spikes
|
||||
|
||||
#ifndef WIN32
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
#endif
|
||||
|
|
|
@ -108,7 +108,7 @@ var GRABBABLE_PROPERTIES = [
|
|||
"position",
|
||||
"rotation",
|
||||
"gravity",
|
||||
"collisionMask",
|
||||
"collidesWith",
|
||||
"collisionsWillMove",
|
||||
"locked",
|
||||
"name",
|
||||
|
@ -134,12 +134,11 @@ var blacklist = [];
|
|||
//we've created various ways of visualizing looking for and moving distant objects
|
||||
var USE_ENTITY_LINES_FOR_SEARCHING = false;
|
||||
var USE_OVERLAY_LINES_FOR_SEARCHING = true;
|
||||
var USE_PARTICLE_BEAM_FOR_SEARCHING = false;
|
||||
|
||||
var USE_ENTITY_LINES_FOR_MOVING = false;
|
||||
var USE_OVERLAY_LINES_FOR_MOVING = false;
|
||||
var USE_PARTICLE_BEAM_FOR_MOVING = true;
|
||||
var TEMPORARY_PARTICLE_BEAM_LIFETIME = 30;
|
||||
|
||||
|
||||
var USE_SPOTLIGHT = false;
|
||||
var USE_POINTLIGHT = false;
|
||||
|
@ -163,9 +162,9 @@ var STATE_CONTINUE_EQUIP = 14;
|
|||
var STATE_WAITING_FOR_BUMPER_RELEASE = 15;
|
||||
var STATE_EQUIP_SPRING = 16;
|
||||
|
||||
// collision masks are specified by comma-separated list of group names
|
||||
// the possible list of names is: static, dynamic, kinematic, myAvatar, otherAvatar
|
||||
var COLLISION_MASK_WHILE_GRABBED = "dynamic,otherAvatar";
|
||||
// "collidesWith" is specified by comma-separated list of group names
|
||||
// the possible group names are: static, dynamic, kinematic, myAvatar, otherAvatar
|
||||
var COLLIDES_WITH_WHILE_GRABBED = "dynamic,otherAvatar";
|
||||
|
||||
function stateToName(state) {
|
||||
switch (state) {
|
||||
|
@ -475,24 +474,6 @@ function MyController(hand) {
|
|||
}
|
||||
};
|
||||
|
||||
this.handleParticleBeam = function(position, orientation, color) {
|
||||
|
||||
var rotation = Quat.angleAxis(0, {
|
||||
x: 1,
|
||||
y: 0,
|
||||
z: 0
|
||||
});
|
||||
|
||||
var finalRotation = Quat.multiply(orientation, rotation);
|
||||
var lifespan = LINE_LENGTH / 10;
|
||||
var speed = 5;
|
||||
var spread = 2;
|
||||
if (this.particleBeam === null) {
|
||||
this.createParticleBeam(position, finalRotation, color, speed, spread, lifespan);
|
||||
} else {
|
||||
this.updateParticleBeam(position, finalRotation, color, speed, spread, lifespan);
|
||||
}
|
||||
};
|
||||
|
||||
this.handleDistantParticleBeam = function(handPosition, objectPosition, color) {
|
||||
|
||||
|
@ -505,7 +486,6 @@ function MyController(hand) {
|
|||
|
||||
var lifespan = distance / speed;
|
||||
|
||||
|
||||
if (this.particleBeam === null) {
|
||||
this.createParticleBeam(objectPosition, finalRotation, color, speed, spread, lifespan);
|
||||
} else {
|
||||
|
@ -520,6 +500,7 @@ function MyController(hand) {
|
|||
isEmitting: true,
|
||||
position: position,
|
||||
visible: false,
|
||||
lifetime: 60,
|
||||
"name": "Particle Beam",
|
||||
"color": color,
|
||||
"maxParticles": 2000,
|
||||
|
@ -555,15 +536,6 @@ function MyController(hand) {
|
|||
},
|
||||
"particleRadius": 0.015,
|
||||
"radiusSpread": 0.005,
|
||||
// "radiusStart": 0.01,
|
||||
// "radiusFinish": 0.01,
|
||||
// "colorSpread": {
|
||||
// "red": 0,
|
||||
// "green": 0,
|
||||
// "blue": 0
|
||||
// },
|
||||
// "colorStart": color,
|
||||
// "colorFinish": color,
|
||||
"alpha": 1,
|
||||
"alphaSpread": 0,
|
||||
"alphaStart": 1,
|
||||
|
@ -712,9 +684,8 @@ function MyController(hand) {
|
|||
|
||||
this.particleBeamOff = function() {
|
||||
if (this.particleBeam !== null) {
|
||||
Entities.editEntity(this.particleBeam, {
|
||||
visible: false
|
||||
})
|
||||
Entities.deleteEntity(this.particleBeam);
|
||||
this.particleBeam = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -744,7 +715,7 @@ function MyController(hand) {
|
|||
this.overlayLineOff();
|
||||
}
|
||||
|
||||
if (USE_PARTICLE_BEAM_FOR_SEARCHING === true || USE_PARTICLE_BEAM_FOR_MOVING === true) {
|
||||
if (USE_PARTICLE_BEAM_FOR_MOVING === true) {
|
||||
this.particleBeamOff();
|
||||
}
|
||||
this.searchSphereOff();
|
||||
|
@ -814,8 +785,7 @@ function MyController(hand) {
|
|||
|
||||
var distantPickRay = {
|
||||
origin: PICK_WITH_HAND_RAY ? handPosition : Camera.position,
|
||||
direction: PICK_WITH_HAND_RAY ? Quat.getUp(this.getHandRotation()) :
|
||||
Vec3.mix(Quat.getUp(this.getHandRotation()), Quat.getFront(Camera.orientation), HAND_HEAD_MIX_RATIO),
|
||||
direction: PICK_WITH_HAND_RAY ? Quat.getUp(this.getHandRotation()) : Vec3.mix(Quat.getUp(this.getHandRotation()), Quat.getFront(Camera.orientation), HAND_HEAD_MIX_RATIO),
|
||||
length: PICK_MAX_DISTANCE
|
||||
};
|
||||
|
||||
|
@ -853,7 +823,7 @@ function MyController(hand) {
|
|||
intersection = Entities.findRayIntersection(pickRayBacked, true, [], blacklist);
|
||||
} else {
|
||||
intersection = Entities.findRayIntersection(pickRayBacked, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (intersection.intersects) {
|
||||
rayPickedCandidateEntities.push(intersection.entityID);
|
||||
|
@ -925,13 +895,14 @@ function MyController(hand) {
|
|||
if (typeof grabbableData.spatialKey === 'undefined') {
|
||||
// We want to give a temporary position offset to this object so it is pulled close to hand
|
||||
var intersectionPointToCenterDistance = Vec3.length(Vec3.subtract(intersection.intersection,
|
||||
intersection.properties.position));
|
||||
intersection.properties.position));
|
||||
this.temporaryPositionOffset = Vec3.normalize(Vec3.subtract(intersection.properties.position, handPosition));
|
||||
this.temporaryPositionOffset = Vec3.multiply(this.temporaryPositionOffset,
|
||||
intersectionPointToCenterDistance *
|
||||
FAR_TO_NEAR_GRAB_PADDING_FACTOR);
|
||||
intersectionPointToCenterDistance *
|
||||
FAR_TO_NEAR_GRAB_PADDING_FACTOR);
|
||||
}
|
||||
this.setState(this.state == STATE_SEARCHING ? STATE_DISTANCE_HOLDING : STATE_EQUIP);
|
||||
this.searchSphereOff();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -945,10 +916,6 @@ function MyController(hand) {
|
|||
this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR);
|
||||
}
|
||||
|
||||
if (USE_PARTICLE_BEAM_FOR_SEARCHING === true) {
|
||||
this.handleParticleBeam(distantPickRay.origin, this.getHandRotation(), NO_INTERSECT_COLOR);
|
||||
}
|
||||
|
||||
var SEARCH_SPHERE_SIZE = 0.011;
|
||||
var SEARCH_SPHERE_FOLLOW_RATE = 0.50;
|
||||
|
||||
|
@ -956,7 +923,7 @@ function MyController(hand) {
|
|||
// If we hit something with our pick ray, move the search sphere toward that distance
|
||||
this.searchSphereDistance = this.searchSphereDistance * SEARCH_SPHERE_FOLLOW_RATE + this.intersectionDistance * (1.0 - SEARCH_SPHERE_FOLLOW_RATE);
|
||||
}
|
||||
|
||||
|
||||
var searchSphereLocation = Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, this.searchSphereDistance));
|
||||
this.searchSphereOn(searchSphereLocation, SEARCH_SPHERE_SIZE * this.searchSphereDistance, (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
|
||||
if ((USE_OVERLAY_LINES_FOR_SEARCHING === true) && PICK_WITH_HAND_RAY) {
|
||||
|
@ -1159,7 +1126,6 @@ function MyController(hand) {
|
|||
}
|
||||
if (USE_PARTICLE_BEAM_FOR_MOVING === true) {
|
||||
this.handleDistantParticleBeam(handPosition, grabbedProperties.position, INTERSECT_COLOR)
|
||||
// this.handleDistantParticleBeam(handPosition, this.currentObjectPosition, INTERSECT_COLOR)
|
||||
}
|
||||
if (USE_POINTLIGHT === true) {
|
||||
this.handlePointLight(this.grabbedEntity);
|
||||
|
@ -1597,8 +1563,8 @@ function MyController(hand) {
|
|||
if (this.actionID !== null) {
|
||||
//sometimes we want things to stay right where they are when we let go.
|
||||
var releaseVelocityData = getEntityCustomData(GRABBABLE_DATA_KEY,
|
||||
this.grabbedEntity,
|
||||
DEFAULT_GRABBABLE_DATA);
|
||||
this.grabbedEntity,
|
||||
DEFAULT_GRABBABLE_DATA);
|
||||
if (releaseVelocityData.disableReleaseVelocity === true) {
|
||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
||||
|
||||
|
@ -1654,7 +1620,7 @@ function MyController(hand) {
|
|||
// zero gravity and set ignoreForCollisions in a way that lets us put them back, after all grabs are done
|
||||
if (data["refCount"] == 1) {
|
||||
data["gravity"] = grabbedProperties.gravity;
|
||||
data["collisionMask"] = grabbedProperties.collisionMask;
|
||||
data["collidesWith"] = grabbedProperties.collidesWith;
|
||||
data["collisionsWillMove"] = grabbedProperties.collisionsWillMove;
|
||||
data["parentID"] = grabbedProperties.parentID;
|
||||
data["parentJointIndex"] = grabbedProperties.parentJointIndex;
|
||||
|
@ -1664,7 +1630,10 @@ function MyController(hand) {
|
|||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
"collisionMask": COLLISION_MASK_WHILE_GRABBED
|
||||
// bummer, it isn't easy to do bitwise collisionMask operations like this:
|
||||
//"collisionMask": COLLISION_MASK_WHILE_GRABBED | grabbedProperties.collisionMask
|
||||
// when using string values
|
||||
"collidesWith": COLLIDES_WITH_WHILE_GRABBED
|
||||
};
|
||||
Entities.editEntity(entityID, whileHeldProperties);
|
||||
}
|
||||
|
@ -1680,7 +1649,7 @@ function MyController(hand) {
|
|||
if (data["refCount"] < 1) {
|
||||
Entities.editEntity(entityID, {
|
||||
gravity: data["gravity"],
|
||||
collisionMask: data["collisionMask"],
|
||||
collidesWith: data["collidesWith"],
|
||||
collisionsWillMove: data["collisionsWillMove"],
|
||||
ignoreForCollisions: data["ignoreForCollisions"],
|
||||
parentID: data["parentID"],
|
||||
|
@ -1698,12 +1667,6 @@ function MyController(hand) {
|
|||
var rightController = new MyController(RIGHT_HAND);
|
||||
var leftController = new MyController(LEFT_HAND);
|
||||
|
||||
//preload the particle beams so that they are full length when you start searching
|
||||
if (USE_PARTICLE_BEAM_FOR_SEARCHING === true || USE_PARTICLE_BEAM_FOR_MOVING === true) {
|
||||
rightController.createParticleBeam();
|
||||
leftController.createParticleBeam();
|
||||
}
|
||||
|
||||
var MAPPING_NAME = "com.highfidelity.handControllerGrab";
|
||||
|
||||
var mapping = Controller.newMapping(MAPPING_NAME);
|
||||
|
@ -1780,31 +1743,7 @@ function cleanup() {
|
|||
rightController.cleanup();
|
||||
leftController.cleanup();
|
||||
Controller.disableMapping(MAPPING_NAME);
|
||||
if (USE_PARTICLE_BEAM_FOR_SEARCHING === true || USE_PARTICLE_BEAM_FOR_MOVING === true) {
|
||||
Script.update.disconnect(renewParticleBeamLifetimes);
|
||||
}
|
||||
|
||||
}
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
Script.update.connect(update);
|
||||
|
||||
// particle systems can end up hanging around if a user crashes or something else causes controller cleanup not to get called.
|
||||
// we can't create the search system on-demand since it takes some time for the particles to reach their entire length.
|
||||
// thus the system cannot have a fixed lifetime. this loop updates the lifetimes and will stop updating if a user crashes.
|
||||
|
||||
if (USE_PARTICLE_BEAM_FOR_SEARCHING === true || USE_PARTICLE_BEAM_FOR_MOVING === true) {
|
||||
Script.update.connect(renewParticleBeamLifetimes)
|
||||
}
|
||||
|
||||
var sinceLastParticleLifetimeUpdate = 0;
|
||||
|
||||
function renewParticleBeamLifetimes(deltaTime) {
|
||||
//debounce this call since we don't want it 60x a second
|
||||
sinceLastParticleLifetimeUpdate = sinceLastParticleLifetimeUpdate + deltaTime;
|
||||
if (sinceLastParticleLifetimeUpdate > TEMPORARY_PARTICLE_BEAM_LIFETIME - 2) {
|
||||
sinceLastParticleLifetimeUpdate = 0;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
rightController.renewParticleBeamLifetime();
|
||||
leftController.renewParticleBeamLifetime();
|
||||
}
|
||||
Script.update.connect(update);
|
|
@ -1659,29 +1659,6 @@ PropertiesTool = function(opts) {
|
|||
});
|
||||
}
|
||||
}
|
||||
} else if (data.action == "centerAtmosphereToZone") {
|
||||
if (selectionManager.hasSelection()) {
|
||||
selectionManager.saveProperties();
|
||||
for (var i = 0; i < selectionManager.selections.length; i++) {
|
||||
var properties = selectionManager.savedProperties[selectionManager.selections[i]];
|
||||
if (properties.type == "Zone") {
|
||||
var centerOfZone = properties.boundingBox.center;
|
||||
var atmosphereCenter = {
|
||||
x: centerOfZone.x,
|
||||
y: centerOfZone.y - properties.atmosphere.innerRadius,
|
||||
z: centerOfZone.z
|
||||
};
|
||||
|
||||
Entities.editEntity(selectionManager.selections[i], {
|
||||
atmosphere: {
|
||||
center: atmosphereCenter
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
pushCommandForSelections();
|
||||
selectionManager._update();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
//
|
||||
// changingAtmosphereExample.js
|
||||
// examples
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 4/16/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// This is an example script that demonstrates creating a zone using the atmosphere features that changes scatter properties
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
|
||||
var count = 0;
|
||||
var stopAfter = 10000;
|
||||
|
||||
var zoneEntityA = Entities.addEntity({
|
||||
type: "Zone",
|
||||
position: { x: 1000, y: 1000, z: 1000},
|
||||
dimensions: { x: 2000, y: 2000, z: 2000 },
|
||||
keyLightColor: { red: 255, green: 0, blue: 0 },
|
||||
stageSunModelEnabled: false,
|
||||
shapeType: "sphere",
|
||||
backgroundMode: "atmosphere",
|
||||
atmosphere: {
|
||||
center: { x: 1000, y: 0, z: 1000},
|
||||
innerRadius: 1000.0,
|
||||
outerRadius: 1025.0,
|
||||
rayleighScattering: 0.0025, // Meaningful values 0 to ~0.01
|
||||
mieScattering: 0.0010, // Meaningful values 0 to ~0.01
|
||||
|
||||
// First two, Meaningful values 0 to 1 each, blue, purple; third meaningful 0.3 to 1 - affects shape
|
||||
scatteringWavelengths: { x: 0.650, y: 0.570, z: 0.475 },
|
||||
hasStars: true
|
||||
},
|
||||
stage: {
|
||||
latitude: 37.777,
|
||||
longitude: 122.407,
|
||||
altitude: 0.03,
|
||||
day: 183,
|
||||
hour: 5,
|
||||
sunModelEnabled: true
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// register the call back so it fires before each data send
|
||||
Script.update.connect(function(deltaTime) {
|
||||
// stop it...
|
||||
if (count >= stopAfter) {
|
||||
print("calling Script.stop()");
|
||||
Script.stop();
|
||||
}
|
||||
count++;
|
||||
var rayleighScattering = (count / 100000) % 0.01;
|
||||
var mieScattering = (count / 100000) % 0.01;
|
||||
var waveX = (count / 2000) % 1;
|
||||
var waveZ = ((count / 2000) % 0.7) + 0.3;
|
||||
|
||||
Entities.editEntity(zoneEntityA, {
|
||||
atmosphere: {
|
||||
rayleighScattering: rayleighScattering,
|
||||
mieScattering: mieScattering,
|
||||
scatteringWavelengths: { x: waveX, y: waveX, z: waveZ }
|
||||
},
|
||||
|
||||
});
|
||||
});
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
//
|
||||
// zoneAtmosphereExample.js
|
||||
// examples
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 4/16/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// This is an example script that demonstrates creating a zone using the atmosphere features
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
|
||||
var count = 0;
|
||||
var stopAfter = 10000;
|
||||
|
||||
var zoneEntityA = Entities.addEntity({
|
||||
type: "Zone",
|
||||
position: { x: 1000, y: 1000, z: 1000},
|
||||
dimensions: { x: 2000, y: 2000, z: 2000 },
|
||||
keyLightColor: { red: 255, green: 0, blue: 0 },
|
||||
stageSunModelEnabled: false,
|
||||
shapeType: "sphere",
|
||||
backgroundMode: "atmosphere",
|
||||
atmosphere: {
|
||||
center: { x: 1000, y: 0, z: 1000},
|
||||
innerRadius: 1000.0,
|
||||
outerRadius: 1025.0,
|
||||
rayleighScattering: 0.0025,
|
||||
mieScattering: 0.0010,
|
||||
scatteringWavelengths: { x: 0.650, y: 0.570, z: 0.475 },
|
||||
hasStars: false
|
||||
},
|
||||
stage: {
|
||||
latitude: 37.777,
|
||||
longitude: 122.407,
|
||||
altitude: 0.03,
|
||||
day: 60,
|
||||
hour: 0,
|
||||
sunModelEnabled: true
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// register the call back so it fires before each data send
|
||||
Script.update.connect(function(deltaTime) {
|
||||
// stop it...
|
||||
if (count >= stopAfter) {
|
||||
print("calling Script.stop()");
|
||||
Script.stop();
|
||||
}
|
||||
count++;
|
||||
var newHour = (count / 10) % 24;
|
||||
var newIntensity = ((count / 10) % 24) / 24;
|
||||
print("newHour:" + newHour);
|
||||
print("newIntensity:" + newIntensity);
|
||||
|
||||
Entities.editEntity(zoneEntityA, {
|
||||
stageHour: newHour,
|
||||
keyLightIntensity: newIntensity
|
||||
});
|
||||
});
|
||||
|
16
examples/example/messages/messagesTestReceive.js
Normal file
16
examples/example/messages/messagesTestReceive.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
var messagesReceivedCount = 0;
|
||||
|
||||
function handleMessages(channel, message, sender) {
|
||||
print('GOT MESSAGE')
|
||||
if (sender === MyAvatar.sessionUUID) {
|
||||
if (channel === 'messageTest') {
|
||||
messagesReceivedCount++;
|
||||
print('sendIndex/receiveCount::' + message + "/" + messagesReceivedCount);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Messages.messageReceived.connect(handleMessages);
|
||||
Messages.subscribe('messageTest')
|
||||
print('READY TO RECEIVE')
|
18
examples/example/messages/messagesTestSend.js
Normal file
18
examples/example/messages/messagesTestSend.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
var messageIndex = 1;
|
||||
|
||||
var messageRate = 500;
|
||||
function sendMessage(){
|
||||
print('SENDING MESSAGE')
|
||||
Messages.sendMessage('messageTest',messageIndex)
|
||||
messageIndex++;
|
||||
}
|
||||
|
||||
function cleanup(){
|
||||
Script.clearInterval(messageInterval);
|
||||
}
|
||||
|
||||
var messageInterval = Script.setInterval(function(){
|
||||
sendMessage();
|
||||
},messageRate);
|
||||
|
||||
Script.scriptEnding.connect(cleanup);
|
|
@ -105,7 +105,8 @@
|
|||
alphaStart: 0.5,
|
||||
alphaFinish: 0.5,
|
||||
textures: "https://s3.amazonaws.com/hifi-public/eric/textures/particleSprites/beamParticle.png",
|
||||
emitterShouldTrail: false
|
||||
emitterShouldTrail: false,
|
||||
lifetime: 1000
|
||||
}
|
||||
this.beam = Entities.addEntity(props);
|
||||
|
||||
|
|
|
@ -360,20 +360,6 @@
|
|||
var elZoneSkyboxColorBlue = document.getElementById("property-zone-skybox-color-blue");
|
||||
var elZoneSkyboxURL = document.getElementById("property-zone-skybox-url");
|
||||
|
||||
var elZoneAtmosphereCenterX = document.getElementById("property-zone-atmosphere-center-x");
|
||||
var elZoneAtmosphereCenterY = document.getElementById("property-zone-atmosphere-center-y");
|
||||
var elZoneAtmosphereCenterZ = document.getElementById("property-zone-atmosphere-center-z");
|
||||
var elCenterAtmosphereToZone = document.getElementById("center-atmosphere-in-zone");
|
||||
|
||||
var elZoneAtmosphereInnerRadius = document.getElementById("property-zone-atmosphere-inner-radius");
|
||||
var elZoneAtmosphereOuterRadius = document.getElementById("property-zone-atmosphere-outer-radius");
|
||||
var elZoneAtmosphereMieScattering = document.getElementById("property-zone-atmosphere-mie-scattering");
|
||||
var elZoneAtmosphereRayleighScattering = document.getElementById("property-zone-atmosphere-rayleigh-scattering");
|
||||
var elZoneAtmosphereScatteringWavelengthsX = document.getElementById("property-zone-atmosphere-scattering-wavelengths-x");
|
||||
var elZoneAtmosphereScatteringWavelengthsY = document.getElementById("property-zone-atmosphere-scattering-wavelengths-y");
|
||||
var elZoneAtmosphereScatteringWavelengthsZ = document.getElementById("property-zone-atmosphere-scattering-wavelengths-z");
|
||||
var elZoneAtmosphereHasStars = document.getElementById("property-zone-atmosphere-has-stars");
|
||||
|
||||
var elPolyVoxSections = document.querySelectorAll(".poly-vox-section");
|
||||
allSections.push(elPolyVoxSections);
|
||||
var elVoxelVolumeSizeX = document.getElementById("property-voxel-volume-size-x");
|
||||
|
@ -606,20 +592,7 @@
|
|||
elZoneSkyboxColorBlue.value = properties.skybox.color.blue;
|
||||
elZoneSkyboxURL.value = properties.skybox.url;
|
||||
|
||||
elZoneAtmosphereCenterX.value = properties.atmosphere.center.x;
|
||||
elZoneAtmosphereCenterY.value = properties.atmosphere.center.y;
|
||||
elZoneAtmosphereCenterZ.value = properties.atmosphere.center.z;
|
||||
elZoneAtmosphereInnerRadius.value = properties.atmosphere.innerRadius;
|
||||
elZoneAtmosphereOuterRadius.value = properties.atmosphere.outerRadius;
|
||||
elZoneAtmosphereMieScattering.value = properties.atmosphere.mieScattering;
|
||||
elZoneAtmosphereRayleighScattering.value = properties.atmosphere.rayleighScattering;
|
||||
elZoneAtmosphereScatteringWavelengthsX.value = properties.atmosphere.scatteringWavelengths.x;
|
||||
elZoneAtmosphereScatteringWavelengthsY.value = properties.atmosphere.scatteringWavelengths.y;
|
||||
elZoneAtmosphereScatteringWavelengthsZ.value = properties.atmosphere.scatteringWavelengths.z;
|
||||
elZoneAtmosphereHasStars.checked = properties.atmosphere.hasStars;
|
||||
|
||||
showElements(document.getElementsByClassName('skybox-section'), elZoneBackgroundMode.value == 'skybox');
|
||||
showElements(document.getElementsByClassName('atmosphere-section'), elZoneBackgroundMode.value == 'atmosphere');
|
||||
} else if (properties.type == "ParticleEffect") {
|
||||
for (var i = 0; i < elParticleSections.length; i++) {
|
||||
elParticleSections[i].style.display = 'block';
|
||||
|
@ -874,25 +847,6 @@
|
|||
|
||||
elZoneSkyboxURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('skybox','url'));
|
||||
|
||||
var zoneAtmosphereCenterChangeFunction = createEmitGroupVec3PropertyUpdateFunction(
|
||||
'atmosphere','center', elZoneAtmosphereCenterX, elZoneAtmosphereCenterY, elZoneAtmosphereCenterZ);
|
||||
elZoneAtmosphereCenterX.addEventListener('change', zoneAtmosphereCenterChangeFunction);
|
||||
elZoneAtmosphereCenterY.addEventListener('change', zoneAtmosphereCenterChangeFunction);
|
||||
elZoneAtmosphereCenterZ.addEventListener('change', zoneAtmosphereCenterChangeFunction);
|
||||
|
||||
|
||||
elZoneAtmosphereInnerRadius.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('atmosphere','innerRadius'));
|
||||
elZoneAtmosphereOuterRadius.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('atmosphere','outerRadius'));
|
||||
elZoneAtmosphereMieScattering.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('atmosphere','mieScattering'));
|
||||
elZoneAtmosphereRayleighScattering.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('atmosphere','rayleighScattering'));
|
||||
var zoneAtmosphereScatterWavelengthsChangeFunction = createEmitGroupVec3PropertyUpdateFunction(
|
||||
'atmosphere','scatteringWavelengths', elZoneAtmosphereScatteringWavelengthsX,
|
||||
elZoneAtmosphereScatteringWavelengthsY, elZoneAtmosphereScatteringWavelengthsZ);
|
||||
elZoneAtmosphereScatteringWavelengthsX.addEventListener('change', zoneAtmosphereScatterWavelengthsChangeFunction);
|
||||
elZoneAtmosphereScatteringWavelengthsY.addEventListener('change', zoneAtmosphereScatterWavelengthsChangeFunction);
|
||||
elZoneAtmosphereScatteringWavelengthsZ.addEventListener('change', zoneAtmosphereScatterWavelengthsChangeFunction);
|
||||
elZoneAtmosphereHasStars.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('atmosphere','hasStars'));
|
||||
|
||||
var voxelVolumeSizeChangeFunction = createEmitVec3PropertyUpdateFunction(
|
||||
'voxelVolumeSize', elVoxelVolumeSizeX, elVoxelVolumeSizeY, elVoxelVolumeSizeZ);
|
||||
elVoxelVolumeSizeX.addEventListener('change', voxelVolumeSizeChangeFunction);
|
||||
|
@ -934,12 +888,6 @@
|
|||
action: "reloadScript"
|
||||
}));
|
||||
});
|
||||
elCenterAtmosphereToZone.addEventListener("click", function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "action",
|
||||
action: "centerAtmosphereToZone",
|
||||
}));
|
||||
});
|
||||
elPreviewCameraButton.addEventListener("click", function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "action",
|
||||
|
@ -1601,7 +1549,6 @@
|
|||
<select name="SelectBackgroundMode" id="property-zone-background-mode">
|
||||
<option value='inherit'>Nothing</option>
|
||||
<option value='skybox'>Skybox</option>
|
||||
<option value='atmosphere'>Atmosphere</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1626,61 +1573,6 @@
|
|||
<input type="text" id="property-zone-skybox-url" class="url">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sub-section-header zone-section atmosphere-section">
|
||||
<label>Atmosphere</label>
|
||||
</div>
|
||||
|
||||
<div class="zone-section atmosphere-section property">
|
||||
<div class="label">Atmosphere Center</div>
|
||||
<div class="value">
|
||||
<div class="input-area">X <br><input class="coord" type='number' id="property-zone-atmosphere-center-x"></div>
|
||||
<div class="input-area">Y <br><input class="coord" type='number' id="property-zone-atmosphere-center-y"></div>
|
||||
<div class="input-area">Z <br><input class="coord" type='number' id="property-zone-atmosphere-center-z"></div>
|
||||
<div>
|
||||
<input type="button" id="center-atmosphere-in-zone" value="Center to Zone">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="zone-section atmosphere-section property">
|
||||
<div class="label">Atmosphere Inner Radius</div>
|
||||
<div class="value">
|
||||
<input class="coord" type='number' id="property-zone-atmosphere-inner-radius" step="1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="zone-section atmosphere-section property">
|
||||
<div class="label">Atmosphere Outer Radius</div>
|
||||
<div class="value">
|
||||
<input class="coord" type='number' id="property-zone-atmosphere-outer-radius" step="1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="zone-section atmosphere-section property">
|
||||
<div class="label">Atmosphere Mie Scattering</div>
|
||||
<div class="value">
|
||||
<input class="coord no-spin" type='number' id="property-zone-atmosphere-mie-scattering" min="0" max="0.5" step="any">
|
||||
</div>
|
||||
</div>
|
||||
<div class="zone-section atmosphere-section property">
|
||||
<div class="label">Atmosphere Rayleigh Scattering</div>
|
||||
<div class="value">
|
||||
<input class="coord no-spin" type='number' id="property-zone-atmosphere-rayleigh-scattering" min="0" max="0.5" step="any">
|
||||
</div>
|
||||
</div>
|
||||
<div class="zone-section atmosphere-section property">
|
||||
<div class="label">Atmosphere Scattering Wavelenghts</div>
|
||||
<div class="value">
|
||||
<div class="input-area">X <br><input class="coord no-spin" type='number' id="property-zone-atmosphere-scattering-wavelengths-x" min="0" max="1" step="any"></div>
|
||||
<div class="input-area">Y <br><input class="coord no-spin" type='number' id="property-zone-atmosphere-scattering-wavelengths-y" min="0" max="1" step="any"></div>
|
||||
<div class="input-area">Z <br><input class="coord no-spin" type='number' id="property-zone-atmosphere-scattering-wavelengths-z" min="0" max="1" step="any"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="zone-section atmosphere-section property" style="display:none">
|
||||
<span class="label">Atmosphere Has Stars</span>
|
||||
<span class="value">
|
||||
<input type='checkbox' id="property-zone-atmosphere-has-stars">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
66
examples/tests/sphereLODTest.js
Normal file
66
examples/tests/sphereLODTest.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// sphereLodTest.js
|
||||
// examples/tests
|
||||
//
|
||||
// Created by Eric Levin on 1/21/16.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
|
||||
// A test script for testing LODing of sphere entities and sphere overlays
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
MyAvatar.orientation = Quat.fromPitchYawRollDegrees(0, 0, 0);
|
||||
orientation = Quat.safeEulerAngles(MyAvatar.orientation);
|
||||
orientation.x = 0;
|
||||
orientation = Quat.fromVec3Degrees(orientation);
|
||||
var tablePosition = Vec3.sum(MyAvatar.position, Quat.getFront(orientation));
|
||||
tablePosition.y += 0.5;
|
||||
|
||||
|
||||
var tableDimensions = {
|
||||
x: 1,
|
||||
y: 0.2,
|
||||
z: 1
|
||||
};
|
||||
var table = Entities.addEntity({
|
||||
type: "Box",
|
||||
position: tablePosition,
|
||||
dimensions: tableDimensions,
|
||||
color: {
|
||||
red: 70,
|
||||
green: 21,
|
||||
blue: 21
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var sphereDimensions = {x: 0.01, y: 0.01, z: 0.01};
|
||||
var entitySpherePosition = Vec3.sum(tablePosition, {x: 0, y: tableDimensions.y/2 + sphereDimensions.y/2, z: 0});
|
||||
var entitySphere = Entities.addEntity({
|
||||
type: "Sphere",
|
||||
position: entitySpherePosition,
|
||||
color: {red: 200, green: 20, blue: 200},
|
||||
dimensions: sphereDimensions
|
||||
});
|
||||
|
||||
var overlaySpherePosition = Vec3.sum(tablePosition, {x: sphereDimensions.x, y: tableDimensions.y/2 + sphereDimensions.y/2, z: 0});
|
||||
var overlaySphere = Overlays.addOverlay("sphere", {
|
||||
position: overlaySpherePosition,
|
||||
size: 0.01,
|
||||
color: { red: 20, green: 200, blue: 0},
|
||||
alpha: 1.0,
|
||||
solid: true,
|
||||
});
|
||||
|
||||
|
||||
|
||||
function cleanup() {
|
||||
Entities.deleteEntity(table);
|
||||
Entities.deleteEntity(entitySphere);
|
||||
Overlays.deleteOverlay(overlaySphere);
|
||||
|
||||
|
||||
}
|
||||
Script.scriptEnding.connect(cleanup);
|
|
@ -540,7 +540,7 @@
|
|||
var arrowProperties = {
|
||||
dynamic: true,
|
||||
collisionless: false,
|
||||
collisionMask: "static,dynamic,otherAvatar", // workaround: not with kinematic --> no collision with bow
|
||||
collidesWith: "static,dynamic,otherAvatar", // workaround: not with kinematic --> no collision with bow
|
||||
velocity: releaseVelocity,
|
||||
gravity: ARROW_GRAVITY,
|
||||
lifetime: 10,
|
||||
|
|
|
@ -9,8 +9,8 @@ var pistol = Entities.addEntity({
|
|||
position: center,
|
||||
dimensions: {
|
||||
x: 0.05,
|
||||
y: .23,
|
||||
z: .36
|
||||
y: 0.23,
|
||||
z: 0.36
|
||||
},
|
||||
script: scriptURL,
|
||||
color: {
|
||||
|
@ -20,9 +20,14 @@ var pistol = Entities.addEntity({
|
|||
},
|
||||
shapeType: 'box',
|
||||
dynamic: true,
|
||||
gravity: {x: 0, y: -5.0, z: 0},
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -5.0,
|
||||
z: 0
|
||||
},
|
||||
restitution: 0,
|
||||
collisionSoundURL: "https://s3.amazonaws.com/hifi-public/sounds/Guns/Gun_Drop_and_Metalli_1.wav",
|
||||
damping:0.5,
|
||||
collisionSoundURL: "http://hifi-content.s3.amazonaws.com/james/pistol/sounds/drop.wav",
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
spatialKey: {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//
|
||||
// pistol.js
|
||||
// examples/toybox/entityScripts
|
||||
//
|
||||
// Created by Eric Levin on11/11/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
|
@ -16,7 +15,6 @@
|
|||
Script.include("../../libraries/constants.js");
|
||||
|
||||
var _this;
|
||||
// if the trigger value goes below this while held, the can will stop spraying. if it goes above, it will spray
|
||||
var DISABLE_LASER_THRESHOLD = 0.2;
|
||||
var TRIGGER_CONTROLS = [
|
||||
Controller.Standard.LT,
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
Script.include("cookies.js");
|
||||
|
||||
var MENU = "Developer>Render>Debug Deferred Buffer";
|
||||
var ACTIONS = ["Off", "Diffuse", "Alpha", "Specular", "Roughness", "Normal", "Depth", "Lighting", "Custom"];
|
||||
var ACTIONS = ["Off", "Diffuse", "Metallic", "Roughness", "Normal", "Depth", "Lighting", "Shadow", "PyramidDepth", "AmbientOcclusion", "OcclusionBlurred", "Custom"];
|
||||
var SETTINGS_KEY = "EngineDebugScript.DebugMode";
|
||||
|
||||
Number.prototype.clamp = function(min, max) {
|
||||
|
@ -52,6 +52,7 @@ var overlaysCounter = new CounterWidget(panel, "Overlays", Render.overlay3D);
|
|||
|
||||
var resizing = false;
|
||||
var previousMode = Settings.getValue(SETTINGS_KEY, -1);
|
||||
previousMode = 8;
|
||||
Menu.addActionGroup(MENU, ACTIONS, ACTIONS[previousMode + 1]);
|
||||
Render.deferredDebugMode = previousMode;
|
||||
Render.deferredDebugSize = { x: 0.0, y: -1.0, z: 1.0, w: 1.0 }; // Reset to default size
|
||||
|
@ -98,12 +99,70 @@ panel.newSlider("Tone Mapping Exposure", -10, 10,
|
|||
function() { return Render.tone.exposure; },
|
||||
function (value) { return (value); });
|
||||
|
||||
panel.newSlider("Ambient Occlusion Resolution Level", 0.0, 4.0,
|
||||
function (value) { Render.ambientOcclusion.resolutionLevel = value; },
|
||||
function() { return Render.ambientOcclusion.resolutionLevel; },
|
||||
function (value) { return (value); });
|
||||
|
||||
panel.newSlider("Ambient Occlusion Radius", 0.0, 2.0,
|
||||
function (value) { Render.ambientOcclusion.radius = value; },
|
||||
function() { return Render.ambientOcclusion.radius; },
|
||||
function (value) { return (value.toFixed(2)); });
|
||||
|
||||
panel.newSlider("Ambient Occlusion Level", 0.0, 1.0,
|
||||
function (value) { Render.ambientOcclusion.level = value; },
|
||||
function() { return Render.ambientOcclusion.level; },
|
||||
function (value) { return (value.toFixed(2)); });
|
||||
|
||||
panel.newSlider("Ambient Occlusion Num Samples", 1, 32,
|
||||
function (value) { Render.ambientOcclusion.numSamples = value; },
|
||||
function() { return Render.ambientOcclusion.numSamples; },
|
||||
function (value) { return (value); });
|
||||
|
||||
panel.newSlider("Ambient Occlusion Num Spiral Turns", 0.0, 30.0,
|
||||
function (value) { Render.ambientOcclusion.numSpiralTurns = value; },
|
||||
function() { return Render.ambientOcclusion.numSpiralTurns; },
|
||||
function (value) { return (value.toFixed(2)); });
|
||||
|
||||
panel.newCheckbox("Ambient Occlusion Dithering",
|
||||
function (value) { Render.ambientOcclusion.ditheringEnabled = value; },
|
||||
function() { return Render.ambientOcclusion.ditheringEnabled; },
|
||||
function (value) { return (value); });
|
||||
|
||||
panel.newSlider("Ambient Occlusion Falloff Bias", 0.0, 0.2,
|
||||
function (value) { Render.ambientOcclusion.falloffBias = value; },
|
||||
function() { return Render.ambientOcclusion.falloffBias; },
|
||||
function (value) { return (value.toFixed(2)); });
|
||||
|
||||
panel.newSlider("Ambient Occlusion Edge Sharpness", 0.0, 1.0,
|
||||
function (value) { Render.ambientOcclusion.edgeSharpness = value; },
|
||||
function() { return Render.ambientOcclusion.edgeSharpness; },
|
||||
function (value) { return (value.toFixed(2)); });
|
||||
|
||||
panel.newSlider("Ambient Occlusion Blur Radius", 0.0, 6.0,
|
||||
function (value) { Render.ambientOcclusion.blurRadius = value; },
|
||||
function() { return Render.ambientOcclusion.blurRadius; },
|
||||
function (value) { return (value); });
|
||||
|
||||
panel.newSlider("Ambient Occlusion Blur Deviation", 0.0, 3.0,
|
||||
function (value) { Render.ambientOcclusion.blurDeviation = value; },
|
||||
function() { return Render.ambientOcclusion.blurDeviation; },
|
||||
function (value) { return (value.toFixed(2)); });
|
||||
|
||||
|
||||
panel.newSlider("Ambient Occlusion GPU time", 0.0, 10.0,
|
||||
function (value) {},
|
||||
function() { return Render.ambientOcclusion.gpuTime; },
|
||||
function (value) { return (value.toFixed(2) + " ms"); });
|
||||
|
||||
|
||||
var tickTackPeriod = 500;
|
||||
|
||||
function updateCounters() {
|
||||
opaquesCounter.update();
|
||||
transparentsCounter.update();
|
||||
overlaysCounter.update();
|
||||
panel.update("Ambient Occlusion GPU time");
|
||||
}
|
||||
Script.setInterval(updateCounters, tickTackPeriod);
|
||||
|
||||
|
|
161
examples/widgets/weatherBox.js
Normal file
161
examples/widgets/weatherBox.js
Normal file
|
@ -0,0 +1,161 @@
|
|||
//
|
||||
// weatherBox.js
|
||||
// examples/widgets/weatherBox
|
||||
//
|
||||
// Created by Eric Levin on 1/20/16.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// This script creates a weatherBox widget which (in final version) will display the current weather
|
||||
//
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
Script.include("../libraries/utils.js");
|
||||
var weatherBox, boxDimensions;
|
||||
var orientation = Camera.getOrientation();
|
||||
orientation = Quat.safeEulerAngles(orientation);
|
||||
orientation.x = 0;
|
||||
orientation = Quat.fromVec3Degrees(orientation);
|
||||
var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(orientation)));
|
||||
|
||||
var emitters = [];
|
||||
var spheres = [];
|
||||
|
||||
createWeatherBox(center);
|
||||
center.y += boxDimensions.y / 2;
|
||||
createCloud(center);
|
||||
for (var i = 0; i < 7; i++) {
|
||||
createLightningStrike(center)
|
||||
}
|
||||
|
||||
function createLightningStrike(basePosition) {
|
||||
var normal = Vec3.subtract(position, MyAvatar.position);
|
||||
normal.y = 0;
|
||||
var textureURL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/lightning.png"
|
||||
var linePoints = [];
|
||||
var normals = [];
|
||||
var strokeWidths = [];
|
||||
var strokeWidth = 0.02
|
||||
var currentPointPosition = {x: 0, y: 0, z: 0};
|
||||
for (var i = 0; i < 8; i++) {
|
||||
linePoints.push(currentPointPosition);
|
||||
currentPointPosition = Vec3.sum(currentPointPosition, {x: randFloat(-0.05, 0.05), y: randFloat(-0.1, -0.05), z: randFloat(-0.05, 0.05)});
|
||||
linePoints.push(currentPointPosition);
|
||||
normals.push(normal);
|
||||
normals.push(normal);
|
||||
strokeWidth -= 0.002;
|
||||
strokeWidths.push(strokeWidth);
|
||||
strokeWidths.push(strokeWidth);
|
||||
}
|
||||
var position = Vec3.sum(basePosition, {x: randFloat(-boxDimensions.x/20, boxDimensions.x/20), y: 0, z: randFloat(-boxDimensions.x/20, boxDimensions.x/20)});
|
||||
var bolt = Entities.addEntity({
|
||||
type: "PolyLine",
|
||||
textures: textureURL,
|
||||
position: position,
|
||||
dimensions: {
|
||||
x: 10,
|
||||
y: 10,
|
||||
z: 10
|
||||
},
|
||||
linePoints: linePoints,
|
||||
normals: normals,
|
||||
strokeWidths: strokeWidths,
|
||||
lifetime: randFloat(0.01, 0.2)
|
||||
});
|
||||
|
||||
Script.setTimeout(function() {
|
||||
createLightningStrike(position)
|
||||
}, randInt(500, 5000));
|
||||
|
||||
}
|
||||
|
||||
|
||||
function createWeatherBox(position) {
|
||||
var naturalDimensions = {
|
||||
x: 1.11,
|
||||
y: 1.3,
|
||||
z: 1.11
|
||||
};
|
||||
boxDimensions = Vec3.multiply(naturalDimensions, 0.7);
|
||||
var modelURL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/weatherBox.fbx"
|
||||
weatherBox = Entities.addEntity({
|
||||
type: "Model",
|
||||
name: "Weather Box",
|
||||
modelURL: modelURL,
|
||||
position: position,
|
||||
dimensions: boxDimensions
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function createCloud(position) {
|
||||
var props = {
|
||||
"type": "ParticleEffect",
|
||||
"position": position,
|
||||
"isEmitting": true,
|
||||
"maxParticles": 10000,
|
||||
"lifespan": 3,
|
||||
"emitRate": 2000,
|
||||
"emitSpeed": 0.025,
|
||||
"speedSpread": 0,
|
||||
"emitDimensions": {
|
||||
x: boxDimensions.x,
|
||||
y: boxDimensions.x,
|
||||
z: 0.1
|
||||
},
|
||||
"emitRadiusStart": 1,
|
||||
"polarStart": 0,
|
||||
"polarFinish": 1.570796012878418,
|
||||
"azimuthStart": -3.1415927410125732,
|
||||
"azimuthFinish": 3.1415927410125732,
|
||||
"emitAcceleration": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"particleRadius": 0.04,
|
||||
"radiusSpread": 0.02,
|
||||
"radiusStart": 0.04,
|
||||
radiusFinish: 0.04,
|
||||
"colorStart": {
|
||||
"red": 40,
|
||||
"green": 40,
|
||||
"blue": 100
|
||||
},
|
||||
color: {
|
||||
red: 40,
|
||||
green: 40,
|
||||
blue: 100
|
||||
},
|
||||
"colorFinish": {
|
||||
"red": 40,
|
||||
"green": 40,
|
||||
"blue": 100
|
||||
},
|
||||
"alpha": 1,
|
||||
"alphaSpread": 0,
|
||||
"alphaStart": 0.3,
|
||||
"alphaFinish": 0,
|
||||
"emitterShouldTrail": true,
|
||||
"textures": "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"
|
||||
}
|
||||
|
||||
var oceanEmitter = Entities.addEntity(props);
|
||||
emitters.push(oceanEmitter);
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
emitters.forEach(function(emitter) {
|
||||
Entities.deleteEntity(emitter);
|
||||
});
|
||||
spheres.forEach(function(sphere) {
|
||||
Entities.deleteEntity(sphere);
|
||||
});
|
||||
Entities.deleteEntity(weatherBox);
|
||||
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(cleanup);
|
|
@ -27,7 +27,7 @@ IceServer::IceServer(int argc, char* argv[]) :
|
|||
_id(QUuid::createUuid()),
|
||||
_serverSocket(),
|
||||
_activePeers(),
|
||||
_httpManager(ICE_SERVER_MONITORING_PORT, QString("%1/web/").arg(QCoreApplication::applicationDirPath()), this)
|
||||
_httpManager(QHostAddress::AnyIPv4, ICE_SERVER_MONITORING_PORT, QString("%1/web/").arg(QCoreApplication::applicationDirPath()), this)
|
||||
{
|
||||
// start the ice-server socket
|
||||
qDebug() << "ice-server socket is listening on" << ICE_SERVER_DEFAULT_PORT;
|
||||
|
|
|
@ -20,12 +20,10 @@ find_package(Qt5LinguistTools REQUIRED)
|
|||
find_package(Qt5LinguistToolsMacros)
|
||||
|
||||
if (WIN32)
|
||||
add_definitions(-D_USE_MATH_DEFINES) # apparently needed to get M_PI and other defines from cmath/math.h
|
||||
add_definitions(-DWINDOWS_LEAN_AND_MEAN) # needed to make sure windows doesn't go to crazy with its defines
|
||||
add_definitions(-D_USE_MATH_DEFINES) # apparently needed to get M_PI and other defines from cmath/math.h
|
||||
add_definitions(-DWINDOWS_LEAN_AND_MEAN) # needed to make sure windows doesn't go to crazy with its defines
|
||||
endif()
|
||||
|
||||
include_application_version()
|
||||
|
||||
# grab the implementation and header files from src dirs
|
||||
file(GLOB_RECURSE INTERFACE_SRCS "src/*.cpp" "src/*.h")
|
||||
GroupSources("src")
|
||||
|
@ -45,8 +43,8 @@ else ()
|
|||
list(REMOVE_ITEM INTERFACE_SRCS ${SPEECHRECOGNIZER_CPP})
|
||||
endif ()
|
||||
|
||||
find_package(Qt5 COMPONENTS
|
||||
Gui Multimedia Network OpenGL Qml Quick Script Svg
|
||||
find_package(Qt5 COMPONENTS
|
||||
Gui Multimedia Network OpenGL Qml Quick Script Svg
|
||||
WebChannel WebEngine WebEngineWidgets WebKitWidgets WebSockets)
|
||||
|
||||
# grab the ui files in resources/ui
|
||||
|
@ -65,23 +63,24 @@ set(INTERFACE_SRCS ${INTERFACE_SRCS} "${QT_UI_HEADERS}" "${QT_RESOURCES}")
|
|||
|
||||
if (APPLE)
|
||||
# configure CMake to use a custom Info.plist
|
||||
SET_TARGET_PROPERTIES( ${this_target} PROPERTIES MACOSX_BUNDLE_INFO_PLIST MacOSXBundleInfo.plist.in )
|
||||
set_target_properties(${this_target} PROPERTIES MACOSX_BUNDLE_INFO_PLIST MacOSXBundleInfo.plist.in)
|
||||
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME Interface)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER io.highfidelity.Interface)
|
||||
|
||||
if (UPPER_CMAKE_BUILD_TYPE MATCHES RELEASE OR UPPER_CMAKE_BUILD_TYPE MATCHES RELWITHDEBINFO)
|
||||
set(ICON_FILENAME "interface.icns")
|
||||
if (PRODUCTION_BUILD)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER com.highfidelity.interface)
|
||||
else ()
|
||||
set(ICON_FILENAME "interface-beta.icns")
|
||||
if (DEV_BUILD)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER com.highfidelity.interface-dev)
|
||||
elseif (PR_BUILD)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER com.highfidelity.interface-pr)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
# set how the icon shows up in the Info.plist file
|
||||
SET(MACOSX_BUNDLE_ICON_FILE "${ICON_FILENAME}")
|
||||
set(MACOSX_BUNDLE_ICON_FILE "${INTERFACE_ICON_FILENAME}")
|
||||
|
||||
# set where in the bundle to put the resources file
|
||||
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/icon/${ICON_FILENAME} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
|
||||
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
|
||||
set(DISCOVERED_RESOURCES "")
|
||||
|
||||
# use the add_resources_to_os_x_bundle macro to recurse into resources
|
||||
|
@ -89,28 +88,37 @@ if (APPLE)
|
|||
|
||||
# append the discovered resources to our list of interface sources
|
||||
list(APPEND INTERFACE_SRCS ${DISCOVERED_RESOURCES})
|
||||
|
||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/icon/${ICON_FILENAME}")
|
||||
|
||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME}")
|
||||
endif()
|
||||
|
||||
# create the executable, make it a bundle on OS X
|
||||
if (APPLE)
|
||||
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM})
|
||||
|
||||
# make sure the output name for the .app bundle is correct
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${INTERFACE_BUNDLE_NAME})
|
||||
elseif(WIN32)
|
||||
add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM})
|
||||
# configure an rc file for the chosen icon
|
||||
set(CONFIGURE_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME}")
|
||||
set(CONFIGURE_ICON_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Icon.rc")
|
||||
configure_file("${HF_CMAKE_DIR}/templates/Icon.rc.in" ${CONFIGURE_ICON_RC_OUTPUT})
|
||||
|
||||
# add an executable that also has the icon itself and the configured rc file as resources
|
||||
add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT})
|
||||
else()
|
||||
add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM})
|
||||
endif()
|
||||
|
||||
# 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)
|
||||
add_dependency_external_projects(sdl2)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/includes")
|
||||
|
||||
if (WIN32)
|
||||
add_dependency_external_projects(OpenVR)
|
||||
endif()
|
||||
if(WIN32 OR APPLE)
|
||||
add_dependency_external_projects(neuron)
|
||||
# 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)
|
||||
add_dependency_external_projects(sdl2)
|
||||
add_dependency_external_projects(OpenVR)
|
||||
add_dependency_external_projects(neuron)
|
||||
endif()
|
||||
|
||||
# disable /OPT:REF and /OPT:ICF for the Debug builds
|
||||
|
@ -121,11 +129,14 @@ if (WIN32)
|
|||
endif()
|
||||
|
||||
# link required hifi libraries
|
||||
link_hifi_libraries(shared octree environment gpu gl procedural model render
|
||||
recording fbx networking model-networking entities avatars
|
||||
audio audio-client animation script-engine physics
|
||||
link_hifi_libraries(shared octree gpu gl procedural model render
|
||||
recording fbx networking model-networking entities avatars
|
||||
audio audio-client animation script-engine physics
|
||||
render-utils entities-renderer ui auto-updater
|
||||
controllers plugins display-plugins input-plugins )
|
||||
controllers plugins display-plugins input-plugins)
|
||||
|
||||
# include the binary directory of render-utils for shader includes
|
||||
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/libraries/render-utils")
|
||||
|
||||
#fixme find a way to express faceshift as a plugin
|
||||
target_bullet()
|
||||
|
@ -133,39 +144,39 @@ target_glew()
|
|||
target_opengl()
|
||||
|
||||
if (WIN32 OR APPLE)
|
||||
target_faceshift()
|
||||
target_faceshift()
|
||||
endif()
|
||||
|
||||
# perform standard include and linking for found externals
|
||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||
|
||||
|
||||
if (${${EXTERNAL}_UPPERCASE}_REQUIRED)
|
||||
find_package(${EXTERNAL} REQUIRED)
|
||||
else ()
|
||||
find_package(${EXTERNAL})
|
||||
endif ()
|
||||
|
||||
|
||||
if (${${EXTERNAL}_UPPERCASE}_FOUND AND NOT DISABLE_${${EXTERNAL}_UPPERCASE})
|
||||
add_definitions(-DHAVE_${${EXTERNAL}_UPPERCASE})
|
||||
|
||||
|
||||
# include the library directories (ignoring warnings)
|
||||
if (NOT ${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS)
|
||||
set(${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIR})
|
||||
endif ()
|
||||
|
||||
|
||||
include_directories(SYSTEM ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS})
|
||||
|
||||
|
||||
# perform the system include hack for OS X to ignore warnings
|
||||
if (APPLE)
|
||||
foreach(EXTERNAL_INCLUDE_DIR ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${EXTERNAL_INCLUDE_DIR}")
|
||||
endforeach()
|
||||
endif ()
|
||||
|
||||
|
||||
if (NOT ${${EXTERNAL}_UPPERCASE}_LIBRARIES)
|
||||
set(${${EXTERNAL}_UPPERCASE}_LIBRARIES ${${${EXTERNAL}_UPPERCASE}_LIBRARY})
|
||||
endif ()
|
||||
|
||||
|
||||
if (NOT APPLE OR NOT ${${EXTERNAL}_UPPERCASE} MATCHES "SIXENSE")
|
||||
target_link_libraries(${TARGET_NAME} ${${${EXTERNAL}_UPPERCASE}_LIBRARIES})
|
||||
elseif (APPLE AND NOT INSTALLER_BUILD)
|
||||
|
@ -179,15 +190,15 @@ include_directories("${PROJECT_SOURCE_DIR}/src")
|
|||
|
||||
target_link_libraries(
|
||||
${TARGET_NAME}
|
||||
Qt5::Gui Qt5::Network Qt5::Multimedia Qt5::OpenGL
|
||||
Qt5::Qml Qt5::Quick Qt5::Script Qt5::Svg
|
||||
Qt5::Gui Qt5::Network Qt5::Multimedia Qt5::OpenGL
|
||||
Qt5::Qml Qt5::Quick Qt5::Script Qt5::Svg
|
||||
Qt5::WebChannel Qt5::WebEngine Qt5::WebEngineWidgets Qt5::WebKitWidgets
|
||||
)
|
||||
|
||||
# Issue causes build failure unless we add this directory.
|
||||
# See https://bugreports.qt.io/browse/QTBUG-43351
|
||||
# Issue causes build failure unless we add this directory.
|
||||
# See https://bugreports.qt.io/browse/QTBUG-43351
|
||||
if (WIN32)
|
||||
add_paths_to_fixup_libs(${Qt5_DIR}/../../../plugins/qtwebengine)
|
||||
add_paths_to_fixup_libs(${Qt5_DIR}/../../../plugins/qtwebengine)
|
||||
endif()
|
||||
|
||||
# assume we are using a Qt build without bearer management
|
||||
|
@ -199,31 +210,63 @@ if (APPLE)
|
|||
find_library(AppKit AppKit)
|
||||
|
||||
target_link_libraries(${TARGET_NAME} ${OpenGL} ${AppKit})
|
||||
|
||||
# install command for OS X bundle
|
||||
INSTALL(TARGETS ${TARGET_NAME}
|
||||
BUNDLE DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/install" COMPONENT Runtime
|
||||
RUNTIME DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/install" COMPONENT Runtime
|
||||
|
||||
# setup install of OS X interface bundle
|
||||
install(TARGETS ${TARGET_NAME}
|
||||
BUNDLE DESTINATION ${INTERFACE_INSTALL_DIR}
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
)
|
||||
|
||||
set(SCRIPTS_INSTALL_DIR "${INTERFACE_INSTALL_APP_PATH}/Contents/Resources")
|
||||
|
||||
# call the fixup_interface macro to add required bundling commands for installation
|
||||
fixup_interface()
|
||||
|
||||
else (APPLE)
|
||||
# copy the resources files beside the executable
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||
"${PROJECT_SOURCE_DIR}/resources"
|
||||
$<TARGET_FILE_DIR:${TARGET_NAME}>/resources
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||
"${CMAKE_SOURCE_DIR}/examples"
|
||||
$<TARGET_FILE_DIR:${TARGET_NAME}>/scripts
|
||||
)
|
||||
|
||||
# link target to external libraries
|
||||
if (WIN32)
|
||||
target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib)
|
||||
else (WIN32)
|
||||
# Nothing else required on linux apparently
|
||||
|
||||
# setup install of executable and things copied by fixup/windeployqt
|
||||
install(
|
||||
FILES "$<TARGET_FILE_DIR:${TARGET_NAME}>/"
|
||||
DESTINATION ${INTERFACE_INSTALL_DIR}
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
)
|
||||
|
||||
set(SCRIPTS_INSTALL_DIR "${INTERFACE_INSTALL_DIR}")
|
||||
|
||||
set(EXECUTABLE_COMPONENT ${CLIENT_COMPONENT})
|
||||
|
||||
optional_win_executable_signing()
|
||||
endif()
|
||||
endif (APPLE)
|
||||
|
||||
if (WIN32)
|
||||
set(EXTRA_DEPLOY_OPTIONS "--qmldir ${PROJECT_SOURCE_DIR}/resources/qml")
|
||||
if (SCRIPTS_INSTALL_DIR)
|
||||
# setup install of scripts beside interface executable
|
||||
install(
|
||||
DIRECTORY "${CMAKE_SOURCE_DIR}/examples/"
|
||||
DESTINATION ${SCRIPTS_INSTALL_DIR}/scripts
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
)
|
||||
endif()
|
||||
|
||||
package_libraries_for_deployment()
|
||||
consolidate_stack_components()
|
||||
if (WIN32)
|
||||
set(EXTRA_DEPLOY_OPTIONS "--qmldir ${PROJECT_SOURCE_DIR}/resources/qml")
|
||||
|
||||
set(TARGET_INSTALL_DIR ${INTERFACE_INSTALL_DIR})
|
||||
set(TARGET_INSTALL_COMPONENT ${CLIENT_COMPONENT})
|
||||
manually_install_ssl_eay()
|
||||
|
||||
package_libraries_for_deployment()
|
||||
endif()
|
||||
|
|
|
@ -16,8 +16,6 @@ Windows.Window {
|
|||
destroyOnCloseButton: false
|
||||
property alias source: webview.url
|
||||
|
||||
function raiseWindow() { Desktop.raise(root) }
|
||||
|
||||
Controls.WebView {
|
||||
id: webview
|
||||
url: "about:blank"
|
||||
|
|
|
@ -21,16 +21,10 @@ Windows.Window {
|
|||
destroyOnCloseButton: false
|
||||
property alias source: pageLoader.source
|
||||
|
||||
function raiseWindow() { Desktop.raise(root) }
|
||||
|
||||
Loader {
|
||||
id: pageLoader
|
||||
objectName: "Loader"
|
||||
focus: true
|
||||
property var dialog: root
|
||||
|
||||
Keys.onPressed: {
|
||||
console.log("QmlWindow pageLoader keypress")
|
||||
}
|
||||
}
|
||||
} // dialog
|
||||
|
|
|
@ -1,229 +0,0 @@
|
|||
import Hifi 1.0 as Hifi
|
||||
|
||||
import QtQuick 2.4
|
||||
import QtQuick.Controls 1.3
|
||||
import QtQuick.Controls.Styles 1.3
|
||||
|
||||
import "controls"
|
||||
import "styles"
|
||||
|
||||
|
||||
Hifi.VrMenu {
|
||||
id: root
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
objectName: "VrMenu"
|
||||
enabled: false
|
||||
opacity: 0.0
|
||||
z: 10000
|
||||
|
||||
property int animationDuration: 200
|
||||
property var models: []
|
||||
property var columns: []
|
||||
|
||||
onEnabledChanged: {
|
||||
if (enabled && columns.length == 0) {
|
||||
pushColumn(rootMenu.items);
|
||||
}
|
||||
opacity = enabled ? 1.0 : 0.0
|
||||
offscreenFlags.navigationFocused = enabled;
|
||||
}
|
||||
|
||||
// The actual animator
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: root.animationDuration
|
||||
easing.type: Easing.InOutBounce
|
||||
}
|
||||
}
|
||||
|
||||
onOpacityChanged: {
|
||||
visible = (opacity != 0.0);
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) reset();
|
||||
}
|
||||
|
||||
property var menuBuilder: Component {
|
||||
VrMenuView {
|
||||
property int menuDepth: root.models.length - 1
|
||||
model: root.models[menuDepth]
|
||||
|
||||
function fit(position, size, maxposition) {
|
||||
var padding = 8;
|
||||
if (position < padding) {
|
||||
position = padding;
|
||||
} else if (position + size + padding > maxposition) {
|
||||
position = maxposition - (size + padding);
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (menuDepth === 0) {
|
||||
x = lastMousePosition.x - 20
|
||||
y = lastMousePosition.y - 20
|
||||
} else {
|
||||
var lastColumn = root.columns[menuDepth - 1]
|
||||
x = lastColumn.x + 64;
|
||||
y = lastMousePosition.y - height / 2;
|
||||
}
|
||||
x = fit(x, width, parent.width);
|
||||
y = fit(y, height, parent.height);
|
||||
}
|
||||
|
||||
onSelected: {
|
||||
root.selectItem(menuDepth, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function lastColumn() {
|
||||
return columns[root.columns.length - 1];
|
||||
}
|
||||
|
||||
function pushColumn(items) {
|
||||
models.push(itemsToModel(items))
|
||||
if (columns.length) {
|
||||
var oldColumn = lastColumn();
|
||||
//oldColumn.enabled = false
|
||||
}
|
||||
var newColumn = menuBuilder.createObject(root);
|
||||
columns.push(newColumn);
|
||||
forceActiveFocus();
|
||||
}
|
||||
|
||||
function popColumn() {
|
||||
if (columns.length > 0) {
|
||||
var curColumn = columns.pop();
|
||||
curColumn.visible = false;
|
||||
curColumn.destroy();
|
||||
models.pop();
|
||||
}
|
||||
|
||||
if (columns.length == 0) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
curColumn = lastColumn();
|
||||
curColumn.enabled = true;
|
||||
curColumn.opacity = 1.0;
|
||||
curColumn.forceActiveFocus();
|
||||
}
|
||||
|
||||
function itemsToModel(items) {
|
||||
var newListModel = Qt.createQmlObject('import QtQuick 2.2; ListModel {}', root);
|
||||
for (var i = 0; i < items.length; ++i) {
|
||||
var item = items[i];
|
||||
switch (item.type) {
|
||||
case 2:
|
||||
newListModel.append({"type":item.type, "name": item.title, "item": item})
|
||||
break;
|
||||
case 1:
|
||||
newListModel.append({"type":item.type, "name": item.text, "item": item})
|
||||
break;
|
||||
case 0:
|
||||
newListModel.append({"type":item.type, "name": "-----", "item": item})
|
||||
break;
|
||||
}
|
||||
}
|
||||
return newListModel;
|
||||
}
|
||||
|
||||
function selectItem(depth, source) {
|
||||
var popped = false;
|
||||
while (depth + 1 < columns.length) {
|
||||
popColumn()
|
||||
popped = true
|
||||
}
|
||||
|
||||
switch (source.type) {
|
||||
case 2:
|
||||
lastColumn().enabled = false
|
||||
pushColumn(source.items)
|
||||
break;
|
||||
case 1:
|
||||
if (!popped) source.trigger()
|
||||
enabled = false
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
while (columns.length > 0) {
|
||||
popColumn();
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
id: mouseArea
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: {
|
||||
if (mouse.button == Qt.RightButton) {
|
||||
root.popColumn();
|
||||
} else {
|
||||
root.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addMenu(menu, newMenu) {
|
||||
return menu.addMenu(newMenu);
|
||||
}
|
||||
|
||||
function addItem(menu, newMenuItem) {
|
||||
return menu.addItem(newMenuItem);
|
||||
}
|
||||
|
||||
function insertItem(menu, beforeItem, newMenuItem) {
|
||||
for (var i = 0; i < menu.items.length; ++i) {
|
||||
if (menu.items[i] === beforeItem) {
|
||||
return menu.insertItem(i, newMenuItem);
|
||||
}
|
||||
}
|
||||
return addItem(menu, newMenuItem);
|
||||
}
|
||||
|
||||
function removeItem(menu, menuItem) {
|
||||
menu.removeItem(menuItem);
|
||||
}
|
||||
|
||||
function previousItem() {
|
||||
if (columns.length) {
|
||||
lastColumn().incrementCurrentIndex()
|
||||
}
|
||||
}
|
||||
|
||||
function nextItem() {
|
||||
if (columns.length) {
|
||||
lastColumn().decrementCurrentIndex()
|
||||
}
|
||||
}
|
||||
|
||||
function selectCurrentItem() {
|
||||
if (columns.length) {
|
||||
var depth = columns.length - 1;
|
||||
var index = lastColumn().currentIndex;
|
||||
if (index >= 0) {
|
||||
var model = models[depth];
|
||||
var item = model.get(index).item;
|
||||
selectItem(depth, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onDownPressed: previousItem();
|
||||
Keys.onUpPressed: nextItem();
|
||||
Keys.onSpacePressed: selectCurrentItem();
|
||||
Keys.onReturnPressed: selectCurrentItem();
|
||||
Keys.onRightPressed: selectCurrentItem();
|
||||
Keys.onLeftPressed: popColumn();
|
||||
Keys.onEscapePressed: popColumn();
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
import QtQuick 2.4
|
||||
import QtQuick.Controls 1.3
|
||||
import QtQuick.Controls.Styles 1.3
|
||||
|
||||
import "styles"
|
||||
|
||||
ListView {
|
||||
id: root
|
||||
HifiConstants { id: hifi }
|
||||
width: 128
|
||||
height: count * 32
|
||||
onEnabledChanged: recalcSize();
|
||||
onVisibleChanged: recalcSize();
|
||||
onCountChanged: recalcSize();
|
||||
|
||||
signal selected(var item)
|
||||
|
||||
highlight: Rectangle {
|
||||
width: root.currentItem ? root.currentItem.width : 0
|
||||
height: root.currentItem ? root.currentItem.height : 0
|
||||
color: "lightsteelblue"; radius: 3
|
||||
}
|
||||
|
||||
delegate: VrMenuItem {
|
||||
text: name
|
||||
source: item
|
||||
onImplicitHeightChanged: root.recalcSize()
|
||||
onImplicitWidthChanged: root.recalcSize()
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: root.currentIndex = index
|
||||
onClicked: root.selected(item)
|
||||
}
|
||||
}
|
||||
|
||||
function recalcSize() {
|
||||
if (model.count !== count || !visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
var originalIndex = currentIndex;
|
||||
var maxWidth = width;
|
||||
var newHeight = 0;
|
||||
for (var i = 0; i < count; ++i) {
|
||||
currentIndex = i;
|
||||
if (!currentItem) {
|
||||
continue;
|
||||
}
|
||||
if (currentItem && currentItem.implicitWidth > maxWidth) {
|
||||
maxWidth = currentItem.implicitWidth
|
||||
}
|
||||
if (currentItem.visible) {
|
||||
newHeight += currentItem.implicitHeight
|
||||
}
|
||||
}
|
||||
if (maxWidth > width) {
|
||||
width = maxWidth;
|
||||
}
|
||||
if (newHeight > height) {
|
||||
height = newHeight
|
||||
}
|
||||
currentIndex = originalIndex;
|
||||
}
|
||||
|
||||
Border {
|
||||
id: border
|
||||
anchors.fill: parent
|
||||
anchors.margins: -8
|
||||
z: parent.z - 1
|
||||
border.color: hifi.colors.hifiBlue
|
||||
color: hifi.colors.window
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2,35 +2,15 @@ import QtQuick 2.5
|
|||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Dialogs 1.2 as OriginalDialogs;
|
||||
|
||||
import "dialogs"
|
||||
import "../dialogs"
|
||||
import "../menus"
|
||||
|
||||
// This is our primary 'desktop' object to which all VR dialogs and
|
||||
// windows will be childed.
|
||||
FocusScope {
|
||||
id: desktop
|
||||
anchors.fill: parent;
|
||||
|
||||
// Debugging help for figuring out focus issues
|
||||
property var offscreenWindow;
|
||||
onOffscreenWindowChanged: offscreenWindow.activeFocusItemChanged.connect(onWindowFocusChanged);
|
||||
function onWindowFocusChanged() {
|
||||
console.log("Focus item is " + offscreenWindow.activeFocusItem);
|
||||
var focusedItem = offscreenWindow.activeFocusItem ;
|
||||
if (DebugQML && focusedItem) {
|
||||
var rect = desktop.mapToItem(desktop, focusedItem.x, focusedItem.y, focusedItem.width, focusedItem.height);
|
||||
focusDebugger.visible = true
|
||||
focusDebugger.x = rect.x;
|
||||
focusDebugger.y = rect.y;
|
||||
focusDebugger.width = rect.width
|
||||
focusDebugger.height = rect.height
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: focusDebugger;
|
||||
z: 9999; visible: false; color: "red"
|
||||
ColorAnimation on color { from: "#7fffff00"; to: "#7f0000ff"; duration: 1000; loops: 9999 }
|
||||
}
|
||||
objectName: "desktop"
|
||||
|
||||
// Allows QML/JS to find the desktop through the parent chain
|
||||
property bool desktopRoot: true
|
||||
|
@ -38,38 +18,13 @@ FocusScope {
|
|||
// The VR version of the primary menu
|
||||
property var rootMenu: Menu { objectName: "rootMenu" }
|
||||
|
||||
// The tool window, one instance
|
||||
property alias toolWindow: toolWindow
|
||||
ToolWindow { id: toolWindow }
|
||||
|
||||
// FIXME support always on top flags
|
||||
function raise(item) {
|
||||
d.raiseWindow(item);
|
||||
}
|
||||
|
||||
Component {
|
||||
id: messageDialogBuilder
|
||||
MessageDialog { }
|
||||
}
|
||||
|
||||
Component {
|
||||
id: nativeMessageDialogBuilder
|
||||
OriginalDialogs.MessageDialog { }
|
||||
}
|
||||
|
||||
function messageBox(properties) {
|
||||
// Debugging: native message dialog for comparison
|
||||
// nativeMessageDialogBuilder.createObject(desktop, properties);
|
||||
return messageDialogBuilder.createObject(desktop, properties);
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property int zBasisNormal: 0
|
||||
readonly property int zBasisAlwaysOnTop: 4096
|
||||
readonly property int zBasisModal: 8192
|
||||
|
||||
readonly property var messageDialogBuilder: Component { MessageDialog { } }
|
||||
readonly property var nativeMessageDialogBuilder: Component { OriginalDialogs.MessageDialog { } }
|
||||
|
||||
function findChild(item, name) {
|
||||
for (var i = 0; i < item.children.length; ++i) {
|
||||
|
@ -203,6 +158,43 @@ FocusScope {
|
|||
}
|
||||
}
|
||||
|
||||
MenuMouseHandler { id: menuPopperUpper }
|
||||
|
||||
function raise(item) {
|
||||
d.raiseWindow(item);
|
||||
}
|
||||
|
||||
function messageBox(properties) {
|
||||
// Debugging: native message dialog for comparison
|
||||
// d.nativeMessageDialogBuilder.createObject(desktop, properties);
|
||||
return d.messageDialogBuilder.createObject(desktop, properties);
|
||||
}
|
||||
|
||||
function popupMenu(point) {
|
||||
menuPopperUpper.popup(desktop, rootMenu.items, point);
|
||||
}
|
||||
|
||||
function toggleMenu(point) {
|
||||
menuPopperUpper.toggle(desktop, rootMenu.items, point);
|
||||
}
|
||||
|
||||
Keys.onEscapePressed: {
|
||||
if (menuPopperUpper.closeLastMenu()) {
|
||||
event.accepted = true;
|
||||
return;
|
||||
}
|
||||
event.accepted = false;
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
if (menuPopperUpper.closeLastMenu()) {
|
||||
event.accepted = true;
|
||||
return;
|
||||
}
|
||||
event.accepted = false;
|
||||
}
|
||||
|
||||
|
||||
function unfocusWindows() {
|
||||
var windows = d.getTopLevelWindows();
|
||||
for (var i = 0; i < windows.length; ++i) {
|
||||
|
@ -210,6 +202,36 @@ FocusScope {
|
|||
}
|
||||
desktop.focus = true;
|
||||
}
|
||||
|
||||
// Debugging help for figuring out focus issues
|
||||
property var offscreenWindow;
|
||||
onOffscreenWindowChanged: {
|
||||
offscreenWindow.activeFocusItemChanged.connect(onWindowFocusChanged);
|
||||
focusHack.start();
|
||||
}
|
||||
|
||||
FocusHack { id: focusHack; }
|
||||
|
||||
function onWindowFocusChanged() {
|
||||
console.log("Focus item is " + offscreenWindow.activeFocusItem);
|
||||
var focusedItem = offscreenWindow.activeFocusItem ;
|
||||
if (DebugQML && focusedItem) {
|
||||
var rect = desktop.mapToItem(null, focusedItem.x, focusedItem.y, focusedItem.width, focusedItem.height);
|
||||
focusDebugger.visible = true
|
||||
focusDebugger.x = rect.x;
|
||||
focusDebugger.y = rect.y;
|
||||
focusDebugger.width = rect.width
|
||||
focusDebugger.height = rect.height
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: focusDebugger;
|
||||
z: 9999; visible: false; color: "red"
|
||||
ColorAnimation on color { from: "#7fffff00"; to: "#7f0000ff"; duration: 1000; loops: 9999 }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
26
interface/resources/qml/desktop/FocusHack.qml
Normal file
26
interface/resources/qml/desktop/FocusHack.qml
Normal file
|
@ -0,0 +1,26 @@
|
|||
import QtQuick 2.5
|
||||
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
TextInput {
|
||||
id: textInput;
|
||||
focus: true
|
||||
width: 10; height: 10
|
||||
onActiveFocusChanged: root.destroy()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: focusTimer
|
||||
running: false
|
||||
interval: 100
|
||||
onTriggered: textInput.forceActiveFocus()
|
||||
}
|
||||
|
||||
function start() {
|
||||
focusTimer.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -8,23 +8,20 @@ import "../windows"
|
|||
import "../styles"
|
||||
|
||||
// Work in progress....
|
||||
Window {
|
||||
ModalWindow {
|
||||
id: root
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
signal selectedFile(var file);
|
||||
signal canceled();
|
||||
|
||||
anchors.centerIn: parent
|
||||
resizable: true
|
||||
width: 640
|
||||
height: 480
|
||||
modality: Qt.ApplicationModal
|
||||
|
||||
property string settingsName: ""
|
||||
property alias folder: folderModel.folder
|
||||
property alias filterModel: selectionType.model
|
||||
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "white"
|
||||
|
|
|
@ -7,19 +7,14 @@ import "../styles"
|
|||
import "../windows"
|
||||
|
||||
// FIXME respect default button functionality
|
||||
// FIXME force active focus at all times (modal dialog)
|
||||
Window {
|
||||
ModalWindow {
|
||||
id: root
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
implicitWidth: 640
|
||||
implicitHeight: 320
|
||||
destroyOnCloseButton: true
|
||||
destroyOnInvisible: true
|
||||
visible: true
|
||||
modality: Qt.ApplicationModal
|
||||
anchors.centerIn: parent
|
||||
frame: ModalFrame {}
|
||||
|
||||
signal selected(int button);
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ Window {
|
|||
resizable: true
|
||||
destroyOnInvisible: true
|
||||
x: 40; y: 40
|
||||
implicitWidth: 384; implicitHeight: 640
|
||||
|
||||
property var scripts: ScriptDiscoveryService;
|
||||
property var scriptsModel: scripts.scriptsModelFilter
|
||||
|
@ -77,7 +78,7 @@ Window {
|
|||
}
|
||||
|
||||
function loadFromFile() {
|
||||
var fileDialog = fileDialogBuilder.createObject(Desktop, { filterModel: fileFilters });
|
||||
var fileDialog = fileDialogBuilder.createObject(desktop, { filterModel: fileFilters });
|
||||
fileDialog.canceled.connect(function(){
|
||||
console.debug("Cancelled file open")
|
||||
})
|
||||
|
@ -90,7 +91,7 @@ Window {
|
|||
|
||||
Rectangle {
|
||||
color: "white"
|
||||
implicitWidth: 384; implicitHeight: 640
|
||||
anchors.fill: parent
|
||||
|
||||
Item {
|
||||
anchors { fill: parent; margins: 8 }
|
||||
|
|
15
interface/resources/qml/hifi/Desktop.qml
Normal file
15
interface/resources/qml/hifi/Desktop.qml
Normal file
|
@ -0,0 +1,15 @@
|
|||
import QtQuick 2.5
|
||||
|
||||
import "../desktop"
|
||||
import ".."
|
||||
|
||||
Desktop {
|
||||
id: desktop
|
||||
|
||||
// The tool window, one instance
|
||||
property alias toolWindow: toolWindow
|
||||
ToolWindow { id: toolWindow }
|
||||
}
|
||||
|
||||
|
||||
|
149
interface/resources/qml/menus/MenuMouseHandler.qml
Normal file
149
interface/resources/qml/menus/MenuMouseHandler.qml
Normal file
|
@ -0,0 +1,149 @@
|
|||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
|
||||
import "."
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property int zBasis: 8192 - 1024
|
||||
anchors.fill: parent
|
||||
|
||||
MouseArea {
|
||||
id: menuRoot;
|
||||
anchors.fill: parent
|
||||
enabled: d.topMenu !== null
|
||||
onClicked: {
|
||||
d.clearMenus();
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property var menuStack: []
|
||||
property var topMenu: null;
|
||||
property var modelMaker: Component { ListModel { } }
|
||||
property var menuViewMaker: Component {
|
||||
VrMenuView {
|
||||
id: subMenu
|
||||
onSelected: d.handleSelection(subMenu, currentItem, item)
|
||||
}
|
||||
}
|
||||
|
||||
function toModel(items) {
|
||||
var result = modelMaker.createObject(desktop);
|
||||
for (var i = 0; i < items.length; ++i) {
|
||||
var item = items[i];
|
||||
if (!item.visible) continue;
|
||||
switch (item.type) {
|
||||
case MenuItemType.Menu:
|
||||
result.append({"name": item.title, "item": item})
|
||||
break;
|
||||
case MenuItemType.Item:
|
||||
result.append({"name": item.text, "item": item})
|
||||
break;
|
||||
case MenuItemType.Separator:
|
||||
result.append({"name": "", "item": item})
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function popMenu() {
|
||||
if (menuStack.length) {
|
||||
menuStack.pop().destroy();
|
||||
}
|
||||
if (menuStack.length) {
|
||||
topMenu = menuStack[menuStack.length - 1];
|
||||
topMenu.focus = true;
|
||||
} else {
|
||||
topMenu = null;
|
||||
offscreenFlags.navigationFocused = false;
|
||||
menuRoot.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function pushMenu(newMenu) {
|
||||
menuStack.push(newMenu);
|
||||
topMenu = newMenu;
|
||||
topMenu.focus = true;
|
||||
offscreenFlags.navigationFocused = true;
|
||||
}
|
||||
|
||||
function clearMenus() {
|
||||
while (menuStack.length) {
|
||||
popMenu()
|
||||
}
|
||||
}
|
||||
|
||||
function clampMenuPosition(menu) {
|
||||
var margins = 0;
|
||||
if (menu.x < margins) {
|
||||
menu.x = margins
|
||||
} else if ((menu.x + menu.width + margins) > root.width) {
|
||||
menu.x = root.width - (menu.width + margins);
|
||||
}
|
||||
|
||||
if (menu.y < 0) {
|
||||
menu.y = margins
|
||||
} else if ((menu.y + menu.height + margins) > root.height) {
|
||||
menu.y = root.height - (menu.height + margins);
|
||||
}
|
||||
}
|
||||
|
||||
function buildMenu(items, targetPosition) {
|
||||
var model = toModel(items);
|
||||
var newMenu = menuViewMaker.createObject(menuRoot, { model: model, z: topMenu ? topMenu.z + 1 : zBasis });
|
||||
if (targetPosition) {
|
||||
newMenu.x = targetPosition.x
|
||||
newMenu.y = targetPosition.y - newMenu.height / 3 * 1
|
||||
}
|
||||
clampMenuPosition(newMenu);
|
||||
pushMenu(newMenu);
|
||||
return newMenu;
|
||||
}
|
||||
|
||||
function handleSelection(parentMenu, selectedItem, item) {
|
||||
while (topMenu && topMenu !== parentMenu) {
|
||||
popMenu();
|
||||
}
|
||||
|
||||
switch (item.type) {
|
||||
case MenuItemType.Menu:
|
||||
var target = Qt.vector2d(topMenu.x, topMenu.y).plus(Qt.vector2d(selectedItem.x + 96, selectedItem.y));
|
||||
buildMenu(item.items, target).objectName = item.title;
|
||||
break;
|
||||
|
||||
case MenuItemType.Item:
|
||||
console.log("Triggering " + item.text)
|
||||
item.trigger();
|
||||
clearMenus();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function popup(parent, items, point) {
|
||||
d.clearMenus();
|
||||
menuRoot.enabled = true;
|
||||
d.buildMenu(items, point);
|
||||
}
|
||||
|
||||
function toggle(parent, items, point) {
|
||||
if (d.topMenu) {
|
||||
d.clearMenus();
|
||||
return;
|
||||
}
|
||||
popup(parent, items, point);
|
||||
}
|
||||
|
||||
function closeLastMenu() {
|
||||
if (d.menuStack.length) {
|
||||
d.popMenu();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +1,13 @@
|
|||
import QtQuick 2.4
|
||||
import QtQuick.Controls 1.3
|
||||
import QtQuick.Controls.Styles 1.3
|
||||
import "controls"
|
||||
import "styles"
|
||||
|
||||
import "../controls"
|
||||
import "../styles"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
HifiConstants {
|
||||
id: hifi
|
||||
}
|
||||
|
||||
// The model object
|
||||
HifiConstants { id: hifi }
|
||||
property alias text: label.text
|
||||
property var source
|
||||
|
100
interface/resources/qml/menus/VrMenuView.qml
Normal file
100
interface/resources/qml/menus/VrMenuView.qml
Normal file
|
@ -0,0 +1,100 @@
|
|||
import QtQuick 2.4
|
||||
import QtQuick.Controls 1.3
|
||||
import QtQuick.Controls.Styles 1.3
|
||||
|
||||
import "../styles"
|
||||
|
||||
|
||||
FocusScope {
|
||||
id: root
|
||||
implicitHeight: border.height
|
||||
implicitWidth: border.width
|
||||
|
||||
property alias currentItem: listView.currentItem
|
||||
property alias model: listView.model
|
||||
signal selected(var item)
|
||||
|
||||
|
||||
Border {
|
||||
id: border
|
||||
anchors.fill: listView
|
||||
anchors.margins: -8
|
||||
border.color: hifi.colors.hifiBlue
|
||||
color: hifi.colors.window
|
||||
// color: "#7f7f7f7f"
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
x: 8; y: 8
|
||||
HifiConstants { id: hifi }
|
||||
width: 128
|
||||
height: count * 32
|
||||
onEnabledChanged: recalcSize();
|
||||
onVisibleChanged: recalcSize();
|
||||
onCountChanged: recalcSize();
|
||||
focus: true
|
||||
|
||||
highlight: Rectangle {
|
||||
width: listView.currentItem ? listView.currentItem.width : 0
|
||||
height: listView.currentItem ? listView.currentItem.height : 0
|
||||
color: "lightsteelblue"; radius: 3
|
||||
}
|
||||
|
||||
delegate: VrMenuItem {
|
||||
text: name
|
||||
source: item
|
||||
onImplicitHeightChanged: listView.recalcSize()
|
||||
onImplicitWidthChanged: listView.recalcSize()
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: listView.currentIndex = index
|
||||
onClicked: root.selected(item)
|
||||
}
|
||||
}
|
||||
|
||||
function recalcSize() {
|
||||
if (model.count !== count || !visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
var originalIndex = currentIndex;
|
||||
var maxWidth = width;
|
||||
var newHeight = 0;
|
||||
for (var i = 0; i < count; ++i) {
|
||||
currentIndex = i;
|
||||
if (!currentItem) {
|
||||
continue;
|
||||
}
|
||||
if (currentItem && currentItem.implicitWidth > maxWidth) {
|
||||
maxWidth = currentItem.implicitWidth
|
||||
}
|
||||
if (currentItem.visible) {
|
||||
newHeight += currentItem.implicitHeight
|
||||
}
|
||||
}
|
||||
if (maxWidth > width) {
|
||||
width = maxWidth;
|
||||
}
|
||||
if (newHeight > height) {
|
||||
height = newHeight
|
||||
}
|
||||
currentIndex = originalIndex;
|
||||
}
|
||||
|
||||
function previousItem() { currentIndex = (currentIndex + count - 1) % count; }
|
||||
function nextItem() { currentIndex = (currentIndex + count + 1) % count; }
|
||||
function selectCurrentItem() { if (currentIndex != -1) root.selected(currentItem.source); }
|
||||
|
||||
Keys.onUpPressed: previousItem();
|
||||
Keys.onDownPressed: nextItem();
|
||||
Keys.onSpacePressed: selectCurrentItem();
|
||||
Keys.onRightPressed: selectCurrentItem();
|
||||
Keys.onReturnPressed: selectCurrentItem();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -17,9 +17,10 @@ Frame {
|
|||
color: "#7f7f7f7f";
|
||||
radius: 3;
|
||||
MouseArea {
|
||||
enabled: window.visible
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.AllButtons
|
||||
onClicked: { }
|
||||
onClicked: {}
|
||||
onDoubleClicked: {}
|
||||
onPressAndHold: {}
|
||||
onReleased: {}
|
||||
|
|
12
interface/resources/qml/windows/ModalWindow.qml
Normal file
12
interface/resources/qml/windows/ModalWindow.qml
Normal file
|
@ -0,0 +1,12 @@
|
|||
import QtQuick 2.5
|
||||
|
||||
import "."
|
||||
|
||||
Window {
|
||||
id: root
|
||||
anchors.centerIn: parent
|
||||
modality: Qt.ApplicationModal
|
||||
frame: ModalFrame{}
|
||||
}
|
||||
|
||||
|
|
@ -69,28 +69,9 @@ Fadable {
|
|||
|
||||
// Default to a standard frame. Can be overriden to provide custom
|
||||
// frame styles, like a full desktop frame to simulate a modal window
|
||||
property var frame;
|
||||
property var frame: DefaultFrame { }
|
||||
|
||||
Component {
|
||||
id: defaultFrameBuilder;
|
||||
DefaultFrame { anchors.fill: parent }
|
||||
}
|
||||
|
||||
Component {
|
||||
id: modalFrameBuilder;
|
||||
ModalFrame { anchors.fill: parent }
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!frame) {
|
||||
if (modality === Qt.NonModal) {
|
||||
frame = defaultFrameBuilder.createObject(window);
|
||||
} else {
|
||||
frame = modalFrameBuilder.createObject(window);
|
||||
}
|
||||
}
|
||||
raise();
|
||||
}
|
||||
Component.onCompleted: raise();
|
||||
|
||||
children: [ frame, content, activator ]
|
||||
|
||||
|
@ -114,7 +95,7 @@ Fadable {
|
|||
|
||||
function raise() {
|
||||
if (visible && parent) {
|
||||
Desktop.raise(window)
|
||||
desktop.raise(window)
|
||||
if (!focus) {
|
||||
focus = true;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
#include <QtGui/QMouseEvent>
|
||||
#include <QtGui/QDesktopServices>
|
||||
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
|
||||
#include <QtQml/QQmlContext>
|
||||
#include <QtQml/QQmlEngine>
|
||||
#include <QtQuick/QQuickWindow>
|
||||
|
@ -57,7 +60,7 @@
|
|||
#include <ResourceScriptingInterface.h>
|
||||
#include <AccountManager.h>
|
||||
#include <AddressManager.h>
|
||||
#include <ApplicationVersion.h>
|
||||
#include <BuildInfo.h>
|
||||
#include <AssetClient.h>
|
||||
#include <AssetUpload.h>
|
||||
#include <AutoUpdater.h>
|
||||
|
@ -303,7 +306,7 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
listenPort = atoi(portStr);
|
||||
}
|
||||
// Set build version
|
||||
QCoreApplication::setApplicationVersion(BUILD_VERSION);
|
||||
QCoreApplication::setApplicationVersion(BuildInfo::VERSION);
|
||||
|
||||
Setting::preInit();
|
||||
|
||||
|
@ -420,9 +423,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
|
||||
auto controllerScriptingInterface = DependencyManager::get<controller::ScriptingInterface>().data();
|
||||
_controllerScriptingInterface = dynamic_cast<ControllerScriptingInterface*>(controllerScriptingInterface);
|
||||
// to work around the Qt constant wireless scanning, set the env for polling interval very high
|
||||
const QByteArray EXTREME_BEARER_POLL_TIMEOUT = QString::number(INT_MAX).toLocal8Bit();
|
||||
qputenv("QT_BEARER_POLL_TIMEOUT", EXTREME_BEARER_POLL_TIMEOUT);
|
||||
|
||||
_entityClipboard->createRootElement();
|
||||
|
||||
|
@ -796,7 +796,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
} else if (action == controller::toInt(controller::Action::CYCLE_CAMERA)) {
|
||||
cycleCamera();
|
||||
} else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) {
|
||||
VrMenu::toggle(); // show context menu even on non-stereo displays
|
||||
offscreenUi->toggleMenu(_glWidget->mapFromGlobal(QCursor::pos()));
|
||||
} else if (action == controller::toInt(controller::Action::RETICLE_X)) {
|
||||
auto oldPos = QCursor::pos();
|
||||
auto newPos = oldPos;
|
||||
|
@ -1179,7 +1179,6 @@ void Application::initializeUi() {
|
|||
AddressBarDialog::registerType();
|
||||
ErrorDialog::registerType();
|
||||
LoginDialog::registerType();
|
||||
VrMenu::registerType();
|
||||
Tooltip::registerType();
|
||||
UpdateDialog::registerType();
|
||||
|
||||
|
@ -1189,7 +1188,7 @@ void Application::initializeUi() {
|
|||
offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
|
||||
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
|
||||
// support the window management and scripting proxies for VR use
|
||||
offscreenUi->createDesktop();
|
||||
offscreenUi->createDesktop(QString("hifi/Desktop.qml"));
|
||||
|
||||
// FIXME either expose so that dialogs can set this themselves or
|
||||
// do better detection in the offscreen UI of what has focus
|
||||
|
@ -1247,8 +1246,6 @@ void Application::initializeUi() {
|
|||
rootContext->setContextProperty("Render", DependencyManager::get<RenderScriptingInterface>().data());
|
||||
|
||||
_glWidget->installEventFilter(offscreenUi.data());
|
||||
VrMenu::load();
|
||||
VrMenu::executeQueuedLambdas();
|
||||
offscreenUi->setMouseTranslator([=](const QPointF& pt) {
|
||||
QPointF result = pt;
|
||||
auto displayPlugin = getActiveDisplayPlugin();
|
||||
|
@ -1886,12 +1883,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_A:
|
||||
if (isShifted) {
|
||||
Menu::getInstance()->triggerOption(MenuOption::Atmosphere);
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Backslash:
|
||||
Menu::getInstance()->triggerOption(MenuOption::Chat);
|
||||
break;
|
||||
|
@ -2066,7 +2057,8 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
|
||||
void Application::keyReleaseEvent(QKeyEvent* event) {
|
||||
if (event->key() == Qt::Key_Alt && _altPressed && hasFocus()) {
|
||||
VrMenu::toggle(); // show context menu even on non-stereo displays
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
offscreenUi->toggleMenu(_glWidget->mapFromGlobal(QCursor::pos()));
|
||||
}
|
||||
|
||||
_keysPressed.remove(event->key());
|
||||
|
@ -2698,8 +2690,6 @@ void Application::init() {
|
|||
// Make sure Login state is up to date
|
||||
DependencyManager::get<DialogsManager>()->toggleLoginDialog();
|
||||
|
||||
_environment.init();
|
||||
|
||||
DependencyManager::get<DeferredLightingEffect>()->init();
|
||||
|
||||
DependencyManager::get<AvatarManager>()->init();
|
||||
|
@ -3620,10 +3610,6 @@ public:
|
|||
typedef Payload::DataPointer Pointer;
|
||||
|
||||
Stars _stars;
|
||||
Environment* _environment;
|
||||
|
||||
BackgroundRenderData(Environment* environment) : _environment(environment) {
|
||||
}
|
||||
|
||||
static render::ItemID _item; // unique WorldBoxRenderData
|
||||
};
|
||||
|
@ -3665,63 +3651,8 @@ namespace render {
|
|||
"Application::payloadRender<BackgroundRenderData>() ... stars...");
|
||||
// should be the first rendering pass - w/o depth buffer / lighting
|
||||
|
||||
// compute starfield alpha based on distance from atmosphere
|
||||
float alpha = 1.0f;
|
||||
bool hasStars = true;
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||
// TODO: handle this correctly for zones
|
||||
const EnvironmentData& closestData = background->_environment->getClosestData(args->_viewFrustum->getPosition()); // was theCamera instead of _viewFrustum
|
||||
|
||||
if (closestData.getHasStars()) {
|
||||
const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f;
|
||||
const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f;
|
||||
|
||||
glm::vec3 sunDirection = (args->_viewFrustum->getPosition()/*getAvatarPosition()*/ - closestData.getSunLocation())
|
||||
/ closestData.getAtmosphereOuterRadius();
|
||||
float height = glm::distance(args->_viewFrustum->getPosition()/*theCamera.getPosition()*/, closestData.getAtmosphereCenter());
|
||||
if (height < closestData.getAtmosphereInnerRadius()) {
|
||||
// If we're inside the atmosphere, then determine if our keyLight is below the horizon
|
||||
alpha = 0.0f;
|
||||
|
||||
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
||||
float directionY = glm::clamp(sunDirection.y,
|
||||
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
||||
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
||||
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
||||
}
|
||||
|
||||
|
||||
} else if (height < closestData.getAtmosphereOuterRadius()) {
|
||||
alpha = (height - closestData.getAtmosphereInnerRadius()) /
|
||||
(closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
|
||||
|
||||
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
||||
float directionY = glm::clamp(sunDirection.y,
|
||||
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
||||
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
||||
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hasStars = false;
|
||||
}
|
||||
}
|
||||
|
||||
// finally render the starfield
|
||||
if (hasStars) {
|
||||
background->_stars.render(args, alpha);
|
||||
}
|
||||
|
||||
// draw the sky dome
|
||||
if (/*!selfAvatarOnly &&*/ Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||
PerformanceTimer perfTimer("atmosphere");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... atmosphere...");
|
||||
|
||||
background->_environment->renderAtmospheres(batch, *(args->_viewFrustum));
|
||||
}
|
||||
|
||||
static const float alpha = 1.0f;
|
||||
background->_stars.render(args, alpha);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -3761,12 +3692,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
|
||||
// Background rendering decision
|
||||
if (BackgroundRenderData::_item == 0) {
|
||||
auto backgroundRenderData = make_shared<BackgroundRenderData>(&_environment);
|
||||
auto backgroundRenderData = make_shared<BackgroundRenderData>();
|
||||
auto backgroundRenderPayload = make_shared<BackgroundRenderData::Payload>(backgroundRenderData);
|
||||
BackgroundRenderData::_item = _main3DScene->allocateID();
|
||||
pendingChanges.resetItem(BackgroundRenderData::_item, backgroundRenderPayload);
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
// Assuming nothing get's rendered through that
|
||||
|
@ -3806,7 +3735,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
DependencyManager::get<DeferredLightingEffect>()->setAmbientLightMode(getRenderAmbientLight());
|
||||
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity());
|
||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalAtmosphere(skyStage->getAtmosphere());
|
||||
|
||||
auto skybox = model::SkyboxPointer();
|
||||
if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
|
||||
|
@ -3847,6 +3775,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
|
||||
auto engineContext = _renderEngine->getRenderContext();
|
||||
renderInterface->setItemCounts(engineContext->getItemsConfig());
|
||||
renderInterface->setJobGPUTimes(engineContext->getAmbientOcclusion().gpuTime);
|
||||
|
||||
}
|
||||
|
||||
activeRenderingThread = nullptr;
|
||||
|
@ -5181,3 +5111,30 @@ void Application::setActiveDisplayPlugin(const QString& pluginName) {
|
|||
}
|
||||
updateDisplayMode();
|
||||
}
|
||||
|
||||
void Application::handleLocalServerConnection() {
|
||||
auto server = qobject_cast<QLocalServer*>(sender());
|
||||
|
||||
qDebug() << "Got connection on local server from additional instance - waiting for parameters";
|
||||
|
||||
auto socket = server->nextPendingConnection();
|
||||
|
||||
connect(socket, &QLocalSocket::readyRead, this, &Application::readArgumentsFromLocalSocket);
|
||||
|
||||
qApp->getWindow()->raise();
|
||||
qApp->getWindow()->activateWindow();
|
||||
}
|
||||
|
||||
void Application::readArgumentsFromLocalSocket() {
|
||||
auto socket = qobject_cast<QLocalSocket*>(sender());
|
||||
|
||||
auto message = socket->readAll();
|
||||
socket->deleteLater();
|
||||
|
||||
qDebug() << "Read from connection: " << message;
|
||||
|
||||
// If we received a message, try to open it as a URL
|
||||
if (message.length() > 0) {
|
||||
qApp->openUrl(QString::fromUtf8(message));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#include "avatar/MyAvatar.h"
|
||||
#include "Bookmarks.h"
|
||||
#include "Camera.h"
|
||||
#include "Environment.h"
|
||||
#include "FileLogger.h"
|
||||
#include "gpu/Context.h"
|
||||
#include "Menu.h"
|
||||
|
@ -89,7 +88,7 @@ class Application;
|
|||
|
||||
class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface, public AbstractUriHandler {
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
// TODO? Get rid of those
|
||||
friend class OctreePacketProcessor;
|
||||
friend class PluginContainerProxy;
|
||||
|
@ -102,15 +101,15 @@ public:
|
|||
Application(int& argc, char** argv, QElapsedTimer& startup_time);
|
||||
~Application();
|
||||
|
||||
void postLambdaEvent(std::function<void()> f);
|
||||
void postLambdaEvent(std::function<void()> f) override;
|
||||
|
||||
void initializeGL();
|
||||
void initializeUi();
|
||||
void paintGL();
|
||||
void resizeGL();
|
||||
|
||||
bool event(QEvent* event);
|
||||
bool eventFilter(QObject* object, QEvent* event);
|
||||
bool event(QEvent* event) override;
|
||||
bool eventFilter(QObject* object, QEvent* event) override;
|
||||
|
||||
glm::uvec2 getCanvasSize() const;
|
||||
glm::uvec2 getUiSize() const;
|
||||
|
@ -129,7 +128,7 @@ public:
|
|||
// passes, mirror window passes, etc
|
||||
ViewFrustum* getDisplayViewFrustum();
|
||||
const ViewFrustum* getDisplayViewFrustum() const;
|
||||
ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; }
|
||||
ViewFrustum* getShadowViewFrustum() override { return &_shadowViewFrustum; }
|
||||
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
|
||||
EntityTreeRenderer* getEntities() { return DependencyManager::get<EntityTreeRenderer>().data(); }
|
||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||
|
@ -151,7 +150,7 @@ public:
|
|||
Overlays& getOverlays() { return _overlays; }
|
||||
|
||||
bool isForeground() const { return _isForeground; }
|
||||
|
||||
|
||||
uint32_t getFrameCount() { return _frameCount; }
|
||||
float getFps() const { return _fps; }
|
||||
float getTargetFrameRate(); // frames/second
|
||||
|
@ -164,7 +163,7 @@ public:
|
|||
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
|
||||
|
||||
virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; }
|
||||
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine);
|
||||
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) override;
|
||||
|
||||
QImage renderAvatarBillboard(RenderArgs* renderArgs);
|
||||
|
||||
|
@ -172,8 +171,6 @@ public:
|
|||
virtual QThread* getMainThread() { return thread(); }
|
||||
virtual PickRay computePickRay(float x, float y) const;
|
||||
virtual glm::vec3 getAvatarPosition() const;
|
||||
virtual void overrideEnvironmentData(const EnvironmentData& newData) { _environment.override(newData); }
|
||||
virtual void endOverrideEnvironmentData() { _environment.endOverride(); }
|
||||
virtual qreal getDevicePixelRatio();
|
||||
|
||||
void setActiveDisplayPlugin(const QString& pluginName);
|
||||
|
@ -208,9 +205,9 @@ public:
|
|||
void setMaxOctreePacketsPerSecond(int maxOctreePPS);
|
||||
int getMaxOctreePacketsPerSecond();
|
||||
|
||||
render::ScenePointer getMain3DScene() { return _main3DScene; }
|
||||
render::ScenePointer getMain3DScene() override { return _main3DScene; }
|
||||
render::ScenePointer getMain3DScene() const { return _main3DScene; }
|
||||
render::EnginePointer getRenderEngine() { return _renderEngine; }
|
||||
render::EnginePointer getRenderEngine() override { return _renderEngine; }
|
||||
gpu::ContextPointer getGPUContext() const { return _gpuContext; }
|
||||
|
||||
const QRect& getMirrorViewRect() const { return _mirrorViewRect; }
|
||||
|
@ -245,6 +242,9 @@ public slots:
|
|||
void toggleLogDialog();
|
||||
void toggleRunningScriptsWidget();
|
||||
|
||||
void handleLocalServerConnection();
|
||||
void readArgumentsFromLocalSocket();
|
||||
|
||||
void showFriendsWindow();
|
||||
|
||||
void packageModel();
|
||||
|
@ -258,7 +258,7 @@ public slots:
|
|||
|
||||
void resetSensors(bool andReload = false);
|
||||
void setActiveFaceTracker();
|
||||
|
||||
|
||||
#ifdef HAVE_IVIEWHMD
|
||||
void setActiveEyeTracker();
|
||||
void calibrateEyeTracker1Point();
|
||||
|
@ -275,11 +275,11 @@ public slots:
|
|||
void reloadResourceCaches();
|
||||
|
||||
void crashApplication();
|
||||
|
||||
|
||||
void rotationModeChanged();
|
||||
|
||||
|
||||
void runTests();
|
||||
|
||||
|
||||
private slots:
|
||||
void clearDomainOctreeDetails();
|
||||
void idle(uint64_t now);
|
||||
|
@ -291,12 +291,12 @@ private slots:
|
|||
void faceTrackerMuteToggled();
|
||||
|
||||
void activeChanged(Qt::ApplicationState state);
|
||||
|
||||
|
||||
void domainSettingsReceived(const QJsonObject& domainSettingsObject);
|
||||
void handleDomainConnectionDeniedPacket(QSharedPointer<ReceivedMessage> message);
|
||||
|
||||
|
||||
void notifyPacketVersionMismatch();
|
||||
|
||||
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
|
@ -318,13 +318,13 @@ private slots:
|
|||
void packetSent(quint64 length);
|
||||
void updateDisplayMode();
|
||||
void updateInputModes();
|
||||
|
||||
|
||||
private:
|
||||
void initDisplay();
|
||||
void init();
|
||||
|
||||
void cleanupBeforeQuit();
|
||||
|
||||
|
||||
void emptyLocalCache();
|
||||
|
||||
void update(float deltaTime);
|
||||
|
@ -344,45 +344,45 @@ private:
|
|||
void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard = false);
|
||||
|
||||
int sendNackPackets();
|
||||
|
||||
|
||||
void takeSnapshot();
|
||||
|
||||
|
||||
MyAvatar* getMyAvatar() const;
|
||||
|
||||
|
||||
void checkSkeleton();
|
||||
|
||||
|
||||
void initializeAcceptedFiles();
|
||||
int getRenderAmbientLight() const;
|
||||
|
||||
|
||||
void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false, bool billboard = false);
|
||||
|
||||
|
||||
bool importSVOFromURL(const QString& urlString);
|
||||
|
||||
|
||||
bool nearbyEntitiesAreReadyForPhysics();
|
||||
int processOctreeStats(ReceivedMessage& message, SharedNodePointer sendingNode);
|
||||
void trackIncomingOctreePacket(ReceivedMessage& message, SharedNodePointer sendingNode, bool wasStatsPacket);
|
||||
|
||||
|
||||
void resizeEvent(QResizeEvent* size);
|
||||
|
||||
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void keyReleaseEvent(QKeyEvent* event);
|
||||
|
||||
|
||||
void focusOutEvent(QFocusEvent* event);
|
||||
void focusInEvent(QFocusEvent* event);
|
||||
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0);
|
||||
void mousePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
|
||||
void mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
|
||||
void mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0);
|
||||
|
||||
|
||||
void touchBeginEvent(QTouchEvent* event);
|
||||
void touchEndEvent(QTouchEvent* event);
|
||||
void touchUpdateEvent(QTouchEvent* event);
|
||||
|
||||
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
void dropEvent(QDropEvent* event);
|
||||
void dragEnterEvent(QDragEnterEvent* event);
|
||||
|
||||
|
||||
|
||||
bool _dependencyManagerIsSetup;
|
||||
|
||||
|
@ -437,8 +437,6 @@ private:
|
|||
float _rotateMirror;
|
||||
float _raiseMirror;
|
||||
|
||||
Environment _environment;
|
||||
|
||||
QSet<int> _keysPressed;
|
||||
|
||||
bool _enableProcessOctreeThread;
|
||||
|
@ -461,7 +459,7 @@ private:
|
|||
|
||||
quint64 _lastNackTime;
|
||||
quint64 _lastSendDownstreamAudioStats;
|
||||
|
||||
|
||||
bool _aboutToQuit;
|
||||
|
||||
Bookmarks* _bookmarks;
|
||||
|
@ -470,9 +468,9 @@ private:
|
|||
|
||||
QThread _settingsThread;
|
||||
QTimer _settingsTimer;
|
||||
|
||||
|
||||
GLCanvas* _glWidget{ nullptr };
|
||||
|
||||
|
||||
typedef bool (Application::* AcceptURLMethod)(const QString &);
|
||||
static const QHash<QString, AcceptURLMethod> _acceptedExtensions;
|
||||
|
||||
|
|
|
@ -323,7 +323,6 @@ Menu::Menu() {
|
|||
|
||||
// Developer > Render >>>
|
||||
MenuWrapper* renderOptionsMenu = developerMenu->addMenu("Render");
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::WorldAxes);
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DebugAmbientOcclusion);
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DebugShadows);
|
||||
|
|
|
@ -154,7 +154,6 @@ namespace MenuOption {
|
|||
const QString AnimDebugDrawPosition= "Debug Draw Position";
|
||||
const QString Antialiasing = "Antialiasing";
|
||||
const QString AssetMigration = "ATP Asset Migration";
|
||||
const QString Atmosphere = "Atmosphere";
|
||||
const QString Attachments = "Attachments...";
|
||||
const QString AudioNetworkStats = "Audio Network Stats";
|
||||
const QString AudioNoiseReduction = "Audio Noise Reduction";
|
||||
|
@ -187,8 +186,8 @@ namespace MenuOption {
|
|||
const QString CopyPath = "Copy Path to Clipboard";
|
||||
const QString CoupleEyelids = "Couple Eyelids";
|
||||
const QString CrashInterface = "Crash Interface";
|
||||
const QString DebugAmbientOcclusion = "Debug Ambient Occlusion";
|
||||
const QString DebugShadows = "Debug Shadows";
|
||||
const QString DebugShadows = "Shadows";
|
||||
const QString DebugAmbientOcclusion = "Ambient Occlusion";
|
||||
const QString DecreaseAvatarSize = "Decrease Avatar Size";
|
||||
const QString DeleteBookmark = "Delete Bookmark...";
|
||||
const QString DisableActivityLogger = "Disable Activity Logger";
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
#include <RenderArgs.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "../../libraries/render-utils/stars_vert.h"
|
||||
#include "../../libraries/render-utils/stars_frag.h"
|
||||
#include <stars_vert.h>
|
||||
#include <stars_frag.h>
|
||||
|
||||
#include "../../libraries/render-utils/standardTransformPNTC_vert.h"
|
||||
#include "../../libraries/render-utils/starsGrid_frag.h"
|
||||
#include <standardTransformPNTC_vert.h>
|
||||
#include <starsGrid_frag.h>
|
||||
|
||||
//static const float TILT = 0.23f;
|
||||
static const float TILT = 0.0f;
|
||||
|
|
|
@ -1230,3 +1230,33 @@ void Avatar::updatePalms() {
|
|||
_leftPalmPositionCache.set(getUncachedLeftPalmPosition());
|
||||
_rightPalmPositionCache.set(getUncachedRightPalmPosition());
|
||||
}
|
||||
|
||||
void Avatar::setParentID(const QUuid& parentID) {
|
||||
if (!isMyAvatar()) {
|
||||
return;
|
||||
}
|
||||
bool success;
|
||||
Transform beforeChangeTransform = getTransform(success);
|
||||
SpatiallyNestable::setParentID(parentID);
|
||||
if (success) {
|
||||
setTransform(beforeChangeTransform, success);
|
||||
if (!success) {
|
||||
qDebug() << "Avatar::setParentID failed to reset avatar's location.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Avatar::setParentJointIndex(quint16 parentJointIndex) {
|
||||
if (!isMyAvatar()) {
|
||||
return;
|
||||
}
|
||||
bool success;
|
||||
Transform beforeChangeTransform = getTransform(success);
|
||||
SpatiallyNestable::setParentJointIndex(parentJointIndex);
|
||||
if (success) {
|
||||
setTransform(beforeChangeTransform, success);
|
||||
if (!success) {
|
||||
qDebug() << "Avatar::setParentJointIndex failed to reset avatar's location.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,6 +167,12 @@ public:
|
|||
using SpatiallyNestable::setOrientation;
|
||||
virtual void setOrientation(const glm::quat& orientation) override;
|
||||
|
||||
// these call through to the SpatiallyNestable versions, but they are here to expose these to javascript.
|
||||
Q_INVOKABLE virtual const QUuid getParentID() const { return SpatiallyNestable::getParentID(); }
|
||||
Q_INVOKABLE virtual void setParentID(const QUuid& parentID);
|
||||
Q_INVOKABLE virtual quint16 getParentJointIndex() const { return SpatiallyNestable::getParentJointIndex(); }
|
||||
Q_INVOKABLE virtual void setParentJointIndex(quint16 parentJointIndex);
|
||||
|
||||
// NOT thread safe, must be called on main thread.
|
||||
glm::vec3 getUncachedLeftPalmPosition() const;
|
||||
glm::quat getUncachedLeftPalmRotation() const;
|
||||
|
|
|
@ -30,7 +30,7 @@ public:
|
|||
|
||||
virtual void updateActionWorker(float deltaTimeStep) override;
|
||||
|
||||
QByteArray serialize() const;
|
||||
QByteArray serialize() const override;
|
||||
virtual void deserialize(QByteArray serializedArguments) override;
|
||||
|
||||
virtual bool shouldSuppressLocationEdits() override { return _active && !_ownerEntity.expired(); }
|
||||
|
|
|
@ -134,7 +134,7 @@ glm::vec3 AvatarMotionState::getObjectGravity() const {
|
|||
}
|
||||
|
||||
// virtual
|
||||
const QUuid& AvatarMotionState::getObjectID() const {
|
||||
const QUuid AvatarMotionState::getObjectID() const {
|
||||
return _avatar->getSessionUUID();
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
virtual glm::vec3 getObjectAngularVelocity() const override;
|
||||
virtual glm::vec3 getObjectGravity() const override;
|
||||
|
||||
virtual const QUuid& getObjectID() const override;
|
||||
virtual const QUuid getObjectID() const override;
|
||||
|
||||
virtual QUuid getSimulatorID() const override;
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "Application.h"
|
||||
#include "devices/Faceshift.h"
|
||||
#include "AvatarManager.h"
|
||||
#include "Environment.h"
|
||||
#include "Menu.h"
|
||||
#include "MyAvatar.h"
|
||||
#include "Physics.h"
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
#include <QCommandLineParser>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QLocalSocket>
|
||||
#include <QLocalServer>
|
||||
#include <QSettings>
|
||||
#include <QSharedMemory>
|
||||
#include <QTranslator>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
|
@ -19,71 +22,72 @@
|
|||
#include "AddressManager.h"
|
||||
#include "Application.h"
|
||||
#include "InterfaceLogging.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
static BOOL CALLBACK enumWindowsCallback(HWND hWnd, LPARAM lParam) {
|
||||
const UINT TIMEOUT = 200; // ms
|
||||
DWORD_PTR response;
|
||||
LRESULT result = SendMessageTimeout(hWnd, UWM_IDENTIFY_INSTANCES, 0, 0, SMTO_BLOCK | SMTO_ABORTIFHUNG, TIMEOUT, &response);
|
||||
if (result == 0) { // Timeout; continue search.
|
||||
return TRUE;
|
||||
}
|
||||
if (response == UWM_IDENTIFY_INSTANCES) {
|
||||
HWND* target = (HWND*)lParam;
|
||||
*target = hWnd;
|
||||
return FALSE; // Found; terminate search.
|
||||
}
|
||||
return TRUE; // Not found; continue search.
|
||||
}
|
||||
#endif
|
||||
#include "MainWindow.h"
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
disableQtBearerPoll(); // Fixes wifi ping spikes
|
||||
|
||||
QString applicationName = "High Fidelity Interface - " + qgetenv("USERNAME");
|
||||
|
||||
bool instanceMightBeRunning = true;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Run only one instance of Interface at a time.
|
||||
HANDLE mutex = CreateMutex(NULL, FALSE, "High Fidelity Interface - " + qgetenv("USERNAME"));
|
||||
DWORD result = GetLastError();
|
||||
if (result == ERROR_ALREADY_EXISTS || result == ERROR_ACCESS_DENIED) {
|
||||
// Interface is already running.
|
||||
HWND otherInstance = NULL;
|
||||
EnumWindows(enumWindowsCallback, (LPARAM)&otherInstance);
|
||||
if (otherInstance) {
|
||||
// Show other instance.
|
||||
SendMessage(otherInstance, UWM_SHOW_APPLICATION, 0, 0);
|
||||
// Try to create a shared memory block - if it can't be created, there is an instance of
|
||||
// interface already running. We only do this on Windows for now because of the potential
|
||||
// for crashed instances to leave behind shared memory instances on unix.
|
||||
QSharedMemory sharedMemory { applicationName };
|
||||
instanceMightBeRunning = !sharedMemory.create(1, QSharedMemory::ReadOnly);
|
||||
#endif
|
||||
|
||||
// Send command line --url value to other instance.
|
||||
if (argc >= 3) {
|
||||
QStringList arguments;
|
||||
for (int i = 0; i < argc; i += 1) {
|
||||
arguments << argv[i];
|
||||
}
|
||||
if (instanceMightBeRunning) {
|
||||
// Try to connect and send message to existing interface instance
|
||||
QLocalSocket socket;
|
||||
|
||||
QCommandLineParser parser;
|
||||
QCommandLineOption urlOption("url", "", "value");
|
||||
parser.addOption(urlOption);
|
||||
parser.process(arguments);
|
||||
socket.connectToServer(applicationName);
|
||||
|
||||
if (parser.isSet(urlOption)) {
|
||||
QUrl url = QUrl(parser.value(urlOption));
|
||||
if (url.isValid() && url.scheme() == HIFI_URL_SCHEME) {
|
||||
QByteArray urlBytes = url.toString().toLatin1();
|
||||
const char* urlChars = urlBytes.data();
|
||||
COPYDATASTRUCT cds;
|
||||
cds.cbData = urlBytes.length() + 1;
|
||||
cds.lpData = (PVOID)urlChars;
|
||||
SendMessage(otherInstance, WM_COPYDATA, 0, (LPARAM)&cds);
|
||||
static const int LOCAL_SERVER_TIMEOUT_MS = 500;
|
||||
|
||||
// Try to connect - if we can't connect, interface has probably just gone down
|
||||
if (socket.waitForConnected(LOCAL_SERVER_TIMEOUT_MS)) {
|
||||
|
||||
QStringList arguments;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
arguments << argv[i];
|
||||
}
|
||||
|
||||
QCommandLineParser parser;
|
||||
QCommandLineOption urlOption("url", "", "value");
|
||||
parser.addOption(urlOption);
|
||||
parser.process(arguments);
|
||||
|
||||
if (parser.isSet(urlOption)) {
|
||||
QUrl url = QUrl(parser.value(urlOption));
|
||||
if (url.isValid() && url.scheme() == HIFI_URL_SCHEME) {
|
||||
qDebug() << "Writing URL to local socket";
|
||||
socket.write(url.toString().toUtf8());
|
||||
if (!socket.waitForBytesWritten(5000)) {
|
||||
qDebug() << "Error writing URL to local socket";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
socket.close();
|
||||
|
||||
qDebug() << "Interface instance appears to be running, exiting";
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
return EXIT_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
QElapsedTimer startupTime;
|
||||
startupTime.start();
|
||||
|
||||
// Debug option to demonstrate that the client's local time does not
|
||||
// need to be in sync with any other network node. This forces clock
|
||||
|
||||
// Debug option to demonstrate that the client's local time does not
|
||||
// need to be in sync with any other network node. This forces clock
|
||||
// skew for the individual client
|
||||
const char* CLOCK_SKEW = "--clockSkew";
|
||||
const char* clockSkewOption = getCmdOption(argc, argv, CLOCK_SKEW);
|
||||
|
@ -102,19 +106,26 @@ int main(int argc, const char* argv[]) {
|
|||
QSettings::setDefaultFormat(QSettings::IniFormat);
|
||||
Application app(argc, const_cast<char**>(argv), startupTime);
|
||||
|
||||
// Setup local server
|
||||
QLocalServer server { &app };
|
||||
|
||||
// We failed to connect to a local server, so we remove any existing servers.
|
||||
server.removeServer(applicationName);
|
||||
server.listen(applicationName);
|
||||
|
||||
QObject::connect(&server, &QLocalServer::newConnection, &app, &Application::handleLocalServerConnection);
|
||||
|
||||
QTranslator translator;
|
||||
translator.load("i18n/interface_en");
|
||||
app.installTranslator(&translator);
|
||||
|
||||
|
||||
qCDebug(interfaceapp, "Created QT Application.");
|
||||
exitCode = app.exec();
|
||||
server.close();
|
||||
}
|
||||
|
||||
Application::shutdownPlugins();
|
||||
#ifdef Q_OS_WIN
|
||||
ReleaseMutex(mutex);
|
||||
#endif
|
||||
|
||||
qCDebug(interfaceapp, "Normal exit.");
|
||||
return exitCode;
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue