mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 02:37:12 +02:00
Merge branch 'master' of git://github.com/highfidelity/hifi into entity-tools-polish-2
This commit is contained in:
commit
5c5c66b265
16 changed files with 177 additions and 160 deletions
15
BUILD.md
15
BUILD.md
|
@ -96,12 +96,13 @@ Currently building on Windows has been tested using the following compilers:
|
||||||
|
|
||||||
#####Windows SDK 7.1
|
#####Windows SDK 7.1
|
||||||
|
|
||||||
Whichever version of Visual Studio you use, you will need [Microsoft Windows SDK for Windows 7 and .NET Framework 4](http://www.microsoft.com/en-us/download/details.aspx?id=8279).
|
If using Visual Studio 2010, or using Visual Studio 2013 but building as a Visual Studio 2010 project, you need [Microsoft Windows SDK for Windows 7 and .NET Framework 4](http://www.microsoft.com/en-us/download/details.aspx?id=8279).
|
||||||
|
|
||||||
NOTE: If using Visual Studio C++ 2010 Express, you need to follow a specific install order. See below before installing the Windows SDK.
|
NOTE: If using Visual Studio C++ 2010 Express, you need to follow a specific install order. See below before installing the Windows SDK.
|
||||||
|
|
||||||
######Windows 8.1
|
######Windows SDK 8.1
|
||||||
You may have already downloaded the Windows 8 SDK (e.g. if you have previously installed Visual Studio 2013). If so, change CMAKE_PREFIX_PATH in %HIFI_DIR%\CMakeLists.txt to point to the Windows 8 SDK binaries. The default path is `C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86`
|
|
||||||
|
If using Visual Studio 2013 and building as a Visual Studio 2013 project you need the Windows 8 SDK which you should already have as part of installing Visual Studio 2013. You should be able to see it at `C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86`.
|
||||||
|
|
||||||
#####Visual Studio C++ 2010 Express
|
#####Visual Studio C++ 2010 Express
|
||||||
|
|
||||||
|
@ -123,9 +124,11 @@ Some of the build instructions will ask you to start a Visual Studio Command Pro
|
||||||
|
|
||||||
#####Visual Studio 2013
|
#####Visual Studio 2013
|
||||||
|
|
||||||
This product must be purchased separately.
|
You can use the Community or Professional editions of Visual Studio 2013.
|
||||||
|
|
||||||
Visual Studio 2013 doesn't have a shortcut to start a Visual Studio Command Prompt. Instead, start a regular command prompt and then run:
|
You can start a Visual Studio 2013 command prompt using the shortcut provided in the Visual Studio Tools folder installed as part of Visual Studio 2013.
|
||||||
|
|
||||||
|
Or you can start a regular command prompt and then run:
|
||||||
|
|
||||||
"%VS120COMNTOOLS%\vsvars32.bat"
|
"%VS120COMNTOOLS%\vsvars32.bat"
|
||||||
|
|
||||||
|
@ -146,6 +149,8 @@ Once Qt is installed, you need to manually configure the following:
|
||||||
* Make sure the Qt runtime DLLs are loadable. You must do this before you attempt to build because some tools for the build depend on Qt. E.g., add to the PATH: `Qt\5.2.0\msvc2010_opengl\bin\`.
|
* Make sure the Qt runtime DLLs are loadable. You must do this before you attempt to build because some tools for the build depend on Qt. E.g., add to the PATH: `Qt\5.2.0\msvc2010_opengl\bin\`.
|
||||||
* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.2.0\msvc2010_opengl` directory.
|
* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.2.0\msvc2010_opengl` directory.
|
||||||
|
|
||||||
|
If building as a Visual Studio 2013 project, download and configure the msvc2013 version of Qt instead.
|
||||||
|
|
||||||
####External Libraries
|
####External Libraries
|
||||||
|
|
||||||
CMake will need to know where the headers and libraries for required external dependencies are.
|
CMake will need to know where the headers and libraries for required external dependencies are.
|
||||||
|
|
|
@ -48,8 +48,13 @@ elseif (UNIX)
|
||||||
select_library_configurations(XINERAMA)
|
select_library_configurations(XINERAMA)
|
||||||
|
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
|
if (MSVC10)
|
||||||
find_library(LIBOVR_LIBRARY_DEBUG NAMES libovrd PATH_SUFFIXES Lib/Win32/VS2010 HINTS ${LIBOVR_SEARCH_DIRS})
|
find_library(LIBOVR_LIBRARY_DEBUG NAMES libovrd PATH_SUFFIXES Lib/Win32/VS2010 HINTS ${LIBOVR_SEARCH_DIRS})
|
||||||
find_library(LIBOVR_LIBRARY_RELEASE NAMES libovr PATH_SUFFIXES Lib/Win32/VS2010 HINTS ${LIBOVR_SEARCH_DIRS})
|
find_library(LIBOVR_LIBRARY_RELEASE NAMES libovr PATH_SUFFIXES Lib/Win32/VS2010 HINTS ${LIBOVR_SEARCH_DIRS})
|
||||||
|
elseif (MSVC12)
|
||||||
|
find_library(LIBOVR_LIBRARY_DEBUG NAMES libovrd PATH_SUFFIXES Lib/Win32/VS2013 HINTS ${LIBOVR_SEARCH_DIRS})
|
||||||
|
find_library(LIBOVR_LIBRARY_RELEASE NAMES libovr PATH_SUFFIXES Lib/Win32/VS2013 HINTS ${LIBOVR_SEARCH_DIRS})
|
||||||
|
endif ()
|
||||||
find_package(ATL)
|
find_package(ATL)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
|
|
||||||
int const DomainServer::EXIT_CODE_REBOOT = 234923;
|
int const DomainServer::EXIT_CODE_REBOOT = 234923;
|
||||||
|
|
||||||
|
const QString ICE_SERVER_DEFAULT_HOSTNAME = "ice.highfidelity.io";
|
||||||
|
|
||||||
DomainServer::DomainServer(int argc, char* argv[]) :
|
DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
QCoreApplication(argc, argv),
|
QCoreApplication(argc, argv),
|
||||||
_shutdownEventListener(this),
|
_shutdownEventListener(this),
|
||||||
|
@ -52,7 +54,8 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
_webAuthenticationStateSet(),
|
_webAuthenticationStateSet(),
|
||||||
_cookieSessionHash(),
|
_cookieSessionHash(),
|
||||||
_automaticNetworkingSetting(),
|
_automaticNetworkingSetting(),
|
||||||
_settingsManager()
|
_settingsManager(),
|
||||||
|
_iceServerSocket(ICE_SERVER_DEFAULT_HOSTNAME, ICE_SERVER_DEFAULT_PORT)
|
||||||
{
|
{
|
||||||
LogUtils::init();
|
LogUtils::init();
|
||||||
|
|
||||||
|
@ -337,39 +340,19 @@ bool DomainServer::optionallySetupAssignmentPayment() {
|
||||||
|
|
||||||
void DomainServer::setupAutomaticNetworking() {
|
void DomainServer::setupAutomaticNetworking() {
|
||||||
|
|
||||||
if (!didSetupAccountManagerWithAccessToken()) {
|
|
||||||
qDebug() << "Cannot setup domain-server automatic networking without an access token.";
|
|
||||||
qDebug() << "Please add an access token to your config file or via the web interface.";
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_automaticNetworkingSetting =
|
|
||||||
_settingsManager.valueOrDefaultValueForKeyPath(METAVERSE_AUTOMATIC_NETWORKING_KEY_PATH).toString();
|
|
||||||
|
|
||||||
if (_automaticNetworkingSetting == IP_ONLY_AUTOMATIC_NETWORKING_VALUE ||
|
|
||||||
_automaticNetworkingSetting == FULL_AUTOMATIC_NETWORKING_VALUE) {
|
|
||||||
|
|
||||||
LimitedNodeList* nodeList = LimitedNodeList::getInstance();
|
LimitedNodeList* nodeList = LimitedNodeList::getInstance();
|
||||||
const QUuid& domainID = nodeList->getSessionUUID();
|
|
||||||
|
|
||||||
if (!domainID.isNull()) {
|
|
||||||
qDebug() << "domain-server" << _automaticNetworkingSetting << "automatic networking enabled for ID"
|
|
||||||
<< uuidStringWithoutCurlyBraces(domainID) << "via" << _oauthProviderURL.toString();
|
|
||||||
|
|
||||||
const int STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS = 30 * 1000;
|
|
||||||
const int STUN_REFLEXIVE_KEEPALIVE_INTERVAL_MSECS = 10 * 1000;
|
const int STUN_REFLEXIVE_KEEPALIVE_INTERVAL_MSECS = 10 * 1000;
|
||||||
|
const int STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS = 30 * 1000;
|
||||||
|
|
||||||
// setup our timer to check our IP via stun every X seconds
|
// setup our timer to check our IP via stun every X seconds
|
||||||
QTimer* dynamicIPTimer = new QTimer(this);
|
QTimer* dynamicIPTimer = new QTimer(this);
|
||||||
connect(dynamicIPTimer, &QTimer::timeout, this, &DomainServer::requestCurrentPublicSocketViaSTUN);
|
connect(dynamicIPTimer, &QTimer::timeout, this, &DomainServer::requestCurrentPublicSocketViaSTUN);
|
||||||
|
|
||||||
if (_automaticNetworkingSetting == IP_ONLY_AUTOMATIC_NETWORKING_VALUE) {
|
_automaticNetworkingSetting =
|
||||||
dynamicIPTimer->start(STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS);
|
_settingsManager.valueOrDefaultValueForKeyPath(METAVERSE_AUTOMATIC_NETWORKING_KEY_PATH).toString();
|
||||||
|
|
||||||
// send public socket changes to the data server so nodes can find us at our new IP
|
if (_automaticNetworkingSetting == FULL_AUTOMATIC_NETWORKING_VALUE) {
|
||||||
connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::performIPAddressUpdate);
|
|
||||||
} else {
|
|
||||||
dynamicIPTimer->start(STUN_REFLEXIVE_KEEPALIVE_INTERVAL_MSECS);
|
dynamicIPTimer->start(STUN_REFLEXIVE_KEEPALIVE_INTERVAL_MSECS);
|
||||||
|
|
||||||
// setup a timer to heartbeat with the ice-server every so often
|
// setup a timer to heartbeat with the ice-server every so often
|
||||||
|
@ -377,17 +360,47 @@ void DomainServer::setupAutomaticNetworking() {
|
||||||
connect(iceHeartbeatTimer, &QTimer::timeout, this, &DomainServer::performICEUpdates);
|
connect(iceHeartbeatTimer, &QTimer::timeout, this, &DomainServer::performICEUpdates);
|
||||||
iceHeartbeatTimer->start(ICE_HEARBEAT_INTERVAL_MSECS);
|
iceHeartbeatTimer->start(ICE_HEARBEAT_INTERVAL_MSECS);
|
||||||
|
|
||||||
// call our sendHeartbeaToIceServer immediately anytime a local or public socket changes
|
// call our sendHeartbeatToIceServer immediately anytime a local or public socket changes
|
||||||
connect(nodeList, &LimitedNodeList::localSockAddrChanged, this, &DomainServer::sendHeartbeatToIceServer);
|
connect(nodeList, &LimitedNodeList::localSockAddrChanged, this, &DomainServer::sendHeartbeatToIceServer);
|
||||||
connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::sendHeartbeatToIceServer);
|
connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::sendHeartbeatToIceServer);
|
||||||
|
|
||||||
// send our heartbeat to data server so it knows what our network settings are
|
// attempt to update our public socket now, this will send a heartbeat once we get public socket
|
||||||
sendHeartbeatToDataServer();
|
requestCurrentPublicSocketViaSTUN();
|
||||||
|
|
||||||
|
// in case the STUN lookup is still happening we should re-request a public socket once we get that address
|
||||||
|
connect(&nodeList->getSTUNSockAddr(), &HifiSockAddr::lookupCompleted,
|
||||||
|
this, &DomainServer::requestCurrentPublicSocketViaSTUN);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!didSetupAccountManagerWithAccessToken()) {
|
||||||
|
qDebug() << "Cannot send heartbeat to data server without an access token.";
|
||||||
|
qDebug() << "Add an access token to your config file or via the web interface.";
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_automaticNetworkingSetting == IP_ONLY_AUTOMATIC_NETWORKING_VALUE ||
|
||||||
|
_automaticNetworkingSetting == FULL_AUTOMATIC_NETWORKING_VALUE) {
|
||||||
|
|
||||||
|
const QUuid& domainID = nodeList->getSessionUUID();
|
||||||
|
|
||||||
|
if (!domainID.isNull()) {
|
||||||
|
qDebug() << "domain-server" << _automaticNetworkingSetting << "automatic networking enabled for ID"
|
||||||
|
<< uuidStringWithoutCurlyBraces(domainID) << "via" << _oauthProviderURL.toString();
|
||||||
|
|
||||||
|
if (_automaticNetworkingSetting == IP_ONLY_AUTOMATIC_NETWORKING_VALUE) {
|
||||||
|
dynamicIPTimer->start(STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS);
|
||||||
|
|
||||||
|
// send public socket changes to the data server so nodes can find us at our new IP
|
||||||
|
connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::performIPAddressUpdate);
|
||||||
|
|
||||||
// attempt to update our sockets now
|
// attempt to update our sockets now
|
||||||
requestCurrentPublicSocketViaSTUN();
|
requestCurrentPublicSocketViaSTUN();
|
||||||
|
} else {
|
||||||
|
// send our heartbeat to data server so it knows what our network settings are
|
||||||
|
sendHeartbeatToDataServer();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Cannot enable domain-server automatic networking without a domain ID."
|
qDebug() << "Cannot enable domain-server automatic networking without a domain ID."
|
||||||
<< "Please add an ID to your config file or via the web interface.";
|
<< "Please add an ID to your config file or via the web interface.";
|
||||||
|
@ -1164,8 +1177,7 @@ void DomainServer::performICEUpdates() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::sendHeartbeatToIceServer() {
|
void DomainServer::sendHeartbeatToIceServer() {
|
||||||
static HifiSockAddr ICE_SERVER_SOCK_ADDR = HifiSockAddr("ice.highfidelity.io", ICE_SERVER_DEFAULT_PORT);
|
LimitedNodeList::getInstance()->sendHeartbeatToIceServer(_iceServerSocket);
|
||||||
LimitedNodeList::getInstance()->sendHeartbeatToIceServer(ICE_SERVER_SOCK_ADDR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::sendICEPingPackets() {
|
void DomainServer::sendICEPingPackets() {
|
||||||
|
|
|
@ -154,6 +154,8 @@ private:
|
||||||
QString _automaticNetworkingSetting;
|
QString _automaticNetworkingSetting;
|
||||||
|
|
||||||
DomainServerSettingsManager _settingsManager;
|
DomainServerSettingsManager _settingsManager;
|
||||||
|
|
||||||
|
HifiSockAddr _iceServerSocket;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -245,10 +245,12 @@ function handleGrabBehavior(deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update for joysticks and move button
|
// Update for joysticks and move button
|
||||||
|
var THRUST_DEAD_ZONE = 0.1;
|
||||||
|
var ROTATE_DEAD_ZONE = 0.1;
|
||||||
function flyWithHydra(deltaTime) {
|
function flyWithHydra(deltaTime) {
|
||||||
var thrustJoystickPosition = Controller.getJoystickPosition(THRUST_CONTROLLER);
|
var thrustJoystickPosition = Controller.getJoystickPosition(THRUST_CONTROLLER);
|
||||||
|
|
||||||
if (thrustJoystickPosition.x != 0 || thrustJoystickPosition.y != 0) {
|
if (Math.abs(thrustJoystickPosition.x) > THRUST_DEAD_ZONE || Math.abs(thrustJoystickPosition.y) > THRUST_DEAD_ZONE) {
|
||||||
if (thrustMultiplier < MAX_THRUST_MULTIPLIER) {
|
if (thrustMultiplier < MAX_THRUST_MULTIPLIER) {
|
||||||
thrustMultiplier *= 1 + (deltaTime * THRUST_INCREASE_RATE);
|
thrustMultiplier *= 1 + (deltaTime * THRUST_INCREASE_RATE);
|
||||||
}
|
}
|
||||||
|
@ -270,7 +272,7 @@ function flyWithHydra(deltaTime) {
|
||||||
|
|
||||||
// View Controller
|
// View Controller
|
||||||
var viewJoystickPosition = Controller.getJoystickPosition(VIEW_CONTROLLER);
|
var viewJoystickPosition = Controller.getJoystickPosition(VIEW_CONTROLLER);
|
||||||
if (viewJoystickPosition.x != 0 || viewJoystickPosition.y != 0) {
|
if (Math.abs(viewJoystickPosition.x) > ROTATE_DEAD_ZONE || Math.abs(viewJoystickPosition.y) > ROTATE_DEAD_ZONE) {
|
||||||
|
|
||||||
// change the body yaw based on our x controller
|
// change the body yaw based on our x controller
|
||||||
var orientation = MyAvatar.orientation;
|
var orientation = MyAvatar.orientation;
|
||||||
|
|
|
@ -842,7 +842,7 @@ bool Application::event(QEvent* event) {
|
||||||
QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event);
|
QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event);
|
||||||
|
|
||||||
if (!fileEvent->url().isEmpty()) {
|
if (!fileEvent->url().isEmpty()) {
|
||||||
AddressManager::getInstance().handleLookupString(fileEvent->url().toLocalFile());
|
AddressManager::getInstance().handleLookupString(fileEvent->url().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1574,7 +1574,9 @@ void Application::setFullscreen(bool fullscreen) {
|
||||||
}
|
}
|
||||||
_window->setWindowState(fullscreen ? (_window->windowState() | Qt::WindowFullScreen) :
|
_window->setWindowState(fullscreen ? (_window->windowState() | Qt::WindowFullScreen) :
|
||||||
(_window->windowState() & ~Qt::WindowFullScreen));
|
(_window->windowState() & ~Qt::WindowFullScreen));
|
||||||
|
if (!_aboutToQuit) {
|
||||||
_window->show();
|
_window->show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setEnable3DTVMode(bool enable3DTVMode) {
|
void Application::setEnable3DTVMode(bool enable3DTVMode) {
|
||||||
|
@ -4013,26 +4015,23 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser
|
||||||
return _scriptEnginesHash[scriptURLString];
|
return _scriptEnginesHash[scriptURLString];
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptEngine* scriptEngine;
|
ScriptEngine* scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface);
|
||||||
if (scriptFilename.isNull()) {
|
|
||||||
scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface);
|
|
||||||
} else {
|
|
||||||
// start the script on a new thread...
|
|
||||||
scriptEngine = new ScriptEngine(scriptUrl, &_controllerScriptingInterface);
|
|
||||||
|
|
||||||
if (!scriptEngine->hasScript()) {
|
|
||||||
qDebug() << "Application::loadScript(), script failed to load...";
|
|
||||||
QMessageBox::warning(getWindow(), "Error Loading Script", scriptURLString + " failed to load.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
_scriptEnginesHash.insertMulti(scriptURLString, scriptEngine);
|
|
||||||
_runningScriptsWidget->setRunningScripts(getRunningScripts());
|
|
||||||
UserActivityLogger::getInstance().loadedScript(scriptURLString);
|
|
||||||
}
|
|
||||||
scriptEngine->setUserLoaded(isUserLoaded);
|
scriptEngine->setUserLoaded(isUserLoaded);
|
||||||
|
|
||||||
|
if (scriptFilename.isNull()) {
|
||||||
|
// this had better be the script editor (we should de-couple so somebody who thinks they are loading a script
|
||||||
|
// doesn't just get an empty script engine)
|
||||||
|
|
||||||
|
// we can complete setup now since there isn't a script we have to load
|
||||||
registerScriptEngineWithApplicationServices(scriptEngine);
|
registerScriptEngineWithApplicationServices(scriptEngine);
|
||||||
|
} else {
|
||||||
|
// connect to the appropriate signals of this script engine
|
||||||
|
connect(scriptEngine, &ScriptEngine::scriptLoaded, this, &Application::handleScriptEngineLoaded);
|
||||||
|
connect(scriptEngine, &ScriptEngine::errorLoadingScript, this, &Application::handleScriptLoadError);
|
||||||
|
|
||||||
|
// get the script engine object to load the script at the designated script URL
|
||||||
|
scriptEngine->loadURL(scriptUrl);
|
||||||
|
}
|
||||||
|
|
||||||
// restore the main window's active state
|
// restore the main window's active state
|
||||||
if (activateMainWindow && !loadScriptFromEditor) {
|
if (activateMainWindow && !loadScriptFromEditor) {
|
||||||
|
@ -4043,6 +4042,22 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser
|
||||||
return scriptEngine;
|
return scriptEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::handleScriptEngineLoaded(const QUrl& scriptURL) {
|
||||||
|
ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(sender());
|
||||||
|
|
||||||
|
_scriptEnginesHash.insertMulti(scriptURL.toString(), scriptEngine);
|
||||||
|
_runningScriptsWidget->setRunningScripts(getRunningScripts());
|
||||||
|
UserActivityLogger::getInstance().loadedScript(scriptURL.toString());
|
||||||
|
|
||||||
|
// register our application services and set it off on its own thread
|
||||||
|
registerScriptEngineWithApplicationServices(scriptEngine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::handleScriptLoadError(const QUrl& scriptURL) {
|
||||||
|
qDebug() << "Application::loadScript(), script failed to load...";
|
||||||
|
QMessageBox::warning(getWindow(), "Error Loading Script", scriptURL.toString() + " failed to load.");
|
||||||
|
}
|
||||||
|
|
||||||
void Application::scriptFinished(const QString& scriptName) {
|
void Application::scriptFinished(const QString& scriptName) {
|
||||||
const QString& scriptURLString = QUrl(scriptName).toString();
|
const QString& scriptURLString = QUrl(scriptName).toString();
|
||||||
QHash<QString, ScriptEngine*>::iterator it = _scriptEnginesHash.find(scriptURLString);
|
QHash<QString, ScriptEngine*>::iterator it = _scriptEnginesHash.find(scriptURLString);
|
||||||
|
|
|
@ -394,6 +394,9 @@ private slots:
|
||||||
void idle();
|
void idle();
|
||||||
void aboutToQuit();
|
void aboutToQuit();
|
||||||
|
|
||||||
|
void handleScriptEngineLoaded(const QUrl& scriptURL);
|
||||||
|
void handleScriptLoadError(const QUrl& scriptURL);
|
||||||
|
|
||||||
void connectedToDomain(const QString& hostname);
|
void connectedToDomain(const QString& hostname);
|
||||||
|
|
||||||
friend class HMDToolsDialog;
|
friend class HMDToolsDialog;
|
||||||
|
|
|
@ -835,11 +835,16 @@ void GeometryReader::run() {
|
||||||
fbxgeo = readSVO(_reply->readAll());
|
fbxgeo = readSVO(_reply->readAll());
|
||||||
} else {
|
} else {
|
||||||
bool grabLightmaps = true;
|
bool grabLightmaps = true;
|
||||||
|
float lightmapLevel = 1.0f;
|
||||||
// HACK: For monday 12/01/2014 we need to kill lighmaps loading in starchamber...
|
// HACK: For monday 12/01/2014 we need to kill lighmaps loading in starchamber...
|
||||||
if (_url.path().toLower().endsWith("loungev4_11-18.fbx")) {
|
if (_url.path().toLower().endsWith("loungev4_11-18.fbx")) {
|
||||||
grabLightmaps = false;
|
grabLightmaps = false;
|
||||||
|
} else if (_url.path().toLower().endsWith("apt8_reboot.fbx")) {
|
||||||
|
lightmapLevel = 4.0f;
|
||||||
|
} else if (_url.path().toLower().endsWith("palaceoforinthilian4.fbx")) {
|
||||||
|
lightmapLevel = 3.5f;
|
||||||
}
|
}
|
||||||
fbxgeo = readFBX(_reply->readAll(), _mapping, grabLightmaps);
|
fbxgeo = readFBX(_reply->readAll(), _mapping, grabLightmaps, lightmapLevel);
|
||||||
}
|
}
|
||||||
QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&, fbxgeo));
|
QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&, fbxgeo));
|
||||||
|
|
||||||
|
|
|
@ -571,8 +571,6 @@ void ApplicationOverlay::renderControllerPointers() {
|
||||||
static quint64 pressedTime[NUMBER_OF_MAGNIFIERS] = { 0ULL, 0ULL, 0ULL };
|
static quint64 pressedTime[NUMBER_OF_MAGNIFIERS] = { 0ULL, 0ULL, 0ULL };
|
||||||
static bool isPressed[NUMBER_OF_MAGNIFIERS] = { false, false, false };
|
static bool isPressed[NUMBER_OF_MAGNIFIERS] = { false, false, false };
|
||||||
static bool stateWhenPressed[NUMBER_OF_MAGNIFIERS] = { false, false, false };
|
static bool stateWhenPressed[NUMBER_OF_MAGNIFIERS] = { false, false, false };
|
||||||
static bool triggerPressed[NUMBER_OF_MAGNIFIERS] = { false, false, false };
|
|
||||||
static bool bumperPressed[NUMBER_OF_MAGNIFIERS] = { false, false, false };
|
|
||||||
|
|
||||||
const HandData* handData = Application::getInstance()->getAvatar()->getHandData();
|
const HandData* handData = Application::getInstance()->getAvatar()->getHandData();
|
||||||
|
|
||||||
|
@ -613,30 +611,6 @@ void ApplicationOverlay::renderControllerPointers() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check for UI active toggle
|
|
||||||
if (palmData->getTrigger() == 1.0f) {
|
|
||||||
if (!triggerPressed[index]) {
|
|
||||||
if (bumperPressed[index]) {
|
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::UserInterface,
|
|
||||||
!Menu::getInstance()->isOptionChecked(MenuOption::UserInterface));
|
|
||||||
}
|
|
||||||
triggerPressed[index] = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
triggerPressed[index] = false;
|
|
||||||
}
|
|
||||||
if ((controllerButtons & BUTTON_FWD)) {
|
|
||||||
if (!bumperPressed[index]) {
|
|
||||||
if (triggerPressed[index]) {
|
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::UserInterface,
|
|
||||||
!Menu::getInstance()->isOptionChecked(MenuOption::UserInterface));
|
|
||||||
}
|
|
||||||
bumperPressed[index] = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bumperPressed[index] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if we have the oculus, we should make the cursor smaller since it will be
|
//if we have the oculus, we should make the cursor smaller since it will be
|
||||||
//magnified
|
//magnified
|
||||||
if (OculusManager::isConnected()) {
|
if (OculusManager::isConnected()) {
|
||||||
|
|
|
@ -1194,7 +1194,7 @@ int matchTextureUVSetToAttributeChannel(const std::string& texUVSetName, const Q
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, bool loadLightmaps) {
|
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) {
|
||||||
QHash<QString, ExtractedMesh> meshes;
|
QHash<QString, ExtractedMesh> meshes;
|
||||||
QHash<QString, QString> modelIDsToNames;
|
QHash<QString, QString> modelIDsToNames;
|
||||||
QHash<QString, int> meshIDsToMeshIndices;
|
QHash<QString, int> meshIDsToMeshIndices;
|
||||||
|
@ -1954,6 +1954,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
||||||
|
|
||||||
FBXTexture emissiveTexture;
|
FBXTexture emissiveTexture;
|
||||||
glm::vec2 emissiveParams(0.f, 1.f);
|
glm::vec2 emissiveParams(0.f, 1.f);
|
||||||
|
emissiveParams.y = lightmapLevel;
|
||||||
QString emissiveTextureID = emissiveTextures.value(childID);
|
QString emissiveTextureID = emissiveTextures.value(childID);
|
||||||
QString ambientTextureID = ambientTextures.value(childID);
|
QString ambientTextureID = ambientTextures.value(childID);
|
||||||
if (!emissiveTextureID.isNull() || !ambientTextureID.isNull()) {
|
if (!emissiveTextureID.isNull() || !ambientTextureID.isNull()) {
|
||||||
|
@ -2372,10 +2373,10 @@ QByteArray writeMapping(const QVariantHash& mapping) {
|
||||||
return buffer.data();
|
return buffer.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps) {
|
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) {
|
||||||
QBuffer buffer(const_cast<QByteArray*>(&model));
|
QBuffer buffer(const_cast<QByteArray*>(&model));
|
||||||
buffer.open(QIODevice::ReadOnly);
|
buffer.open(QIODevice::ReadOnly);
|
||||||
return extractFBXGeometry(parseFBX(&buffer), mapping, loadLightmaps);
|
return extractFBXGeometry(parseFBX(&buffer), mapping, loadLightmaps, lightmapLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addMeshVoxelsOperation(OctreeElement* element, void* extraData) {
|
bool addMeshVoxelsOperation(OctreeElement* element, void* extraData) {
|
||||||
|
|
|
@ -253,7 +253,7 @@ QByteArray writeMapping(const QVariantHash& mapping);
|
||||||
|
|
||||||
/// Reads FBX geometry from the supplied model and mapping data.
|
/// Reads FBX geometry from the supplied model and mapping data.
|
||||||
/// \exception QString if an error occurs in parsing
|
/// \exception QString if an error occurs in parsing
|
||||||
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps = true);
|
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps = true, float lightmapLevel = 1.0f);
|
||||||
|
|
||||||
/// Reads SVO geometry from the supplied model data.
|
/// Reads SVO geometry from the supplied model data.
|
||||||
FBXGeometry readSVO(const QByteArray& model);
|
FBXGeometry readSVO(const QByteArray& model);
|
||||||
|
|
|
@ -86,6 +86,7 @@ bool HifiSockAddr::operator==(const HifiSockAddr& rhsSockAddr) const {
|
||||||
void HifiSockAddr::handleLookupResult(const QHostInfo& hostInfo) {
|
void HifiSockAddr::handleLookupResult(const QHostInfo& hostInfo) {
|
||||||
if (hostInfo.error() != QHostInfo::NoError) {
|
if (hostInfo.error() != QHostInfo::NoError) {
|
||||||
qDebug() << "Lookup failed for" << hostInfo.lookupId() << ":" << hostInfo.errorString();
|
qDebug() << "Lookup failed for" << hostInfo.lookupId() << ":" << hostInfo.errorString();
|
||||||
|
emit lookupFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(const QHostAddress& address, hostInfo.addresses()) {
|
foreach(const QHostAddress& address, hostInfo.addresses()) {
|
||||||
|
@ -94,6 +95,7 @@ void HifiSockAddr::handleLookupResult(const QHostInfo& hostInfo) {
|
||||||
_address = address;
|
_address = address;
|
||||||
qDebug() << "QHostInfo lookup result for"
|
qDebug() << "QHostInfo lookup result for"
|
||||||
<< hostInfo.hostName() << "with lookup ID" << hostInfo.lookupId() << "is" << address.toString();
|
<< hostInfo.hostName() << "with lookup ID" << hostInfo.lookupId() << "is" << address.toString();
|
||||||
|
emit lookupCompleted();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,9 @@ public:
|
||||||
friend QDataStream& operator>>(QDataStream& dataStream, HifiSockAddr& sockAddr);
|
friend QDataStream& operator>>(QDataStream& dataStream, HifiSockAddr& sockAddr);
|
||||||
private slots:
|
private slots:
|
||||||
void handleLookupResult(const QHostInfo& hostInfo);
|
void handleLookupResult(const QHostInfo& hostInfo);
|
||||||
|
signals:
|
||||||
|
void lookupCompleted();
|
||||||
|
void lookupFailed();
|
||||||
private:
|
private:
|
||||||
QHostAddress _address;
|
QHostAddress _address;
|
||||||
quint16 _port;
|
quint16 _port;
|
||||||
|
|
|
@ -105,6 +105,7 @@ public:
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||||
|
|
||||||
const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; }
|
const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; }
|
||||||
|
const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; }
|
||||||
|
|
||||||
void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet);
|
void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet);
|
||||||
void processKillNode(const QByteArray& datagram);
|
void processKillNode(const QByteArray& datagram);
|
||||||
|
|
|
@ -100,71 +100,6 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptEngine::ScriptEngine(const QUrl& scriptURL,
|
|
||||||
AbstractControllerScriptingInterface* controllerScriptingInterface) :
|
|
||||||
_scriptContents(),
|
|
||||||
_isFinished(false),
|
|
||||||
_isRunning(false),
|
|
||||||
_isInitialized(false),
|
|
||||||
_isAvatar(false),
|
|
||||||
_avatarIdentityTimer(NULL),
|
|
||||||
_avatarBillboardTimer(NULL),
|
|
||||||
_timerFunctionMap(),
|
|
||||||
_isListeningToAudioStream(false),
|
|
||||||
_avatarSound(NULL),
|
|
||||||
_numAvatarSoundSentBytes(0),
|
|
||||||
_controllerScriptingInterface(controllerScriptingInterface),
|
|
||||||
_avatarData(NULL),
|
|
||||||
_scriptName(),
|
|
||||||
_fileNameString(),
|
|
||||||
_quatLibrary(),
|
|
||||||
_vec3Library(),
|
|
||||||
_uuidLibrary(),
|
|
||||||
_animationCache(this),
|
|
||||||
_isUserLoaded(false),
|
|
||||||
_arrayBufferClass(new ArrayBufferClass(this))
|
|
||||||
{
|
|
||||||
QString scriptURLString = scriptURL.toString();
|
|
||||||
_fileNameString = scriptURLString;
|
|
||||||
|
|
||||||
QUrl url(scriptURL);
|
|
||||||
|
|
||||||
// if the scheme length is one or lower, maybe they typed in a file, let's try
|
|
||||||
const int WINDOWS_DRIVE_LETTER_SIZE = 1;
|
|
||||||
if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) {
|
|
||||||
url = QUrl::fromLocalFile(scriptURLString);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ok, let's see if it's valid... and if so, load it
|
|
||||||
if (url.isValid()) {
|
|
||||||
if (url.scheme() == "file") {
|
|
||||||
QString fileName = url.toLocalFile();
|
|
||||||
QFile scriptFile(fileName);
|
|
||||||
if (scriptFile.open(QFile::ReadOnly | QFile::Text)) {
|
|
||||||
qDebug() << "Loading file:" << fileName;
|
|
||||||
QTextStream in(&scriptFile);
|
|
||||||
_scriptContents = in.readAll();
|
|
||||||
} else {
|
|
||||||
qDebug() << "ERROR Loading file:" << fileName;
|
|
||||||
emit errorMessage("ERROR Loading file:" + fileName);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
|
||||||
QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url));
|
|
||||||
qDebug() << "Downloading script at" << url;
|
|
||||||
QEventLoop loop;
|
|
||||||
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
|
||||||
loop.exec();
|
|
||||||
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) {
|
|
||||||
_scriptContents = reply->readAll();
|
|
||||||
} else {
|
|
||||||
qDebug() << "ERROR Loading file:" << url.toString();
|
|
||||||
emit errorMessage("ERROR Loading file:" + url.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptEngine::setIsAvatar(bool isAvatar) {
|
void ScriptEngine::setIsAvatar(bool isAvatar) {
|
||||||
_isAvatar = isAvatar;
|
_isAvatar = isAvatar;
|
||||||
|
|
||||||
|
@ -217,6 +152,56 @@ bool ScriptEngine::setScriptContents(const QString& scriptContents, const QStrin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::loadURL(const QUrl& scriptURL) {
|
||||||
|
if (_isRunning) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString scriptURLString = scriptURL.toString();
|
||||||
|
_fileNameString = scriptURLString;
|
||||||
|
|
||||||
|
QUrl url(scriptURL);
|
||||||
|
|
||||||
|
// if the scheme length is one or lower, maybe they typed in a file, let's try
|
||||||
|
const int WINDOWS_DRIVE_LETTER_SIZE = 1;
|
||||||
|
if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) {
|
||||||
|
url = QUrl::fromLocalFile(scriptURLString);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok, let's see if it's valid... and if so, load it
|
||||||
|
if (url.isValid()) {
|
||||||
|
if (url.scheme() == "file") {
|
||||||
|
QString fileName = url.toLocalFile();
|
||||||
|
QFile scriptFile(fileName);
|
||||||
|
if (scriptFile.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
|
qDebug() << "Loading file:" << fileName;
|
||||||
|
QTextStream in(&scriptFile);
|
||||||
|
_scriptContents = in.readAll();
|
||||||
|
emit scriptLoaded(url);
|
||||||
|
} else {
|
||||||
|
qDebug() << "ERROR Loading file:" << fileName;
|
||||||
|
emit errorLoadingScript(url);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
|
QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url));
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &ScriptEngine::handleScriptDownload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::handleScriptDownload() {
|
||||||
|
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
|
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) {
|
||||||
|
_scriptContents = reply->readAll();
|
||||||
|
emit scriptLoaded(reply->url());
|
||||||
|
} else {
|
||||||
|
qDebug() << "ERROR Loading file:" << reply->url().toString();
|
||||||
|
emit errorLoadingScript(reply->url());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Q_SCRIPT_DECLARE_QMETAOBJECT(LocalVoxels, QString)
|
Q_SCRIPT_DECLARE_QMETAOBJECT(LocalVoxels, QString)
|
||||||
|
|
||||||
void ScriptEngine::init() {
|
void ScriptEngine::init() {
|
||||||
|
|
|
@ -40,9 +40,6 @@ const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 10
|
||||||
class ScriptEngine : public QScriptEngine {
|
class ScriptEngine : public QScriptEngine {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ScriptEngine(const QUrl& scriptURL,
|
|
||||||
AbstractControllerScriptingInterface* controllerScriptingInterface = NULL);
|
|
||||||
|
|
||||||
ScriptEngine(const QString& scriptContents = NO_SCRIPT,
|
ScriptEngine(const QString& scriptContents = NO_SCRIPT,
|
||||||
const QString& fileNameString = QString(""),
|
const QString& fileNameString = QString(""),
|
||||||
AbstractControllerScriptingInterface* controllerScriptingInterface = NULL);
|
AbstractControllerScriptingInterface* controllerScriptingInterface = NULL);
|
||||||
|
@ -94,6 +91,7 @@ public:
|
||||||
bool isUserLoaded() const { return _isUserLoaded; }
|
bool isUserLoaded() const { return _isUserLoaded; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void loadURL(const QUrl& scriptURL);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1);
|
QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1);
|
||||||
|
@ -109,6 +107,8 @@ public slots:
|
||||||
void nodeKilled(SharedNodePointer node);
|
void nodeKilled(SharedNodePointer node);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void scriptLoaded(const QUrl& scriptURL);
|
||||||
|
void errorLoadingScript(const QUrl& scriptURL);
|
||||||
void update(float deltaTime);
|
void update(float deltaTime);
|
||||||
void scriptEnding();
|
void scriptEnding();
|
||||||
void finished(const QString& fileNameString);
|
void finished(const QString& fileNameString);
|
||||||
|
@ -155,6 +155,8 @@ private:
|
||||||
ArrayBufferClass* _arrayBufferClass;
|
ArrayBufferClass* _arrayBufferClass;
|
||||||
|
|
||||||
QHash<QUuid, quint16> _outgoingScriptAudioSequenceNumbers;
|
QHash<QUuid, quint16> _outgoingScriptAudioSequenceNumbers;
|
||||||
|
private slots:
|
||||||
|
void handleScriptDownload();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_ScriptEngine_h
|
#endif // hifi_ScriptEngine_h
|
||||||
|
|
Loading…
Reference in a new issue