mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-16 22:30:42 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into optimizeFindZones
This commit is contained in:
commit
b76f8509aa
39 changed files with 608 additions and 298 deletions
23
cmake/externals/LibOVR/CMakeLists.txt
vendored
23
cmake/externals/LibOVR/CMakeLists.txt
vendored
|
@ -12,19 +12,16 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
|||
# 0.5 public
|
||||
# URL http://static.oculus.com/sdk-downloads/ovr_sdk_win_0.5.0.1.zip
|
||||
# URL_MD5 d3fc4c02db9be5ff08af4ef4c97b32f9
|
||||
# 0.6 public
|
||||
# URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip
|
||||
# URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9
|
||||
# 0.8 public
|
||||
# URL http://static.oculus.com/sdk-downloads/0.8.0.0/Public/1445451746/ovr_sdk_win_0.8.0.0.zip
|
||||
# URL_MD5 54944b03b95149d6010f84eb701b9647
|
||||
# 1.3 public
|
||||
# URL http://hifi-public.s3.amazonaws.com/dependencies/ovr_sdk_win_1.3.0_public.zip
|
||||
# URL_MD5 4d26faba0c1f35ff80bf674c96ed9259
|
||||
|
||||
if (WIN32)
|
||||
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL http://static.oculus.com/sdk-downloads/0.8.0.0/Public/1445451746/ovr_sdk_win_0.8.0.0.zip
|
||||
URL_MD5 54944b03b95149d6010f84eb701b9647
|
||||
URL http://hifi-public.s3.amazonaws.com/dependencies/ovr_sdk_win_1.3.0_public.zip
|
||||
URL_MD5 a2dcf695e0f03a70fdd1ed7480585e82
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
@ -33,14 +30,16 @@ if (WIN32)
|
|||
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
|
||||
|
||||
# FIXME need to account for different architectures
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/LibOVR/Include CACHE TYPE INTERNAL)
|
||||
set(LIBOVR_DIR ${SOURCE_DIR}/OculusSDK/LibOVR)
|
||||
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/LibOVR/Lib/Windows/x64/Release/VS2013/LibOVR.lib CACHE TYPE INTERNAL)
|
||||
set(LIBOVR_LIB_DIR ${LIBOVR_DIR}/Lib/Windows/x64/Release/VS2013 CACHE TYPE INTERNAL)
|
||||
else()
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/LibOVR/Lib/Windows/Win32/Release/VS2013/LibOVR.lib CACHE TYPE INTERNAL)
|
||||
set(LIBOVR_LIB_DIR ${LIBOVR_DIR}/Lib/Windows/Win32/Release/VS2013 CACHE TYPE INTERNAL)
|
||||
endif()
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${LIBOVR_DIR}/Include CACHE TYPE INTERNAL)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${LIBOVR_LIB_DIR}/LibOVR.lib CACHE TYPE INTERNAL)
|
||||
|
||||
elseif(APPLE)
|
||||
|
||||
ExternalProject_Add(
|
||||
|
|
|
@ -85,8 +85,8 @@ macro(GENERATE_INSTALLERS)
|
|||
|
||||
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")
|
||||
cpack_add_component(${CLIENT_COMPONENT} DISPLAY_NAME "High Fidelity Interface")
|
||||
cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "High Fidelity Sandbox")
|
||||
|
||||
include(CPack)
|
||||
endmacro()
|
||||
|
|
|
@ -53,7 +53,7 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set(CONSOLE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
||||
set(INTERFACE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
||||
|
||||
set(CONSOLE_EXEC_NAME "Server Console.app")
|
||||
set(CONSOLE_EXEC_NAME "Sandbox.app")
|
||||
set(CONSOLE_INSTALL_APP_PATH "${CONSOLE_INSTALL_DIR}/${CONSOLE_EXEC_NAME}")
|
||||
|
||||
set(CONSOLE_APP_CONTENTS "${CONSOLE_INSTALL_APP_PATH}/Contents")
|
||||
|
@ -84,12 +84,19 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
|
||||
# shortcut names
|
||||
if (PRODUCTION_BUILD)
|
||||
set(INTERFACE_SHORTCUT_NAME "High Fidelity")
|
||||
set(CONSOLE_SHORTCUT_NAME "Server Console")
|
||||
set(INTERFACE_SHORTCUT_NAME "Interface")
|
||||
set(CONSOLE_SHORTCUT_NAME "Sandbox")
|
||||
else ()
|
||||
set(INTERFACE_SHORTCUT_NAME "High Fidelity - ${BUILD_VERSION}")
|
||||
set(CONSOLE_SHORTCUT_NAME "Server Console - ${BUILD_VERSION}")
|
||||
set(INTERFACE_SHORTCUT_NAME "Interface - ${BUILD_VERSION}")
|
||||
set(CONSOLE_SHORTCUT_NAME "Sandbox - ${BUILD_VERSION}")
|
||||
endif ()
|
||||
|
||||
set(INTERFACE_HF_SHORTCUT_NAME "High Fidelity ${INTERFACE_SHORTCUT_NAME}")
|
||||
set(CONSOLE_HF_SHORTCUT_NAME "High Fidelity ${CONSOLE_SHORTCUT_NAME}")
|
||||
|
||||
set(PRE_SANDBOX_INTERFACE_SHORTCUT_NAME "High Fidelity")
|
||||
set(PRE_SANDBOX_CONSOLE_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")
|
||||
|
|
|
@ -10,10 +10,14 @@
|
|||
#
|
||||
|
||||
set(INTERFACE_SHORTCUT_NAME "@INTERFACE_SHORTCUT_NAME@")
|
||||
set(INTERFACE_HF_SHORTCUT_NAME "@INTERFACE_HF_SHORTCUT_NAME@")
|
||||
set(INTERFACE_WIN_EXEC_NAME "@INTERFACE_EXEC_PREFIX@.exe")
|
||||
set(CONSOLE_INSTALL_SUBDIR "@CONSOLE_INSTALL_DIR@")
|
||||
set(CONSOLE_SHORTCUT_NAME "@CONSOLE_SHORTCUT_NAME@")
|
||||
set(CONSOLE_HF_SHORTCUT_NAME "@CONSOLE_HF_SHORTCUT_NAME@")
|
||||
set(CONSOLE_WIN_EXEC_NAME "@CONSOLE_EXEC_NAME@")
|
||||
set(PRE_SANDBOX_INTERFACE_SHORTCUT_NAME "@PRE_SANDBOX_INTERFACE_SHORTCUT_NAME@")
|
||||
set(PRE_SANDBOX_CONSOLE_SHORTCUT_NAME "@PRE_SANDBOX_CONSOLE_SHORTCUT_NAME@")
|
||||
set(DS_EXEC_NAME "@DS_EXEC_NAME@")
|
||||
set(AC_EXEC_NAME "@AC_EXEC_NAME@")
|
||||
set(HIGH_FIDELITY_PROTOCOL "@HIGH_FIDELITY_PROTOCOL@")
|
||||
|
|
|
@ -387,7 +387,7 @@ Function PostInstallOptionsPage
|
|||
StrCpy $OffsetUnits u
|
||||
|
||||
${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@}
|
||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @INTERFACE_SHORTCUT_NAME@"
|
||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @INTERFACE_HF_SHORTCUT_NAME@"
|
||||
Pop $DesktopClientCheckbox
|
||||
IntOp $CurrentOffset $CurrentOffset + 15
|
||||
|
||||
|
@ -396,7 +396,7 @@ Function PostInstallOptionsPage
|
|||
${EndIf}
|
||||
|
||||
${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@}
|
||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for High Fidelity @CONSOLE_SHORTCUT_NAME@"
|
||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @CONSOLE_HF_SHORTCUT_NAME@"
|
||||
Pop $DesktopServerCheckbox
|
||||
|
||||
; set the checkbox state depending on what is present in the registry
|
||||
|
@ -404,7 +404,7 @@ Function PostInstallOptionsPage
|
|||
|
||||
IntOp $CurrentOffset $CurrentOffset + 15
|
||||
|
||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch High Fidelity @CONSOLE_SHORTCUT_NAME@ on startup"
|
||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ on startup"
|
||||
Pop $ServerStartupCheckbox
|
||||
|
||||
; set the checkbox state depending on what is present in the registry
|
||||
|
@ -414,9 +414,9 @@ Function PostInstallOptionsPage
|
|||
${EndIf}
|
||||
|
||||
${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@}
|
||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch High Fidelity Server Console after install"
|
||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ after install"
|
||||
${Else}
|
||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch High Fidelity after install"
|
||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @INTERFACE_HF_SHORTCUT_NAME@ after install"
|
||||
${EndIf}
|
||||
|
||||
Pop $LaunchNowCheckbox
|
||||
|
@ -465,10 +465,10 @@ Function ReadPostInstallOptions
|
|||
${EndIf}
|
||||
|
||||
${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@}
|
||||
; check if the user asked for a desktop shortcut to Server Console
|
||||
; check if the user asked for a desktop shortcut to Sandbox
|
||||
${NSD_GetState} $DesktopServerCheckbox $DesktopServerState
|
||||
|
||||
; check if the user asked to have Server Console launched every startup
|
||||
; check if the user asked to have Sandbox launched every startup
|
||||
${NSD_GetState} $ServerStartupCheckbox $ServerStartupState
|
||||
${EndIf}
|
||||
|
||||
|
@ -485,7 +485,7 @@ Function HandlePostInstallOptions
|
|||
${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@}
|
||||
; check if the user asked for a desktop shortcut to High Fidelity
|
||||
${If} $DesktopClientState == ${BST_CHECKED}
|
||||
CreateShortCut "$DESKTOP\@INTERFACE_SHORTCUT_NAME@.lnk" "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@"
|
||||
CreateShortCut "$DESKTOP\@INTERFACE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@"
|
||||
!insertmacro WritePostInstallOption "@CLIENT_DESKTOP_SHORTCUT_REG_KEY@" YES
|
||||
${Else}
|
||||
!insertmacro WritePostInstallOption @CLIENT_DESKTOP_SHORTCUT_REG_KEY@ NO
|
||||
|
@ -494,23 +494,23 @@ Function HandlePostInstallOptions
|
|||
${EndIf}
|
||||
|
||||
${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@}
|
||||
; check if the user asked for a desktop shortcut to Server Console
|
||||
; check if the user asked for a desktop shortcut to Sandbox
|
||||
${If} $DesktopServerState == ${BST_CHECKED}
|
||||
CreateShortCut "$DESKTOP\@CONSOLE_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
||||
CreateShortCut "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
||||
!insertmacro WritePostInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ YES
|
||||
${Else}
|
||||
!insertmacro WritePostInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ NO
|
||||
${EndIf}
|
||||
|
||||
; check if the user asked to have Server Console launched every startup
|
||||
; check if the user asked to have Sandbox launched every startup
|
||||
${If} $ServerStartupState == ${BST_CHECKED}
|
||||
; in case we added a shortcut in the global context, pull that now
|
||||
SetShellVarContext all
|
||||
Delete "$SMSTARTUP\@CONSOLE_SHORTCUT_NAME@.lnk"
|
||||
Delete "$SMSTARTUP\@PRE_SANDBOX_CONSOLE_SHORTCUT_NAME@.lnk"
|
||||
|
||||
; make a startup shortcut in this user's current context
|
||||
SetShellVarContext current
|
||||
CreateShortCut "$SMSTARTUP\@CONSOLE_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
||||
CreateShortCut "$SMSTARTUP\@CONSOLE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
||||
|
||||
; reset the shell var context back
|
||||
SetShellVarContext all
|
||||
|
@ -589,6 +589,19 @@ Section "-Core installation"
|
|||
Delete "$INSTDIR\version"
|
||||
Delete "$INSTDIR\xinput1_3.dll"
|
||||
|
||||
; Delete old desktop shortcuts before they were renamed during Sandbox rename
|
||||
Delete "$DESKTOP\@PRE_SANDBOX_INTERFACE_SHORTCUT_NAME@.lnk"
|
||||
Delete "$DESKTOP\@PRE_SANDBOX_CONSOLE_SHORTCUT_NAME@.lnk"
|
||||
|
||||
; Delete old Start Menu shortcuts before Sandbox rename
|
||||
Delete "$SMPROGRAMS\$STARTMENU_FOLDER\@PRE_SANDBOX_INTERFACE_SHORTCUT_NAME@.lnk"
|
||||
Delete "$SMPROGRAMS\$STARTMENU_FOLDER\@PRE_SANDBOX_CONSOLE_SHORTCUT_NAME@.lnk"
|
||||
|
||||
; Delete old startup item for Server Console before Sandbox rename
|
||||
SetShellVarContext current
|
||||
Delete "$SMSTARTUP\@PRE_SANDBOX_CONSOLE_SHORTCUT_NAME@.lnk"
|
||||
SetShellVarContext all
|
||||
|
||||
; Rename the incorrectly cased Raleway font
|
||||
Rename "$INSTDIR\resources\qml\styles-uit\RalewaySemibold.qml" "$INSTDIR\resources\qml\styles-uit\RalewaySemiBold.qml"
|
||||
|
||||
|
@ -724,8 +737,8 @@ SectionEnd
|
|||
!macroend
|
||||
|
||||
!macro CheckForRunningApplications action prompter
|
||||
!insertmacro PromptForRunningApplication "@INTERFACE_WIN_EXEC_NAME@" "High Fidelity client" ${action} ${prompter}
|
||||
!insertmacro PromptForRunningApplication "@CONSOLE_WIN_EXEC_NAME@" "Server Console" ${action} ${prompter}
|
||||
!insertmacro PromptForRunningApplication "@INTERFACE_WIN_EXEC_NAME@" "@CONSOLE_SHORTCUT_NAME@" ${action} ${prompter}
|
||||
!insertmacro PromptForRunningApplication "@CONSOLE_WIN_EXEC_NAME@" "@INTERFACE_SHORTCUT_NAME@" ${action} ${prompter}
|
||||
!insertmacro PromptForRunningApplication "@DS_EXEC_NAME@" "Domain Server" ${action} ${prompter}
|
||||
!insertmacro PromptForRunningApplication "@AC_EXEC_NAME@" "Assignment Client" ${action} ${prompter}
|
||||
!macroend
|
||||
|
@ -869,12 +882,12 @@ Section "Uninstall"
|
|||
Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
|
||||
Delete "$SMPROGRAMS\$MUI_TEMP\@INTERFACE_SHORTCUT_NAME@.lnk"
|
||||
Delete "$SMPROGRAMS\$MUI_TEMP\@CONSOLE_SHORTCUT_NAME@.lnk"
|
||||
Delete "$DESKTOP\@INTERFACE_SHORTCUT_NAME@.lnk"
|
||||
Delete "$DESKTOP\@CONSOLE_SHORTCUT_NAME@.lnk"
|
||||
Delete "$DESKTOP\@INTERFACE_HF_SHORTCUT_NAME@.lnk"
|
||||
Delete "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk"
|
||||
|
||||
; if it exists, delete the startup shortcut for the current user
|
||||
SetShellVarContext current
|
||||
Delete "$SMSTARTUP\@CONSOLE_SHORTCUT_NAME@.lnk"
|
||||
Delete "$SMSTARTUP\@CONSOLE_HF_SHORTCUT_NAME@.lnk"
|
||||
SetShellVarContext all
|
||||
|
||||
@CPACK_NSIS_DELETE_ICONS@
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <QtNetwork/QNetworkRequest>
|
||||
|
||||
#include <LimitedNodeList.h>
|
||||
#include <NetworkAccessManager.h>
|
||||
#include <NetworkingConstants.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
|
@ -33,7 +34,8 @@ IceServer::IceServer(int argc, char* argv[]) :
|
|||
_id(QUuid::createUuid()),
|
||||
_serverSocket(),
|
||||
_activePeers(),
|
||||
_httpManager(QHostAddress::AnyIPv4, 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),
|
||||
_lastInactiveCheckTimestamp(QDateTime::currentMSecsSinceEpoch())
|
||||
{
|
||||
// start the ice-server socket
|
||||
qDebug() << "ice-server socket is listening on" << ICE_SERVER_DEFAULT_PORT;
|
||||
|
@ -68,8 +70,6 @@ bool IceServer::packetVersionMatch(const udt::Packet& packet) {
|
|||
|
||||
void IceServer::processPacket(std::unique_ptr<udt::Packet> packet) {
|
||||
|
||||
_lastPacketTimestamp = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
auto nlPacket = NLPacket::fromBase(std::move(packet));
|
||||
|
||||
// make sure that this packet at least looks like something we can read
|
||||
|
@ -201,8 +201,8 @@ bool IceServer::isVerifiedHeartbeat(const QUuid& domainID, const QByteArray& pla
|
|||
|
||||
void IceServer::requestDomainPublicKey(const QUuid& domainID) {
|
||||
// send a request to the metaverse API for the public key for this domain
|
||||
QNetworkAccessManager* manager = new QNetworkAccessManager { this };
|
||||
connect(manager, &QNetworkAccessManager::finished, this, &IceServer::publicKeyReplyFinished);
|
||||
auto& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
connect(&networkAccessManager, &QNetworkAccessManager::finished, this, &IceServer::publicKeyReplyFinished);
|
||||
|
||||
QUrl publicKeyURL { NetworkingConstants::METAVERSE_SERVER_URL };
|
||||
QString publicKeyPath = QString("/api/v1/domains/%1/public_key").arg(uuidStringWithoutCurlyBraces(domainID));
|
||||
|
@ -213,7 +213,7 @@ void IceServer::requestDomainPublicKey(const QUuid& domainID) {
|
|||
|
||||
qDebug() << "Requesting public key for domain with ID" << domainID;
|
||||
|
||||
manager->get(publicKeyRequest);
|
||||
networkAccessManager.get(publicKeyRequest);
|
||||
}
|
||||
|
||||
void IceServer::publicKeyReplyFinished(QNetworkReply* reply) {
|
||||
|
@ -281,6 +281,8 @@ void IceServer::sendPeerInformationPacket(const NetworkPeer& peer, const HifiSoc
|
|||
void IceServer::clearInactivePeers() {
|
||||
NetworkPeerHash::iterator peerItem = _activePeers.begin();
|
||||
|
||||
_lastInactiveCheckTimestamp = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
while (peerItem != _activePeers.end()) {
|
||||
SharedNetworkPeer peer = peerItem.value();
|
||||
|
||||
|
@ -309,11 +311,14 @@ bool IceServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url, b
|
|||
|
||||
const quint64 MAX_PACKET_GAP_MS_FOR_STUCK_SOCKET = 10 * 1000;
|
||||
|
||||
int statusNumber = (QDateTime::currentMSecsSinceEpoch() - _lastPacketTimestamp > MAX_PACKET_GAP_MS_FOR_STUCK_SOCKET)
|
||||
? 1 : 0;
|
||||
auto sinceLastInactiveCheck = QDateTime::currentMSecsSinceEpoch() - _lastInactiveCheckTimestamp;
|
||||
int statusNumber = (sinceLastInactiveCheck > MAX_PACKET_GAP_MS_FOR_STUCK_SOCKET) ? 1 : 0;
|
||||
|
||||
connection->respond(HTTPConnection::StatusCode200, QByteArray::number(statusNumber));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ private:
|
|||
using DomainPublicKeyHash = std::unordered_map<QUuid, RSAUniquePtr>;
|
||||
DomainPublicKeyHash _domainPublicKeys;
|
||||
|
||||
quint64 _lastPacketTimestamp;
|
||||
quint64 _lastInactiveCheckTimestamp;
|
||||
};
|
||||
|
||||
#endif // hifi_IceServer_h
|
||||
|
|
|
@ -1489,11 +1489,15 @@ void Application::paintGL() {
|
|||
// FIXME not needed anymore?
|
||||
_offscreenContext->makeCurrent();
|
||||
|
||||
displayPlugin->updateHeadPose(_frameCount);
|
||||
displayPlugin->beginFrameRender(_frameCount);
|
||||
|
||||
// update the avatar with a fresh HMD pose
|
||||
getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose());
|
||||
|
||||
// update sensorToWorldMatrix for camera and hand controllers
|
||||
getMyAvatar()->updateSensorToWorldMatrix();
|
||||
|
||||
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
|
||||
|
||||
|
@ -2006,6 +2010,12 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Y:
|
||||
if (isShifted && isMeta) {
|
||||
getActiveDisplayPlugin()->cycleDebugOutput();
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_B:
|
||||
if (isMeta) {
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
|
@ -2571,11 +2581,6 @@ void Application::idle(uint64_t now) {
|
|||
return; // bail early, nothing to do here.
|
||||
}
|
||||
|
||||
checkChangeCursor();
|
||||
|
||||
Stats::getInstance()->updateStats();
|
||||
AvatarInputs::getInstance()->update();
|
||||
|
||||
// These tasks need to be done on our first idle, because we don't want the showing of
|
||||
// overlay subwindows to do a showDesktop() until after the first time through
|
||||
static bool firstIdle = true;
|
||||
|
@ -2624,6 +2629,11 @@ void Application::idle(uint64_t now) {
|
|||
// We're going to execute idle processing, so restart the last idle timer
|
||||
_lastTimeUpdated.start();
|
||||
|
||||
checkChangeCursor();
|
||||
|
||||
Stats::getInstance()->updateStats();
|
||||
AvatarInputs::getInstance()->update();
|
||||
|
||||
{
|
||||
static uint64_t lastIdleStart{ now };
|
||||
uint64_t idleStartToStartDuration = now - lastIdleStart;
|
||||
|
@ -3390,9 +3400,6 @@ void Application::update(float deltaTime) {
|
|||
|
||||
qApp->updateMyAvatarLookAtPosition();
|
||||
|
||||
// update sensorToWorldMatrix for camera and hand controllers
|
||||
myAvatar->updateSensorToWorldMatrix();
|
||||
|
||||
{
|
||||
PROFILE_RANGE_EX("MyAvatar", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||
avatarManager->updateMyAvatar(deltaTime);
|
||||
|
|
|
@ -81,6 +81,9 @@ namespace controller {
|
|||
// Triggers
|
||||
LT,
|
||||
RT,
|
||||
// Grips (Oculus touch squeeze)
|
||||
LG,
|
||||
RG,
|
||||
NUM_STANDARD_AXES,
|
||||
LZ = LT,
|
||||
RZ = RT
|
||||
|
|
|
@ -552,9 +552,9 @@ float OpenGLDisplayPlugin::presentRate() {
|
|||
{
|
||||
Lock lock(_mutex);
|
||||
result = _usecsPerFrame.getAverage();
|
||||
result = 1.0f / result;
|
||||
result *= USECS_PER_SECOND;
|
||||
}
|
||||
result = 1.0f / result;
|
||||
result *= USECS_PER_SECOND;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
#include <GLMHelpers.h>
|
||||
#include <SimpleMovingAverage.h>
|
||||
#include <gl/OglplusHelpers.h>
|
||||
#include <gl/GLEscrow.h>
|
||||
|
||||
#define THREADED_PRESENT 1
|
||||
#include <gl/GLEscrow.h>
|
||||
|
||||
class OpenGLDisplayPlugin : public DisplayPlugin {
|
||||
protected:
|
||||
|
|
|
@ -69,10 +69,11 @@ void HmdDisplayPlugin::compositeOverlay() {
|
|||
// set the alpha
|
||||
Uniform<float>(*_program, _alphaUniform).Set(overlayAlpha);
|
||||
|
||||
auto eyePoses = _currentPresentFrameInfo.eyePoses;
|
||||
_sphereSection->Use();
|
||||
for_each_eye([&](Eye eye) {
|
||||
eyeViewport(eye);
|
||||
auto modelView = glm::inverse(_currentRenderEyePoses[eye]); // *glm::translate(mat4(), vec3(0, 0, -1));
|
||||
auto modelView = glm::inverse(eyePoses[eye]); // *glm::translate(mat4(), vec3(0, 0, -1));
|
||||
auto mvp = _eyeProjections[eye] * modelView;
|
||||
Uniform<glm::mat4>(*_program, _mvpUniform).Set(mvp);
|
||||
_sphereSection->Draw();
|
||||
|
@ -95,10 +96,10 @@ void HmdDisplayPlugin::compositePointer() {
|
|||
// Mouse pointer
|
||||
_plane->Use();
|
||||
// Reconstruct the headpose from the eye poses
|
||||
auto headPosition = (vec3(_currentRenderEyePoses[Left][3]) + vec3(_currentRenderEyePoses[Right][3])) / 2.0f;
|
||||
auto headPosition = vec3(_currentPresentFrameInfo.headPose[3]);
|
||||
for_each_eye([&](Eye eye) {
|
||||
eyeViewport(eye);
|
||||
auto reticleTransform = compositorHelper->getReticleTransform(_currentRenderEyePoses[eye], headPosition);
|
||||
auto reticleTransform = compositorHelper->getReticleTransform(_currentPresentFrameInfo.eyePoses[eye], headPosition);
|
||||
auto mvp = _eyeProjections[eye] * reticleTransform;
|
||||
Uniform<glm::mat4>(*_program, _mvpUniform).Set(mvp);
|
||||
_plane->Draw();
|
||||
|
@ -160,15 +161,28 @@ void HmdDisplayPlugin::internalPresent() {
|
|||
|
||||
void HmdDisplayPlugin::setEyeRenderPose(uint32_t frameIndex, Eye eye, const glm::mat4& pose) {
|
||||
Lock lock(_mutex);
|
||||
_renderEyePoses[frameIndex][eye] = pose;
|
||||
FrameInfo& frame = _frameInfos[frameIndex];
|
||||
frame.eyePoses[eye] = pose;
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::updateFrameData() {
|
||||
// Check if we have old frame data to discard
|
||||
{
|
||||
Lock lock(_mutex);
|
||||
auto itr = _frameInfos.find(_currentRenderFrameIndex);
|
||||
if (itr != _frameInfos.end()) {
|
||||
_frameInfos.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
Parent::updateFrameData();
|
||||
Lock lock(_mutex);
|
||||
_currentRenderEyePoses = _renderEyePoses[_currentRenderFrameIndex];
|
||||
|
||||
{
|
||||
Lock lock(_mutex);
|
||||
_currentPresentFrameInfo = _frameInfos[_currentRenderFrameIndex];
|
||||
}
|
||||
}
|
||||
|
||||
glm::mat4 HmdDisplayPlugin::getHeadPose() const {
|
||||
return _headPoseCache.get();
|
||||
return _currentRenderFrameInfo.get().headPose;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,16 @@ public:
|
|||
|
||||
virtual glm::mat4 getHeadPose() const override;
|
||||
|
||||
using EyePoses = std::array<glm::mat4, 2>;
|
||||
|
||||
struct FrameInfo {
|
||||
EyePoses eyePoses;
|
||||
glm::mat4 headPose;
|
||||
double sensorSampleTime { 0 };
|
||||
double predictedDisplayTime { 0 };
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
virtual void hmdPresent() = 0;
|
||||
virtual bool isHmdMounted() const = 0;
|
||||
|
@ -46,10 +56,10 @@ protected:
|
|||
glm::mat4 _cullingProjection;
|
||||
glm::uvec2 _renderTargetSize;
|
||||
float _ipd { 0.064f };
|
||||
using EyePoses = std::array<glm::mat4, 2>;
|
||||
QMap<uint32_t, EyePoses> _renderEyePoses;
|
||||
EyePoses _currentRenderEyePoses;
|
||||
ThreadSafeValueCache<glm::mat4> _headPoseCache { glm::mat4() };
|
||||
|
||||
QMap<uint32_t, FrameInfo> _frameInfos;
|
||||
FrameInfo _currentPresentFrameInfo;
|
||||
ThreadSafeValueCache<FrameInfo> _currentRenderFrameInfo;
|
||||
|
||||
private:
|
||||
bool _enablePreview { false };
|
||||
|
|
|
@ -122,7 +122,7 @@ public:
|
|||
}
|
||||
|
||||
// will query the underlying hmd api to compute the most recent head pose
|
||||
virtual void updateHeadPose(uint32_t frameIndex) {}
|
||||
virtual void beginFrameRender(uint32_t frameIndex) {}
|
||||
|
||||
// returns a copy of the most recent head pose, computed via updateHeadPose
|
||||
virtual glm::mat4 getHeadPose() const {
|
||||
|
@ -142,6 +142,8 @@ public:
|
|||
virtual float presentRate() { return -1.0f; }
|
||||
uint32_t presentCount() const { return _presentedFrameIndex; }
|
||||
|
||||
virtual void cycleDebugOutput() {}
|
||||
|
||||
static const QString& MENU_PATH();
|
||||
|
||||
signals:
|
||||
|
|
|
@ -538,7 +538,7 @@ void Model::setVisibleInScene(bool newValue, std::shared_ptr<render::Scene> scen
|
|||
pendingChanges.resetItem(item, _modelMeshRenderItems[item]);
|
||||
}
|
||||
foreach (auto item, _collisionRenderItems.keys()) {
|
||||
pendingChanges.resetItem(item, _modelMeshRenderItems[item]);
|
||||
pendingChanges.resetItem(item, _collisionRenderItems[item]);
|
||||
}
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
|
|
|
@ -16,8 +16,13 @@
|
|||
using namespace render;
|
||||
|
||||
void PendingChanges::resetItem(ItemID id, const PayloadPointer& payload) {
|
||||
_resetItems.push_back(id);
|
||||
_resetPayloads.push_back(payload);
|
||||
if (payload) {
|
||||
_resetItems.push_back(id);
|
||||
_resetPayloads.push_back(payload);
|
||||
} else {
|
||||
qDebug() << "WARNING: PendingChanges::resetItem with a null payload!";
|
||||
removeItem(id);
|
||||
}
|
||||
}
|
||||
|
||||
void PendingChanges::removeItem(ItemID id) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
template <typename T>
|
||||
class ThreadSafeValueCache {
|
||||
public:
|
||||
ThreadSafeValueCache() {}
|
||||
ThreadSafeValueCache(const T& v) : _value { v } {}
|
||||
|
||||
// returns atomic copy of the cached value.
|
||||
|
|
|
@ -12,14 +12,19 @@
|
|||
#include "OculusHelpers.h"
|
||||
|
||||
void OculusBaseDisplayPlugin::resetSensors() {
|
||||
ovr_RecenterPose(_session);
|
||||
ovr_RecenterTrackingOrigin(_session);
|
||||
}
|
||||
|
||||
void OculusBaseDisplayPlugin::updateHeadPose(uint32_t frameIndex) {
|
||||
auto displayTime = ovr_GetPredictedDisplayTime(_session, frameIndex);
|
||||
auto trackingState = ovr_GetTrackingState(_session, displayTime, true);
|
||||
mat4 headPose = toGlm(trackingState.HeadPose.ThePose);
|
||||
_headPoseCache.set(headPose);
|
||||
void OculusBaseDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
|
||||
FrameInfo frame;
|
||||
frame.sensorSampleTime = ovr_GetTimeInSeconds();;
|
||||
frame.predictedDisplayTime = ovr_GetPredictedDisplayTime(_session, frameIndex);
|
||||
auto trackingState = ovr_GetTrackingState(_session, frame.predictedDisplayTime, ovrTrue);
|
||||
frame.headPose = toGlm(trackingState.HeadPose.ThePose);
|
||||
|
||||
_currentRenderFrameInfo.set(frame);
|
||||
Lock lock(_mutex);
|
||||
_frameInfos[frameIndex] = frame;
|
||||
}
|
||||
|
||||
bool OculusBaseDisplayPlugin::isSupported() const {
|
||||
|
@ -42,36 +47,30 @@ bool OculusBaseDisplayPlugin::internalActivate() {
|
|||
|
||||
_hmdDesc = ovr_GetHmdDesc(_session);
|
||||
|
||||
_ipd = ovr_GetFloat(_session, OVR_KEY_IPD, _ipd);
|
||||
|
||||
glm::uvec2 eyeSizes[2];
|
||||
_viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
|
||||
|
||||
_ipd = 0;
|
||||
ovr_for_each_eye([&](ovrEyeType eye) {
|
||||
_eyeFovs[eye] = _hmdDesc.DefaultEyeFov[eye];
|
||||
ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_session, eye, _eyeFovs[eye]);
|
||||
ovrMatrix4f ovrPerspectiveProjection =
|
||||
ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
|
||||
ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_ClipRangeOpenGL);
|
||||
_eyeProjections[eye] = toGlm(ovrPerspectiveProjection);
|
||||
_eyeOffsets[eye] = glm::translate(mat4(), toGlm(erd.HmdToEyeViewOffset));
|
||||
_eyeOffsets[eye] = glm::translate(mat4(), toGlm(erd.HmdToEyeOffset));
|
||||
eyeSizes[eye] = toGlm(ovr_GetFovTextureSize(_session, eye, erd.Fov, 1.0f));
|
||||
_viewScaleDesc.HmdToEyeViewOffset[eye] = erd.HmdToEyeViewOffset;
|
||||
_viewScaleDesc.HmdToEyeOffset[eye] = erd.HmdToEyeOffset;
|
||||
_ipd += glm::abs(glm::length(toGlm(erd.HmdToEyeOffset)));
|
||||
});
|
||||
|
||||
auto combinedFov = _eyeFovs[0];
|
||||
combinedFov.LeftTan = combinedFov.RightTan = std::max(combinedFov.LeftTan, combinedFov.RightTan);
|
||||
_cullingProjection = toGlm(ovrMatrix4f_Projection(combinedFov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded));
|
||||
_cullingProjection = toGlm(ovrMatrix4f_Projection(combinedFov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_ClipRangeOpenGL));
|
||||
|
||||
_renderTargetSize = uvec2(
|
||||
eyeSizes[0].x + eyeSizes[1].x,
|
||||
std::max(eyeSizes[0].y, eyeSizes[1].y));
|
||||
|
||||
if (!OVR_SUCCESS(ovr_ConfigureTracking(_session,
|
||||
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
|
||||
logWarning("Failed to attach to sensor device");
|
||||
}
|
||||
|
||||
// Parent class relies on our _session intialization, so it must come after that.
|
||||
memset(&_sceneLayer, 0, sizeof(ovrLayerEyeFov));
|
||||
_sceneLayer.Header.Type = ovrLayerType_EyeFov;
|
||||
_sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
|
||||
|
|
|
@ -20,7 +20,8 @@ public:
|
|||
|
||||
// Stereo specific methods
|
||||
virtual void resetSensors() override final;
|
||||
virtual void updateHeadPose(uint32_t frameIndex) override;
|
||||
virtual void beginFrameRender(uint32_t frameIndex) override;
|
||||
|
||||
|
||||
protected:
|
||||
void customizeContext() override;
|
||||
|
@ -28,9 +29,8 @@ protected:
|
|||
void internalDeactivate() override;
|
||||
|
||||
protected:
|
||||
ovrSession _session;
|
||||
ovrSession _session { nullptr };
|
||||
ovrGraphicsLuid _luid;
|
||||
float _ipd{ OVR_DEFAULT_IPD };
|
||||
ovrEyeRenderDesc _eyeRenderDescs[2];
|
||||
ovrFovPort _eyeFovs[2];
|
||||
ovrHmdDesc _hmdDesc;
|
||||
|
|
219
plugins/oculus/src/OculusControllerManager.cpp
Normal file
219
plugins/oculus/src/OculusControllerManager.cpp
Normal file
|
@ -0,0 +1,219 @@
|
|||
//
|
||||
// OculusControllerManager.cpp
|
||||
// input-plugins/src/input-plugins
|
||||
//
|
||||
// Created by Bradley Austin Davis 2016/03/04.
|
||||
// Copyright 2013-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
|
||||
//
|
||||
|
||||
#include "OculusControllerManager.h"
|
||||
|
||||
#include <QtCore/QLoggingCategory>
|
||||
|
||||
#include <plugins/PluginContainer.h>
|
||||
#include <controllers/UserInputMapper.h>
|
||||
#include <controllers/StandardControls.h>
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <PathUtils.h>
|
||||
|
||||
#include "OculusHelpers.h"
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(oculus)
|
||||
|
||||
|
||||
static const QString MENU_PARENT = "Avatar";
|
||||
static const QString MENU_NAME = "Oculus Touch Controllers";
|
||||
static const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME;
|
||||
|
||||
const QString OculusControllerManager::NAME = "Oculus";
|
||||
|
||||
bool OculusControllerManager::isSupported() const {
|
||||
return oculusAvailable();
|
||||
}
|
||||
|
||||
bool OculusControllerManager::activate() {
|
||||
InputPlugin::activate();
|
||||
if (!_session) {
|
||||
_session = acquireOculusSession();
|
||||
}
|
||||
Q_ASSERT(_session);
|
||||
|
||||
// register with UserInputMapper
|
||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||
if (_remote) {
|
||||
userInputMapper->registerDevice(_remote);
|
||||
}
|
||||
if (_touch) {
|
||||
userInputMapper->registerDevice(_touch);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OculusControllerManager::deactivate() {
|
||||
InputPlugin::deactivate();
|
||||
|
||||
if (_session) {
|
||||
releaseOculusSession();
|
||||
_session = nullptr;
|
||||
}
|
||||
|
||||
// unregister with UserInputMapper
|
||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||
if (_touch) {
|
||||
userInputMapper->removeDevice(_touch->getDeviceID());
|
||||
}
|
||||
if (_remote) {
|
||||
userInputMapper->removeDevice(_remote->getDeviceID());
|
||||
}
|
||||
}
|
||||
|
||||
void OculusControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||
PerformanceTimer perfTimer("OculusControllerManager::TouchDevice::update");
|
||||
|
||||
if (!OVR_SUCCESS(ovr_GetInputState(_session, ovrControllerType_Touch, &_inputState))) {
|
||||
qCWarning(oculus) << "Unable to read oculus input state";
|
||||
return;
|
||||
}
|
||||
|
||||
if (_touch) {
|
||||
_touch->update(deltaTime, inputCalibrationData, jointsCaptured);
|
||||
}
|
||||
if (_remote) {
|
||||
_remote->update(deltaTime, inputCalibrationData, jointsCaptured);
|
||||
}
|
||||
}
|
||||
|
||||
void OculusControllerManager::pluginFocusOutEvent() {
|
||||
if (_touch) {
|
||||
_touch->focusOutEvent();
|
||||
}
|
||||
if (_remote) {
|
||||
_remote->focusOutEvent();
|
||||
}
|
||||
}
|
||||
|
||||
using namespace controller;
|
||||
|
||||
static const std::vector<std::pair<ovrButton, StandardButtonChannel>> BUTTON_MAP { {
|
||||
{ ovrButton_X, X },
|
||||
{ ovrButton_Y, Y },
|
||||
{ ovrButton_A, A },
|
||||
{ ovrButton_B, B },
|
||||
{ ovrButton_LThumb, LS },
|
||||
{ ovrButton_RThumb, RS },
|
||||
{ ovrButton_LShoulder, LB },
|
||||
{ ovrButton_RShoulder, RB },
|
||||
} };
|
||||
|
||||
static const std::vector<std::pair<ovrTouch, StandardButtonChannel>> TOUCH_MAP { {
|
||||
{ ovrTouch_X, LEFT_SECONDARY_THUMB_TOUCH },
|
||||
{ ovrTouch_Y, LEFT_SECONDARY_THUMB_TOUCH },
|
||||
{ ovrTouch_A, RIGHT_SECONDARY_THUMB_TOUCH },
|
||||
{ ovrTouch_B, RIGHT_SECONDARY_THUMB_TOUCH },
|
||||
{ ovrTouch_LIndexTrigger, LEFT_PRIMARY_INDEX_TOUCH },
|
||||
{ ovrTouch_RIndexTrigger, RIGHT_PRIMARY_INDEX_TOUCH },
|
||||
{ ovrTouch_LThumb, LS_TOUCH },
|
||||
{ ovrTouch_RThumb, RS_TOUCH },
|
||||
{ ovrTouch_LThumbUp, LEFT_THUMB_UP },
|
||||
{ ovrTouch_RThumbUp, RIGHT_THUMB_UP },
|
||||
{ ovrTouch_LIndexPointing, LEFT_INDEX_POINT },
|
||||
{ ovrTouch_RIndexPointing, RIGHT_INDEX_POINT },
|
||||
} };
|
||||
|
||||
void OculusControllerManager::TouchDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||
_poseStateMap.clear();
|
||||
_buttonPressedMap.clear();
|
||||
|
||||
if (!jointsCaptured) {
|
||||
int numTrackedControllers = 0;
|
||||
static const auto REQUIRED_HAND_STATUS = ovrStatus_OrientationTracked & ovrStatus_PositionTracked;
|
||||
auto tracking = ovr_GetTrackingState(_parent._session, 0, false);
|
||||
ovr_for_each_hand([&](ovrHandType hand) {
|
||||
++numTrackedControllers;
|
||||
if (REQUIRED_HAND_STATUS == (tracking.HandStatusFlags[hand] & REQUIRED_HAND_STATUS)) {
|
||||
handlePose(deltaTime, inputCalibrationData, hand, tracking.HandPoses[hand]);
|
||||
}
|
||||
});
|
||||
}
|
||||
using namespace controller;
|
||||
// Axes
|
||||
const auto& inputState = _parent._inputState;
|
||||
_axisStateMap[LX] = inputState.Thumbstick[ovrHand_Left].x;
|
||||
_axisStateMap[LY] = inputState.Thumbstick[ovrHand_Left].y;
|
||||
_axisStateMap[LT] = inputState.IndexTrigger[ovrHand_Left];
|
||||
_axisStateMap[LG] = inputState.HandTrigger[ovrHand_Left];
|
||||
|
||||
_axisStateMap[RX] = inputState.Thumbstick[ovrHand_Right].x;
|
||||
_axisStateMap[RY] = inputState.Thumbstick[ovrHand_Right].y;
|
||||
_axisStateMap[RT] = inputState.IndexTrigger[ovrHand_Right];
|
||||
_axisStateMap[RG] = inputState.HandTrigger[ovrHand_Right];
|
||||
|
||||
// Buttons
|
||||
for (const auto& pair : BUTTON_MAP) {
|
||||
if (inputState.Buttons & pair.first) {
|
||||
_buttonPressedMap.insert(pair.second);
|
||||
}
|
||||
}
|
||||
// Touches
|
||||
for (const auto& pair : TOUCH_MAP) {
|
||||
if (inputState.Touches & pair.first) {
|
||||
_buttonPressedMap.insert(pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OculusControllerManager::TouchDevice::focusOutEvent() {
|
||||
_axisStateMap.clear();
|
||||
_buttonPressedMap.clear();
|
||||
};
|
||||
|
||||
void OculusControllerManager::TouchDevice::handlePose(float deltaTime,
|
||||
const controller::InputCalibrationData& inputCalibrationData, ovrHandType hand,
|
||||
const ovrPoseStatef& handPose) {
|
||||
auto poseId = hand == ovrHand_Left ? controller::LEFT_HAND : controller::RIGHT_HAND;
|
||||
auto& pose = _poseStateMap[poseId];
|
||||
pose.translation = toGlm(handPose.ThePose.Position);
|
||||
pose.rotation = toGlm(handPose.ThePose.Orientation);
|
||||
pose.angularVelocity = toGlm(handPose.AngularVelocity);
|
||||
pose.velocity = toGlm(handPose.LinearVelocity);
|
||||
}
|
||||
|
||||
controller::Input::NamedVector OculusControllerManager::TouchDevice::getAvailableInputs() const {
|
||||
using namespace controller;
|
||||
QVector<Input::NamedPair> availableInputs{
|
||||
// Trackpad analogs
|
||||
makePair(LX, "LX"),
|
||||
makePair(LY, "LY"),
|
||||
makePair(RX, "RX"),
|
||||
makePair(RY, "RY"),
|
||||
// trigger analogs
|
||||
makePair(LT, "LT"),
|
||||
makePair(RT, "RT"),
|
||||
|
||||
makePair(LB, "LB"),
|
||||
makePair(RB, "RB"),
|
||||
|
||||
makePair(LS, "LS"),
|
||||
makePair(RS, "RS"),
|
||||
makePair(LEFT_HAND, "LeftHand"),
|
||||
makePair(RIGHT_HAND, "RightHand"),
|
||||
|
||||
makePair(LEFT_PRIMARY_THUMB, "LeftPrimaryThumb"),
|
||||
makePair(LEFT_SECONDARY_THUMB, "LeftSecondaryThumb"),
|
||||
makePair(RIGHT_PRIMARY_THUMB, "RightPrimaryThumb"),
|
||||
makePair(RIGHT_SECONDARY_THUMB, "RightSecondaryThumb"),
|
||||
};
|
||||
return availableInputs;
|
||||
}
|
||||
|
||||
QString OculusControllerManager::TouchDevice::getDefaultMappingConfig() const {
|
||||
static const QString MAPPING_JSON = PathUtils::resourcesPath() + "/controllers/touch.json";
|
||||
return MAPPING_JSON;
|
||||
}
|
||||
|
||||
|
||||
|
81
plugins/oculus/src/OculusControllerManager.h
Normal file
81
plugins/oculus/src/OculusControllerManager.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2016/03/04
|
||||
// Copyright 2013-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
|
||||
//
|
||||
|
||||
#ifndef hifi__OculusControllerManager
|
||||
#define hifi__OculusControllerManager
|
||||
|
||||
#include <QObject>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
#include <controllers/InputDevice.h>
|
||||
#include <plugins/InputPlugin.h>
|
||||
|
||||
#include <OVR_CAPI.h>
|
||||
|
||||
class OculusControllerManager : public InputPlugin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Plugin functions
|
||||
bool isSupported() const override;
|
||||
bool isJointController() const override { return true; }
|
||||
const QString& getName() const override { return NAME; }
|
||||
|
||||
bool activate() override;
|
||||
void deactivate() override;
|
||||
|
||||
void pluginFocusOutEvent() override;
|
||||
void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||
|
||||
private:
|
||||
class OculusInputDevice : public controller::InputDevice {
|
||||
public:
|
||||
OculusInputDevice(OculusControllerManager& parent, const QString& name) : controller::InputDevice(name), _parent(parent) {}
|
||||
|
||||
OculusControllerManager& _parent;
|
||||
friend class OculusControllerManager;
|
||||
};
|
||||
|
||||
class RemoteDevice : public OculusInputDevice {
|
||||
public:
|
||||
using Pointer = std::shared_ptr<RemoteDevice>;
|
||||
RemoteDevice(OculusControllerManager& parent) : OculusInputDevice(parent, "Oculus Remote") {}
|
||||
|
||||
controller::Input::NamedVector getAvailableInputs() const override;
|
||||
QString getDefaultMappingConfig() const override;
|
||||
void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||
void focusOutEvent() override;
|
||||
|
||||
friend class OculusControllerManager;
|
||||
};
|
||||
|
||||
class TouchDevice : public OculusInputDevice {
|
||||
public:
|
||||
using Pointer = std::shared_ptr<TouchDevice>;
|
||||
TouchDevice(OculusControllerManager& parent) : OculusInputDevice(parent, "Oculus Touch") {}
|
||||
|
||||
controller::Input::NamedVector getAvailableInputs() const override;
|
||||
QString getDefaultMappingConfig() const override;
|
||||
void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||
void focusOutEvent() override;
|
||||
|
||||
private:
|
||||
void handlePose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, ovrHandType hand, const ovrPoseStatef& handPose);
|
||||
int _trackedControllers { 0 };
|
||||
friend class OculusControllerManager;
|
||||
};
|
||||
|
||||
ovrSession _session { nullptr };
|
||||
ovrInputState _inputState {};
|
||||
RemoteDevice::Pointer _remote;
|
||||
TouchDevice::Pointer _touch;
|
||||
static const QString NAME;
|
||||
};
|
||||
|
||||
#endif // hifi__OculusControllerManager
|
|
@ -10,6 +10,23 @@
|
|||
#include "OculusHelpers.h"
|
||||
|
||||
const QString OculusDisplayPlugin::NAME("Oculus Rift");
|
||||
static ovrPerfHudMode currentDebugMode = ovrPerfHud_Off;
|
||||
|
||||
bool OculusDisplayPlugin::internalActivate() {
|
||||
bool result = Parent::internalActivate();
|
||||
currentDebugMode = ovrPerfHud_Off;
|
||||
if (result && _session) {
|
||||
ovr_SetInt(_session, OVR_PERF_HUD_MODE, currentDebugMode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void OculusDisplayPlugin::cycleDebugOutput() {
|
||||
if (_session) {
|
||||
currentDebugMode = static_cast<ovrPerfHudMode>((currentDebugMode + 1) % ovrPerfHud_Count);
|
||||
ovr_SetInt(_session, OVR_PERF_HUD_MODE, currentDebugMode);
|
||||
}
|
||||
}
|
||||
|
||||
void OculusDisplayPlugin::customizeContext() {
|
||||
Parent::customizeContext();
|
||||
|
@ -48,12 +65,6 @@ void blit(const SrcFbo& srcFbo, const DstFbo& dstFbo) {
|
|||
});
|
||||
}
|
||||
|
||||
void OculusDisplayPlugin::updateFrameData() {
|
||||
Parent::updateFrameData();
|
||||
_sceneLayer.RenderPose[ovrEyeType::ovrEye_Left] = ovrPoseFromGlm(_currentRenderEyePoses[Left]);
|
||||
_sceneLayer.RenderPose[ovrEyeType::ovrEye_Right] = ovrPoseFromGlm(_currentRenderEyePoses[Right]);
|
||||
}
|
||||
|
||||
void OculusDisplayPlugin::hmdPresent() {
|
||||
|
||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)_currentRenderFrameIndex)
|
||||
|
@ -63,12 +74,15 @@ void OculusDisplayPlugin::hmdPresent() {
|
|||
}
|
||||
|
||||
blit(_compositeFramebuffer, _sceneFbo);
|
||||
_sceneFbo->Commit();
|
||||
{
|
||||
_sceneLayer.SensorSampleTime = _currentPresentFrameInfo.sensorSampleTime;
|
||||
_sceneLayer.RenderPose[ovrEyeType::ovrEye_Left] = ovrPoseFromGlm(_currentPresentFrameInfo.headPose);
|
||||
_sceneLayer.RenderPose[ovrEyeType::ovrEye_Right] = ovrPoseFromGlm(_currentPresentFrameInfo.headPose);
|
||||
ovrLayerHeader* layers = &_sceneLayer.Header;
|
||||
ovrResult result = ovr_SubmitFrame(_session, _currentRenderFrameIndex, &_viewScaleDesc, &layers, 1);
|
||||
if (!OVR_SUCCESS(result)) {
|
||||
logWarning("Failed to present");
|
||||
}
|
||||
}
|
||||
_sceneFbo->Increment();
|
||||
}
|
||||
|
|
|
@ -22,12 +22,13 @@ public:
|
|||
float getTargetFrameRate() override { return TARGET_RATE_Oculus; }
|
||||
|
||||
protected:
|
||||
bool internalActivate() override;
|
||||
void hmdPresent() override;
|
||||
// FIXME update with Oculus API call once it's available in the SDK
|
||||
bool isHmdMounted() const override { return true; }
|
||||
void customizeContext() override;
|
||||
void uncustomizeContext() override;
|
||||
void updateFrameData() override;
|
||||
void cycleDebugOutput() override;
|
||||
|
||||
private:
|
||||
static const QString NAME;
|
||||
|
|
|
@ -9,7 +9,10 @@
|
|||
#include "OculusHelpers.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <QtCore/QLoggingCategory>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QDir>
|
||||
|
||||
using Mutex = std::mutex;
|
||||
using Lock = std::unique_lock<Mutex>;
|
||||
|
@ -38,9 +41,23 @@ void logFatal(const char* what) {
|
|||
qFatal(error.c_str());
|
||||
}
|
||||
|
||||
static const QString OCULUS_RUNTIME_PATH { "C:\\Program Files (x86)\\Oculus\\Support\\oculus-runtime" };
|
||||
static const QString GOOD_OCULUS_RUNTIME_FILE { OCULUS_RUNTIME_PATH + "\\LibOVRRT64_1.dll" };
|
||||
|
||||
bool oculusAvailable() {
|
||||
ovrDetectResult detect = ovr_Detect(0);
|
||||
return (detect.IsOculusServiceRunning && detect.IsOculusHMDConnected);
|
||||
if (!detect.IsOculusServiceRunning || !detect.IsOculusHMDConnected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// HACK Explicitly check for the presence of the 1.0 runtime DLL, and fail if it
|
||||
// doesn't exist
|
||||
if (!QFile(GOOD_OCULUS_RUNTIME_FILE).exists()) {
|
||||
qCWarning(oculus) << "Oculus Runtime detected, but no 1.x DLL present: \"" + GOOD_OCULUS_RUNTIME_FILE + "\"";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ovrSession acquireOculusSession() {
|
||||
|
@ -98,9 +115,9 @@ SwapFramebufferWrapper::~SwapFramebufferWrapper() {
|
|||
destroyColor();
|
||||
}
|
||||
|
||||
void SwapFramebufferWrapper::Increment() {
|
||||
++color->CurrentIndex;
|
||||
color->CurrentIndex %= color->TextureCount;
|
||||
void SwapFramebufferWrapper::Commit() {
|
||||
auto result = ovr_CommitTextureSwapChain(_session, color);
|
||||
Q_ASSERT(OVR_SUCCESS(result));
|
||||
}
|
||||
|
||||
void SwapFramebufferWrapper::Resize(const uvec2 & size) {
|
||||
|
@ -114,7 +131,7 @@ void SwapFramebufferWrapper::Resize(const uvec2 & size) {
|
|||
|
||||
void SwapFramebufferWrapper::destroyColor() {
|
||||
if (color) {
|
||||
ovr_DestroySwapTextureSet(_session, color);
|
||||
ovr_DestroyTextureSwapChain(_session, color);
|
||||
color = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -122,13 +139,30 @@ void SwapFramebufferWrapper::destroyColor() {
|
|||
void SwapFramebufferWrapper::initColor() {
|
||||
destroyColor();
|
||||
|
||||
if (!OVR_SUCCESS(ovr_CreateSwapTextureSetGL(_session, GL_SRGB8_ALPHA8, size.x, size.y, &color))) {
|
||||
ovrTextureSwapChainDesc desc = {};
|
||||
desc.Type = ovrTexture_2D;
|
||||
desc.ArraySize = 1;
|
||||
desc.Width = size.x;
|
||||
desc.Height = size.y;
|
||||
desc.MipLevels = 1;
|
||||
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
|
||||
desc.SampleCount = 1;
|
||||
desc.StaticImage = ovrFalse;
|
||||
|
||||
ovrResult result = ovr_CreateTextureSwapChainGL(_session, &desc, &color);
|
||||
if (!OVR_SUCCESS(result)) {
|
||||
logFatal("Failed to create swap textures");
|
||||
}
|
||||
|
||||
for (int i = 0; i < color->TextureCount; ++i) {
|
||||
ovrGLTexture& ovrTex = (ovrGLTexture&)color->Textures[i];
|
||||
glBindTexture(GL_TEXTURE_2D, ovrTex.OGL.TexId);
|
||||
int length = 0;
|
||||
result = ovr_GetTextureSwapChainLength(_session, color, &length);
|
||||
if (!OVR_SUCCESS(result) || !length) {
|
||||
qFatal("Unable to count swap chain textures");
|
||||
}
|
||||
for (int i = 0; i < length; ++i) {
|
||||
GLuint chainTexId;
|
||||
ovr_GetTextureSwapChainBufferGL(_session, color, i, &chainTexId);
|
||||
glBindTexture(GL_TEXTURE_2D, chainTexId);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
|
@ -141,8 +175,11 @@ void SwapFramebufferWrapper::initDone() {
|
|||
}
|
||||
|
||||
void SwapFramebufferWrapper::onBind(oglplus::Framebuffer::Target target) {
|
||||
ovrGLTexture& tex = (ovrGLTexture&)(color->Textures[color->CurrentIndex]);
|
||||
glFramebufferTexture2D(toEnum(target), GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.OGL.TexId, 0);
|
||||
int curIndex;
|
||||
ovr_GetTextureSwapChainCurrentIndex(_session, color, &curIndex);
|
||||
GLuint curTexId;
|
||||
ovr_GetTextureSwapChainBufferGL(_session, color, curIndex, &curTexId);
|
||||
glFramebufferTexture2D(toEnum(target), GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, curTexId, 0);
|
||||
}
|
||||
|
||||
void SwapFramebufferWrapper::onUnbind(oglplus::Framebuffer::Target target) {
|
||||
|
|
|
@ -111,10 +111,10 @@ inline ovrPosef ovrPoseFromGlm(const glm::mat4 & m) {
|
|||
// then submit it and increment to the next texture.
|
||||
// The Oculus SDK manages the creation and destruction of
|
||||
// the textures
|
||||
struct SwapFramebufferWrapper : public FramebufferWrapper<ovrSwapTextureSet*, void*> {
|
||||
struct SwapFramebufferWrapper : public FramebufferWrapper<ovrTextureSwapChain, void*> {
|
||||
SwapFramebufferWrapper(const ovrSession& session);
|
||||
~SwapFramebufferWrapper();
|
||||
void Increment();
|
||||
void Commit();
|
||||
void Resize(const uvec2 & size);
|
||||
protected:
|
||||
void initColor() override final;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "OculusDisplayPlugin.h"
|
||||
#include "OculusDebugDisplayPlugin.h"
|
||||
#include "OculusControllerManager.h"
|
||||
|
||||
class OculusProvider : public QObject, public DisplayProvider, InputProvider
|
||||
{
|
||||
|
@ -51,8 +52,6 @@ public:
|
|||
}
|
||||
|
||||
virtual InputPluginList getInputPlugins() override {
|
||||
// FIXME pending full oculus input API and hardware
|
||||
#if 0
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
InputPluginPointer plugin(new OculusControllerManager());
|
||||
|
@ -60,7 +59,6 @@ public:
|
|||
_inputPlugins.push_back(plugin);
|
||||
}
|
||||
});
|
||||
#endif
|
||||
return _inputPlugins;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,10 +35,14 @@ void OculusLegacyDisplayPlugin::resetSensors() {
|
|||
ovrHmd_RecenterPose(_hmd);
|
||||
}
|
||||
|
||||
void OculusLegacyDisplayPlugin::updateHeadPose(uint32_t frameIndex) {
|
||||
void OculusLegacyDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
|
||||
FrameInfo frame;
|
||||
frame.predictedDisplayTime = frame.sensorSampleTime = ovr_GetTimeInSeconds();
|
||||
_trackingState = ovrHmd_GetTrackingState(_hmd, frame.predictedDisplayTime);
|
||||
frame.headPose = toGlm(_trackingState.HeadPose.ThePose);
|
||||
_currentRenderFrameInfo.set(frame);
|
||||
Lock lock(_mutex);
|
||||
_trackingState = ovrHmd_GetTrackingState(_hmd, ovr_GetTimeInSeconds());
|
||||
_headPoseCache.set(toGlm(_trackingState.HeadPose.ThePose));
|
||||
_frameInfos[frameIndex] = frame;
|
||||
}
|
||||
|
||||
bool OculusLegacyDisplayPlugin::isSupported() const {
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
|
||||
// Stereo specific methods
|
||||
virtual void resetSensors() override;
|
||||
virtual void updateHeadPose(uint32_t frameIndex) override;
|
||||
virtual void beginFrameRender(uint32_t frameIndex) override;
|
||||
|
||||
virtual float getTargetFrameRate() override;
|
||||
|
||||
|
|
|
@ -121,22 +121,23 @@ void OpenVrDisplayPlugin::resetSensors() {
|
|||
_sensorResetMat = glm::inverse(cancelOutRollAndPitch(m));
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::updateHeadPose(uint32_t frameIndex) {
|
||||
void OpenVrDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
|
||||
|
||||
float displayFrequency = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_DisplayFrequency_Float);
|
||||
float frameDuration = 1.f / displayFrequency;
|
||||
float vsyncToPhotons = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SecondsFromVsyncToPhotons_Float);
|
||||
double displayFrequency = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_DisplayFrequency_Float);
|
||||
double frameDuration = 1.f / displayFrequency;
|
||||
double vsyncToPhotons = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SecondsFromVsyncToPhotons_Float);
|
||||
|
||||
FrameInfo frame;
|
||||
#if THREADED_PRESENT
|
||||
// 3 frames of prediction + vsyncToPhotons = 44ms total
|
||||
const float NUM_PREDICTION_FRAMES = 3.0f;
|
||||
float predictedSecondsFromNow = NUM_PREDICTION_FRAMES * frameDuration + vsyncToPhotons;
|
||||
const double NUM_PREDICTION_FRAMES = 3.0f;
|
||||
frame.predictedDisplayTime = NUM_PREDICTION_FRAMES * frameDuration + vsyncToPhotons;
|
||||
#else
|
||||
float predictedSecondsFromNow = frameDuration + vsyncToPhotons;
|
||||
frame.predictedDisplayTime = frameDuration + vsyncToPhotons;
|
||||
#endif
|
||||
|
||||
vr::TrackedDevicePose_t predictedTrackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
||||
_system->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, predictedSecondsFromNow, predictedTrackedDevicePose, vr::k_unMaxTrackedDeviceCount);
|
||||
_system->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, frame.predictedDisplayTime, predictedTrackedDevicePose, vr::k_unMaxTrackedDeviceCount);
|
||||
|
||||
// copy and process predictedTrackedDevicePoses
|
||||
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
||||
|
@ -145,8 +146,11 @@ void OpenVrDisplayPlugin::updateHeadPose(uint32_t frameIndex) {
|
|||
_trackedDeviceLinearVelocities[i] = transformVectorFast(_sensorResetMat, toGlm(_trackedDevicePose[i].vVelocity));
|
||||
_trackedDeviceAngularVelocities[i] = transformVectorFast(_sensorResetMat, toGlm(_trackedDevicePose[i].vAngularVelocity));
|
||||
}
|
||||
frame.headPose = _trackedDevicePoseMat4[0];
|
||||
_currentRenderFrameInfo.set(frame);
|
||||
|
||||
_headPoseCache.set(_trackedDevicePoseMat4[0]);
|
||||
Lock lock(_mutex);
|
||||
_frameInfos[frameIndex] = frame;
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::hmdPresent() {
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
|
||||
// Stereo specific methods
|
||||
virtual void resetSensors() override;
|
||||
virtual void updateHeadPose(uint32_t frameIndex) override;
|
||||
virtual void beginFrameRender(uint32_t frameIndex) override;
|
||||
|
||||
protected:
|
||||
bool internalActivate() override;
|
||||
|
|
1
server-console/.gitignore
vendored
1
server-console/.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
Server\ Console-*/
|
||||
server-console-*/
|
||||
Sandbox-*/
|
||||
electron-packager/
|
||||
npm-debug.log
|
||||
logs/
|
||||
|
|
|
@ -23,7 +23,7 @@ add_dependencies(${TARGET_NAME} assignment-client domain-server)
|
|||
|
||||
# set the packaged console folder depending on platform, so we can copy it
|
||||
if (APPLE)
|
||||
set(PACKAGED_CONSOLE_FOLDER "Server\\ Console-darwin-x64/${CONSOLE_EXEC_NAME}")
|
||||
set(PACKAGED_CONSOLE_FOLDER "Sandbox-darwin-x64/${CONSOLE_EXEC_NAME}")
|
||||
elseif (WIN32)
|
||||
set(PACKAGED_CONSOLE_FOLDER "server-console-win32-x64")
|
||||
elseif (UNIX)
|
||||
|
|
|
@ -23,12 +23,12 @@ var options = {
|
|||
arch: "x64",
|
||||
platform: platform,
|
||||
icon: "resources/" + iconName,
|
||||
ignore: "logs|(S|s)erver(\\s|-)(C|c)onsole-\\S+|electron-packager|README.md|CMakeLists.txt|packager.js|.gitignore"
|
||||
ignore: "logs|(S|s)erver(\\s|-)(C|c)onsole-\\S+|(S|s)andbox-\\S+|electron-packager|README.md|CMakeLists.txt|packager.js|.gitignore"
|
||||
}
|
||||
|
||||
const EXEC_NAME = "server-console";
|
||||
const SHORT_NAME = "Server Console";
|
||||
const FULL_NAME = "High Fidelity Server Console";
|
||||
const SHORT_NAME = "Sandbox";
|
||||
const FULL_NAME = "High Fidelity Sandbox";
|
||||
|
||||
// setup per OS options
|
||||
if (osType == "Darwin") {
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
@ -111,8 +111,8 @@ function shutdown() {
|
|||
dialog.showMessageBox({
|
||||
type: 'question',
|
||||
buttons: ['Yes', 'No'],
|
||||
title: 'Stopping Server Console',
|
||||
message: 'Quitting will stop your Server Console and your Home domain will no longer be running.\nDo you wish to continue?'
|
||||
title: 'Stopping High Fidelity Sandbox',
|
||||
message: 'Quitting will stop your Sandbox and your Home domain will no longer be running.\nDo you wish to continue?'
|
||||
}, shutdownCallback);
|
||||
} else {
|
||||
shutdownCallback(0);
|
||||
|
@ -212,7 +212,7 @@ var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory)
|
|||
});
|
||||
|
||||
if (shouldQuit) {
|
||||
console.warn("Another instance of the Server Console is already running - this instance will quit.");
|
||||
console.warn("Another instance of the Sandbox is already running - this instance will quit.");
|
||||
app.quit();
|
||||
return;
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ function binaryMissingMessage(displayName, executableName, required) {
|
|||
var message = "The " + displayName + " executable was not found.\n";
|
||||
|
||||
if (required) {
|
||||
message += "It is required for the Server Console to run.\n\n";
|
||||
message += "It is required for the High Fidelity Sandbox to run.\n\n";
|
||||
} else {
|
||||
message += "\n";
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ function binaryMissingMessage(displayName, executableName, required) {
|
|||
message += paths.join("\n");
|
||||
} else {
|
||||
message += "It is expected to be found beside this executable.\n";
|
||||
message += "You may need to re-install the Server Console.";
|
||||
message += "You may need to re-install the High Fidelity Sandbox.";
|
||||
}
|
||||
|
||||
return message;
|
||||
|
@ -347,134 +347,6 @@ function goHomeClicked() {
|
|||
}
|
||||
}
|
||||
|
||||
function stackManagerBasePath() {
|
||||
var dataPath = 'High Fidelity/Stack Manager/resources';
|
||||
|
||||
if (process.platform == "win32") {
|
||||
return path.resolve(osHomeDir(), 'AppData/Local', dataPath);
|
||||
} else if (process.platform == "darwin") {
|
||||
return path.resolve(osHomeDir(), 'Library/Application Support', dataPath);
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
function isStackManagerContentPresent() {
|
||||
var modelsPath = path.resolve(stackManagerBasePath(), 'models.json.gz');
|
||||
|
||||
try {
|
||||
var stats = fs.lstatSync(modelsPath);
|
||||
|
||||
if (stats.isFile()) {
|
||||
console.log("Stack Manager entities file discovered at " + modelsPath)
|
||||
// we found a content file
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Stack Manager entities file not found at " + modelsPath);
|
||||
}
|
||||
}
|
||||
|
||||
function promptToMigrateContent() {
|
||||
dialog.showMessageBox({
|
||||
type: 'question',
|
||||
buttons: ['Yes', 'No'],
|
||||
title: 'Migrate Content',
|
||||
message: 'Are you sure?\n\nThis will stop your home server and replace everything in your home with your content from Stack Manager.'
|
||||
}, function(index) {
|
||||
if (index == 0) {
|
||||
if (homeServer.state != ProcessGroupStates.STOPPED) {
|
||||
var stopThenMigrateCallback = function(processGroup) {
|
||||
if (isShuttingDown) {
|
||||
homeServer.removeListener('state-update', stopThenMigrateCallback);
|
||||
} else if (processGroup.state == ProcessGroupStates.STOPPED) {
|
||||
performContentMigration();
|
||||
|
||||
homeServer.removeListener('state-update', stopThenMigrateCallback);
|
||||
}
|
||||
};
|
||||
|
||||
homeServer.on('state-update', stopThenMigrateCallback);
|
||||
homeServer.stop();
|
||||
|
||||
} else {
|
||||
performContentMigration();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function performContentMigration() {
|
||||
// check if there is a models file to migrate
|
||||
var modelsPath = path.resolve(stackManagerBasePath(), 'models.json.gz');
|
||||
|
||||
try {
|
||||
var stats = fs.lstatSync(modelsPath);
|
||||
} catch (e) {
|
||||
// no entities file
|
||||
dialog.showMessageBox({
|
||||
type: 'info',
|
||||
buttons: ['OK'],
|
||||
title: 'Models File Not Found',
|
||||
message: 'There is no models file at ' + modelsPath + '\n\nStack Manager content migration can not proceed.'
|
||||
}, null);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
function showMigrationCompletionDialog(copyError) {
|
||||
if (!copyError) {
|
||||
// show message for successful migration
|
||||
dialog.showMessageBox({
|
||||
type: 'info',
|
||||
buttons: ['OK'],
|
||||
title: 'Migration Complete',
|
||||
message: 'Your Stack Manager content has been migrated.\n\nYour home server will now be restarted.'
|
||||
}, null);
|
||||
} else {
|
||||
// show error message for copy fail
|
||||
dialog.showMessageBox({
|
||||
type: 'info',
|
||||
buttons: ['OK'],
|
||||
title: 'Migration Failed',
|
||||
message: 'There was an error copying your Stack Manager content: ' + copyError + '\n\nPlease try again.'
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
|
||||
// we have a models file, try and copy it
|
||||
var newModelsPath = path.resolve(getAssignmentClientResourcesDirectory(), 'entities/models.json.gz')
|
||||
console.log("Copying Stack Manager entity file from " + modelsPath + " to " + newModelsPath);
|
||||
|
||||
try {
|
||||
fs.copySync(modelsPath, newModelsPath);
|
||||
|
||||
// check if there are any assets to copy
|
||||
var oldAssetsPath = path.resolve(stackManagerBasePath(), 'assets');
|
||||
|
||||
var assets = fs.readdirSync(oldAssetsPath);
|
||||
|
||||
if (assets.length > 0) {
|
||||
// assume this means the directory is not empty
|
||||
// and that we should copy it
|
||||
var newAssetsPath = path.resolve(getAssignmentClientResourcesDirectory(), 'assets');
|
||||
|
||||
console.log("Copying Stack Manager assets from " + oldAssetsPath + " to " + newAssetsPath);
|
||||
|
||||
// attempt to copy the assets folder
|
||||
fs.copySync(oldAssetsPath, newAssetsPath, {
|
||||
preserveTimestamps: true
|
||||
});
|
||||
}
|
||||
|
||||
showMigrationCompletionDialog(null);
|
||||
} catch (error) {
|
||||
showMigrationCompletionDialog(error);
|
||||
}
|
||||
|
||||
homeServer.start();
|
||||
}
|
||||
|
||||
var logWindow = null;
|
||||
|
||||
var labels = {
|
||||
|
@ -530,12 +402,6 @@ var labels = {
|
|||
shell.openExternal('http://localhost:40100/settings/?action=share')
|
||||
}
|
||||
},
|
||||
migrateContent: {
|
||||
label: 'Migrate Stack Manager Content',
|
||||
click: function() {
|
||||
promptToMigrateContent();
|
||||
}
|
||||
},
|
||||
shuttingDown: {
|
||||
label: "Shutting down...",
|
||||
enabled: false
|
||||
|
@ -569,13 +435,6 @@ function buildMenuArray(serverState) {
|
|||
menuArray.push(labels.share);
|
||||
menuArray.push(separator);
|
||||
menuArray.push(labels.quit);
|
||||
|
||||
var foundStackManagerContent = isStackManagerContentPresent();
|
||||
if (foundStackManagerContent) {
|
||||
// add a separator and the stack manager content migration option
|
||||
menuArray.splice(menuArray.length - 1, 0, labels.migrateContent, separator);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -724,7 +583,7 @@ function maybeShowSplash() {
|
|||
var window = new BrowserWindow({
|
||||
icon: appIcon,
|
||||
width: 1600 * zoomFactor,
|
||||
height: 737 * zoomFactor,
|
||||
height: 650 * zoomFactor,
|
||||
center: true,
|
||||
frame: true,
|
||||
useContentSize: true,
|
||||
|
@ -770,7 +629,7 @@ app.on('ready', function() {
|
|||
|
||||
// Create tray icon
|
||||
tray = new Tray(trayIcons[ProcessGroupStates.STOPPED]);
|
||||
tray.setToolTip('High Fidelity Server Console');
|
||||
tray.setToolTip('High Fidelity Sandbox');
|
||||
|
||||
tray.on('click', function() {
|
||||
tray.popUpContextMenu(tray.menu);
|
||||
|
|
|
@ -122,11 +122,6 @@ h2 {
|
|||
|
||||
#main-content {
|
||||
height: 350px;
|
||||
border-bottom: 2px solid #F5F6F6;
|
||||
}
|
||||
|
||||
#existing-resources-area {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
|
@ -143,4 +138,4 @@ h2 {
|
|||
input[type="checkbox"] {
|
||||
-webkit-transform: scale(1.4);
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ High Fidelity is now installed and your Home domain is ready for you to explore.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
You can make your home yours by uploading your own models and scripts, and adding items from the Market.
|
||||
You can make your home yours by uploading your own models and scripts.
|
||||
|
||||
</p>
|
||||
|
||||
|
@ -67,12 +67,6 @@ You can make your home yours by uploading your own models and scripts, and addin
|
|||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<div id="existing-resources-area">
|
||||
<p>
|
||||
<h2>Your existing Stack Manager content is safe.</h2>
|
||||
Server Console comes with demo content but does not overwrite your data. <a target="_blank" href="https://docs.highfidelity.com/v1.0/docs/migrate-sm-to-sc">See our guide to importing content previously managed with Stack Manager</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div class="content footer">
|
||||
|
|
|
@ -795,3 +795,35 @@ void OctreeTests::modelItemTests() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void OctreeTests::elementAddChildTests() {
|
||||
EntityTreePointer tree = std::make_shared<EntityTree>();
|
||||
auto elem = tree->createNewElement();
|
||||
QCOMPARE((bool)elem->getChildAtIndex(0), false);
|
||||
elem->addChildAtIndex(0);
|
||||
QCOMPARE((bool)elem->getChildAtIndex(0), true);
|
||||
|
||||
const int MAX_CHILD_INDEX = 8;
|
||||
for (int i = 0; i < MAX_CHILD_INDEX; i++) {
|
||||
for (int j = 0; j < MAX_CHILD_INDEX; j++) {
|
||||
auto e = tree->createNewElement();
|
||||
|
||||
// add a single child.
|
||||
auto firstChild = e->addChildAtIndex(i);
|
||||
QCOMPARE(e->getChildAtIndex(i), firstChild);
|
||||
|
||||
if (i != j) {
|
||||
// add a second child.
|
||||
auto secondChild = e->addChildAtIndex(j);
|
||||
QCOMPARE(e->getChildAtIndex(i), firstChild);
|
||||
QCOMPARE(e->getChildAtIndex(j), secondChild);
|
||||
|
||||
// remove scecond child.
|
||||
e->removeChildAtIndex(j);
|
||||
|
||||
QCOMPARE((bool)e->getChildAtIndex(j), false);
|
||||
}
|
||||
|
||||
QCOMPARE(e->getChildAtIndex(i), firstChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ private slots:
|
|||
// This test is fine
|
||||
void modelItemTests();
|
||||
|
||||
void elementAddChildTests();
|
||||
|
||||
// TODO: Break these into separate test functions
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue