Merge branch 'master' of https://github.com/highfidelity/hifi into optimizeFindZones

This commit is contained in:
Brad Hefta-Gaub 2016-03-30 19:29:28 -07:00
commit b76f8509aa
39 changed files with 608 additions and 298 deletions

View file

@ -12,19 +12,16 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
# 0.5 public # 0.5 public
# URL http://static.oculus.com/sdk-downloads/ovr_sdk_win_0.5.0.1.zip # URL http://static.oculus.com/sdk-downloads/ovr_sdk_win_0.5.0.1.zip
# URL_MD5 d3fc4c02db9be5ff08af4ef4c97b32f9 # URL_MD5 d3fc4c02db9be5ff08af4ef4c97b32f9
# 0.6 public # 1.3 public
# URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip # URL http://hifi-public.s3.amazonaws.com/dependencies/ovr_sdk_win_1.3.0_public.zip
# URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9 # URL_MD5 4d26faba0c1f35ff80bf674c96ed9259
# 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
if (WIN32) if (WIN32)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://static.oculus.com/sdk-downloads/0.8.0.0/Public/1445451746/ovr_sdk_win_0.8.0.0.zip URL http://hifi-public.s3.amazonaws.com/dependencies/ovr_sdk_win_1.3.0_public.zip
URL_MD5 54944b03b95149d6010f84eb701b9647 URL_MD5 a2dcf695e0f03a70fdd1ed7480585e82
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""
INSTALL_COMMAND "" INSTALL_COMMAND ""
@ -33,14 +30,16 @@ if (WIN32)
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
# FIXME need to account for different architectures set(LIBOVR_DIR ${SOURCE_DIR}/OculusSDK/LibOVR)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/LibOVR/Include CACHE TYPE INTERNAL)
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") 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() 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() 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) elseif(APPLE)
ExternalProject_Add( ExternalProject_Add(

View file

@ -85,8 +85,8 @@ macro(GENERATE_INSTALLERS)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
cpack_add_component(${CLIENT_COMPONENT} DISPLAY_NAME "High Fidelity Client") cpack_add_component(${CLIENT_COMPONENT} DISPLAY_NAME "High Fidelity Interface")
cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "High Fidelity Server") cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "High Fidelity Sandbox")
include(CPack) include(CPack)
endmacro() endmacro()

View file

@ -53,7 +53,7 @@ macro(SET_PACKAGING_PARAMETERS)
set(CONSOLE_INSTALL_DIR ${DMG_SUBFOLDER_NAME}) set(CONSOLE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
set(INTERFACE_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_INSTALL_APP_PATH "${CONSOLE_INSTALL_DIR}/${CONSOLE_EXEC_NAME}")
set(CONSOLE_APP_CONTENTS "${CONSOLE_INSTALL_APP_PATH}/Contents") set(CONSOLE_APP_CONTENTS "${CONSOLE_INSTALL_APP_PATH}/Contents")
@ -84,12 +84,19 @@ macro(SET_PACKAGING_PARAMETERS)
# shortcut names # shortcut names
if (PRODUCTION_BUILD) if (PRODUCTION_BUILD)
set(INTERFACE_SHORTCUT_NAME "High Fidelity") set(INTERFACE_SHORTCUT_NAME "Interface")
set(CONSOLE_SHORTCUT_NAME "Server Console") set(CONSOLE_SHORTCUT_NAME "Sandbox")
else () else ()
set(INTERFACE_SHORTCUT_NAME "High Fidelity - ${BUILD_VERSION}") set(INTERFACE_SHORTCUT_NAME "Interface - ${BUILD_VERSION}")
set(CONSOLE_SHORTCUT_NAME "Server Console - ${BUILD_VERSION}") set(CONSOLE_SHORTCUT_NAME "Sandbox - ${BUILD_VERSION}")
endif () 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 # check if we need to find signtool
if (PRODUCTION_BUILD OR PR_BUILD) if (PRODUCTION_BUILD OR PR_BUILD)
find_program(SIGNTOOL_EXECUTABLE signtool PATHS "C:/Program Files (x86)/Windows Kits/8.1" PATH_SUFFIXES "bin/x64") find_program(SIGNTOOL_EXECUTABLE signtool PATHS "C:/Program Files (x86)/Windows Kits/8.1" PATH_SUFFIXES "bin/x64")

View file

@ -10,10 +10,14 @@
# #
set(INTERFACE_SHORTCUT_NAME "@INTERFACE_SHORTCUT_NAME@") 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(INTERFACE_WIN_EXEC_NAME "@INTERFACE_EXEC_PREFIX@.exe")
set(CONSOLE_INSTALL_SUBDIR "@CONSOLE_INSTALL_DIR@") set(CONSOLE_INSTALL_SUBDIR "@CONSOLE_INSTALL_DIR@")
set(CONSOLE_SHORTCUT_NAME "@CONSOLE_SHORTCUT_NAME@") 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(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(DS_EXEC_NAME "@DS_EXEC_NAME@")
set(AC_EXEC_NAME "@AC_EXEC_NAME@") set(AC_EXEC_NAME "@AC_EXEC_NAME@")
set(HIGH_FIDELITY_PROTOCOL "@HIGH_FIDELITY_PROTOCOL@") set(HIGH_FIDELITY_PROTOCOL "@HIGH_FIDELITY_PROTOCOL@")

View file

@ -387,7 +387,7 @@ Function PostInstallOptionsPage
StrCpy $OffsetUnits u StrCpy $OffsetUnits u
${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} ${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 Pop $DesktopClientCheckbox
IntOp $CurrentOffset $CurrentOffset + 15 IntOp $CurrentOffset $CurrentOffset + 15
@ -396,7 +396,7 @@ Function PostInstallOptionsPage
${EndIf} ${EndIf}
${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} ${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 Pop $DesktopServerCheckbox
; set the checkbox state depending on what is present in the registry ; set the checkbox state depending on what is present in the registry
@ -404,7 +404,7 @@ Function PostInstallOptionsPage
IntOp $CurrentOffset $CurrentOffset + 15 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 Pop $ServerStartupCheckbox
; set the checkbox state depending on what is present in the registry ; set the checkbox state depending on what is present in the registry
@ -414,9 +414,9 @@ Function PostInstallOptionsPage
${EndIf} ${EndIf}
${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} ${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} ${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} ${EndIf}
Pop $LaunchNowCheckbox Pop $LaunchNowCheckbox
@ -465,10 +465,10 @@ Function ReadPostInstallOptions
${EndIf} ${EndIf}
${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} ${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 ${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 ${NSD_GetState} $ServerStartupCheckbox $ServerStartupState
${EndIf} ${EndIf}
@ -485,7 +485,7 @@ Function HandlePostInstallOptions
${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@}
; check if the user asked for a desktop shortcut to High Fidelity ; check if the user asked for a desktop shortcut to High Fidelity
${If} $DesktopClientState == ${BST_CHECKED} ${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 !insertmacro WritePostInstallOption "@CLIENT_DESKTOP_SHORTCUT_REG_KEY@" YES
${Else} ${Else}
!insertmacro WritePostInstallOption @CLIENT_DESKTOP_SHORTCUT_REG_KEY@ NO !insertmacro WritePostInstallOption @CLIENT_DESKTOP_SHORTCUT_REG_KEY@ NO
@ -494,23 +494,23 @@ Function HandlePostInstallOptions
${EndIf} ${EndIf}
${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} ${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} ${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 !insertmacro WritePostInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ YES
${Else} ${Else}
!insertmacro WritePostInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ NO !insertmacro WritePostInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ NO
${EndIf} ${EndIf}
; check if the user asked to have Server Console launched every startup ; check if the user asked to have Sandbox launched every startup
${If} $ServerStartupState == ${BST_CHECKED} ${If} $ServerStartupState == ${BST_CHECKED}
; in case we added a shortcut in the global context, pull that now ; in case we added a shortcut in the global context, pull that now
SetShellVarContext all 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 ; make a startup shortcut in this user's current context
SetShellVarContext current 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 ; reset the shell var context back
SetShellVarContext all SetShellVarContext all
@ -589,6 +589,19 @@ Section "-Core installation"
Delete "$INSTDIR\version" Delete "$INSTDIR\version"
Delete "$INSTDIR\xinput1_3.dll" 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 the incorrectly cased Raleway font
Rename "$INSTDIR\resources\qml\styles-uit\RalewaySemibold.qml" "$INSTDIR\resources\qml\styles-uit\RalewaySemiBold.qml" Rename "$INSTDIR\resources\qml\styles-uit\RalewaySemibold.qml" "$INSTDIR\resources\qml\styles-uit\RalewaySemiBold.qml"
@ -724,8 +737,8 @@ SectionEnd
!macroend !macroend
!macro CheckForRunningApplications action prompter !macro CheckForRunningApplications action prompter
!insertmacro PromptForRunningApplication "@INTERFACE_WIN_EXEC_NAME@" "High Fidelity client" ${action} ${prompter} !insertmacro PromptForRunningApplication "@INTERFACE_WIN_EXEC_NAME@" "@CONSOLE_SHORTCUT_NAME@" ${action} ${prompter}
!insertmacro PromptForRunningApplication "@CONSOLE_WIN_EXEC_NAME@" "Server Console" ${action} ${prompter} !insertmacro PromptForRunningApplication "@CONSOLE_WIN_EXEC_NAME@" "@INTERFACE_SHORTCUT_NAME@" ${action} ${prompter}
!insertmacro PromptForRunningApplication "@DS_EXEC_NAME@" "Domain Server" ${action} ${prompter} !insertmacro PromptForRunningApplication "@DS_EXEC_NAME@" "Domain Server" ${action} ${prompter}
!insertmacro PromptForRunningApplication "@AC_EXEC_NAME@" "Assignment Client" ${action} ${prompter} !insertmacro PromptForRunningApplication "@AC_EXEC_NAME@" "Assignment Client" ${action} ${prompter}
!macroend !macroend
@ -869,12 +882,12 @@ Section "Uninstall"
Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\@INTERFACE_SHORTCUT_NAME@.lnk" Delete "$SMPROGRAMS\$MUI_TEMP\@INTERFACE_SHORTCUT_NAME@.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\@CONSOLE_SHORTCUT_NAME@.lnk" Delete "$SMPROGRAMS\$MUI_TEMP\@CONSOLE_SHORTCUT_NAME@.lnk"
Delete "$DESKTOP\@INTERFACE_SHORTCUT_NAME@.lnk" Delete "$DESKTOP\@INTERFACE_HF_SHORTCUT_NAME@.lnk"
Delete "$DESKTOP\@CONSOLE_SHORTCUT_NAME@.lnk" Delete "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk"
; if it exists, delete the startup shortcut for the current user ; if it exists, delete the startup shortcut for the current user
SetShellVarContext current SetShellVarContext current
Delete "$SMSTARTUP\@CONSOLE_SHORTCUT_NAME@.lnk" Delete "$SMSTARTUP\@CONSOLE_HF_SHORTCUT_NAME@.lnk"
SetShellVarContext all SetShellVarContext all
@CPACK_NSIS_DELETE_ICONS@ @CPACK_NSIS_DELETE_ICONS@

View file

@ -19,6 +19,7 @@
#include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkRequest>
#include <LimitedNodeList.h> #include <LimitedNodeList.h>
#include <NetworkAccessManager.h>
#include <NetworkingConstants.h> #include <NetworkingConstants.h>
#include <udt/PacketHeaders.h> #include <udt/PacketHeaders.h>
#include <SharedUtil.h> #include <SharedUtil.h>
@ -33,7 +34,8 @@ IceServer::IceServer(int argc, char* argv[]) :
_id(QUuid::createUuid()), _id(QUuid::createUuid()),
_serverSocket(), _serverSocket(),
_activePeers(), _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 // start the ice-server socket
qDebug() << "ice-server socket is listening on" << ICE_SERVER_DEFAULT_PORT; 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) { void IceServer::processPacket(std::unique_ptr<udt::Packet> packet) {
_lastPacketTimestamp = QDateTime::currentMSecsSinceEpoch();
auto nlPacket = NLPacket::fromBase(std::move(packet)); auto nlPacket = NLPacket::fromBase(std::move(packet));
// make sure that this packet at least looks like something we can read // 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) { void IceServer::requestDomainPublicKey(const QUuid& domainID) {
// send a request to the metaverse API for the public key for this domain // send a request to the metaverse API for the public key for this domain
QNetworkAccessManager* manager = new QNetworkAccessManager { this }; auto& networkAccessManager = NetworkAccessManager::getInstance();
connect(manager, &QNetworkAccessManager::finished, this, &IceServer::publicKeyReplyFinished); connect(&networkAccessManager, &QNetworkAccessManager::finished, this, &IceServer::publicKeyReplyFinished);
QUrl publicKeyURL { NetworkingConstants::METAVERSE_SERVER_URL }; QUrl publicKeyURL { NetworkingConstants::METAVERSE_SERVER_URL };
QString publicKeyPath = QString("/api/v1/domains/%1/public_key").arg(uuidStringWithoutCurlyBraces(domainID)); 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; qDebug() << "Requesting public key for domain with ID" << domainID;
manager->get(publicKeyRequest); networkAccessManager.get(publicKeyRequest);
} }
void IceServer::publicKeyReplyFinished(QNetworkReply* reply) { void IceServer::publicKeyReplyFinished(QNetworkReply* reply) {
@ -281,6 +281,8 @@ void IceServer::sendPeerInformationPacket(const NetworkPeer& peer, const HifiSoc
void IceServer::clearInactivePeers() { void IceServer::clearInactivePeers() {
NetworkPeerHash::iterator peerItem = _activePeers.begin(); NetworkPeerHash::iterator peerItem = _activePeers.begin();
_lastInactiveCheckTimestamp = QDateTime::currentMSecsSinceEpoch();
while (peerItem != _activePeers.end()) { while (peerItem != _activePeers.end()) {
SharedNetworkPeer peer = peerItem.value(); 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; const quint64 MAX_PACKET_GAP_MS_FOR_STUCK_SOCKET = 10 * 1000;
int statusNumber = (QDateTime::currentMSecsSinceEpoch() - _lastPacketTimestamp > MAX_PACKET_GAP_MS_FOR_STUCK_SOCKET) auto sinceLastInactiveCheck = QDateTime::currentMSecsSinceEpoch() - _lastInactiveCheckTimestamp;
? 1 : 0; int statusNumber = (sinceLastInactiveCheck > MAX_PACKET_GAP_MS_FOR_STUCK_SOCKET) ? 1 : 0;
connection->respond(HTTPConnection::StatusCode200, QByteArray::number(statusNumber)); connection->respond(HTTPConnection::StatusCode200, QByteArray::number(statusNumber));
return true;
} }
} }
return true;
return false;
} }

View file

@ -58,7 +58,7 @@ private:
using DomainPublicKeyHash = std::unordered_map<QUuid, RSAUniquePtr>; using DomainPublicKeyHash = std::unordered_map<QUuid, RSAUniquePtr>;
DomainPublicKeyHash _domainPublicKeys; DomainPublicKeyHash _domainPublicKeys;
quint64 _lastPacketTimestamp; quint64 _lastInactiveCheckTimestamp;
}; };
#endif // hifi_IceServer_h #endif // hifi_IceServer_h

View file

@ -1489,11 +1489,15 @@ void Application::paintGL() {
// FIXME not needed anymore? // FIXME not needed anymore?
_offscreenContext->makeCurrent(); _offscreenContext->makeCurrent();
displayPlugin->updateHeadPose(_frameCount); displayPlugin->beginFrameRender(_frameCount);
// update the avatar with a fresh HMD pose // update the avatar with a fresh HMD pose
getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose());
// update sensorToWorldMatrix for camera and hand controllers
getMyAvatar()->updateSensorToWorldMatrix();
auto lodManager = DependencyManager::get<LODManager>(); auto lodManager = DependencyManager::get<LODManager>();
@ -2006,6 +2010,12 @@ void Application::keyPressEvent(QKeyEvent* event) {
} }
break; break;
case Qt::Key_Y:
if (isShifted && isMeta) {
getActiveDisplayPlugin()->cycleDebugOutput();
}
break;
case Qt::Key_B: case Qt::Key_B:
if (isMeta) { if (isMeta) {
auto offscreenUi = DependencyManager::get<OffscreenUi>(); auto offscreenUi = DependencyManager::get<OffscreenUi>();
@ -2571,11 +2581,6 @@ void Application::idle(uint64_t now) {
return; // bail early, nothing to do here. 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 // 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 // overlay subwindows to do a showDesktop() until after the first time through
static bool firstIdle = true; 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 // We're going to execute idle processing, so restart the last idle timer
_lastTimeUpdated.start(); _lastTimeUpdated.start();
checkChangeCursor();
Stats::getInstance()->updateStats();
AvatarInputs::getInstance()->update();
{ {
static uint64_t lastIdleStart{ now }; static uint64_t lastIdleStart{ now };
uint64_t idleStartToStartDuration = now - lastIdleStart; uint64_t idleStartToStartDuration = now - lastIdleStart;
@ -3390,9 +3400,6 @@ void Application::update(float deltaTime) {
qApp->updateMyAvatarLookAtPosition(); qApp->updateMyAvatarLookAtPosition();
// update sensorToWorldMatrix for camera and hand controllers
myAvatar->updateSensorToWorldMatrix();
{ {
PROFILE_RANGE_EX("MyAvatar", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount()); PROFILE_RANGE_EX("MyAvatar", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
avatarManager->updateMyAvatar(deltaTime); avatarManager->updateMyAvatar(deltaTime);

View file

@ -81,6 +81,9 @@ namespace controller {
// Triggers // Triggers
LT, LT,
RT, RT,
// Grips (Oculus touch squeeze)
LG,
RG,
NUM_STANDARD_AXES, NUM_STANDARD_AXES,
LZ = LT, LZ = LT,
RZ = RT RZ = RT

View file

@ -552,9 +552,9 @@ float OpenGLDisplayPlugin::presentRate() {
{ {
Lock lock(_mutex); Lock lock(_mutex);
result = _usecsPerFrame.getAverage(); result = _usecsPerFrame.getAverage();
result = 1.0f / result;
result *= USECS_PER_SECOND;
} }
result = 1.0f / result;
result *= USECS_PER_SECOND;
return result; return result;
} }

View file

@ -17,9 +17,9 @@
#include <GLMHelpers.h> #include <GLMHelpers.h>
#include <SimpleMovingAverage.h> #include <SimpleMovingAverage.h>
#include <gl/OglplusHelpers.h> #include <gl/OglplusHelpers.h>
#include <gl/GLEscrow.h>
#define THREADED_PRESENT 1 #define THREADED_PRESENT 1
#include <gl/GLEscrow.h>
class OpenGLDisplayPlugin : public DisplayPlugin { class OpenGLDisplayPlugin : public DisplayPlugin {
protected: protected:

View file

@ -69,10 +69,11 @@ void HmdDisplayPlugin::compositeOverlay() {
// set the alpha // set the alpha
Uniform<float>(*_program, _alphaUniform).Set(overlayAlpha); Uniform<float>(*_program, _alphaUniform).Set(overlayAlpha);
auto eyePoses = _currentPresentFrameInfo.eyePoses;
_sphereSection->Use(); _sphereSection->Use();
for_each_eye([&](Eye eye) { for_each_eye([&](Eye eye) {
eyeViewport(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; auto mvp = _eyeProjections[eye] * modelView;
Uniform<glm::mat4>(*_program, _mvpUniform).Set(mvp); Uniform<glm::mat4>(*_program, _mvpUniform).Set(mvp);
_sphereSection->Draw(); _sphereSection->Draw();
@ -95,10 +96,10 @@ void HmdDisplayPlugin::compositePointer() {
// Mouse pointer // Mouse pointer
_plane->Use(); _plane->Use();
// Reconstruct the headpose from the eye poses // 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) { for_each_eye([&](Eye eye) {
eyeViewport(eye); eyeViewport(eye);
auto reticleTransform = compositorHelper->getReticleTransform(_currentRenderEyePoses[eye], headPosition); auto reticleTransform = compositorHelper->getReticleTransform(_currentPresentFrameInfo.eyePoses[eye], headPosition);
auto mvp = _eyeProjections[eye] * reticleTransform; auto mvp = _eyeProjections[eye] * reticleTransform;
Uniform<glm::mat4>(*_program, _mvpUniform).Set(mvp); Uniform<glm::mat4>(*_program, _mvpUniform).Set(mvp);
_plane->Draw(); _plane->Draw();
@ -160,15 +161,28 @@ void HmdDisplayPlugin::internalPresent() {
void HmdDisplayPlugin::setEyeRenderPose(uint32_t frameIndex, Eye eye, const glm::mat4& pose) { void HmdDisplayPlugin::setEyeRenderPose(uint32_t frameIndex, Eye eye, const glm::mat4& pose) {
Lock lock(_mutex); Lock lock(_mutex);
_renderEyePoses[frameIndex][eye] = pose; FrameInfo& frame = _frameInfos[frameIndex];
frame.eyePoses[eye] = pose;
} }
void HmdDisplayPlugin::updateFrameData() { 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(); Parent::updateFrameData();
Lock lock(_mutex);
_currentRenderEyePoses = _renderEyePoses[_currentRenderFrameIndex]; {
Lock lock(_mutex);
_currentPresentFrameInfo = _frameInfos[_currentRenderFrameIndex];
}
} }
glm::mat4 HmdDisplayPlugin::getHeadPose() const { glm::mat4 HmdDisplayPlugin::getHeadPose() const {
return _headPoseCache.get(); return _currentRenderFrameInfo.get().headPose;
} }

View file

@ -28,6 +28,16 @@ public:
virtual glm::mat4 getHeadPose() const override; 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: protected:
virtual void hmdPresent() = 0; virtual void hmdPresent() = 0;
virtual bool isHmdMounted() const = 0; virtual bool isHmdMounted() const = 0;
@ -46,10 +56,10 @@ protected:
glm::mat4 _cullingProjection; glm::mat4 _cullingProjection;
glm::uvec2 _renderTargetSize; glm::uvec2 _renderTargetSize;
float _ipd { 0.064f }; float _ipd { 0.064f };
using EyePoses = std::array<glm::mat4, 2>;
QMap<uint32_t, EyePoses> _renderEyePoses; QMap<uint32_t, FrameInfo> _frameInfos;
EyePoses _currentRenderEyePoses; FrameInfo _currentPresentFrameInfo;
ThreadSafeValueCache<glm::mat4> _headPoseCache { glm::mat4() }; ThreadSafeValueCache<FrameInfo> _currentRenderFrameInfo;
private: private:
bool _enablePreview { false }; bool _enablePreview { false };

View file

@ -122,7 +122,7 @@ public:
} }
// will query the underlying hmd api to compute the most recent head pose // 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 // returns a copy of the most recent head pose, computed via updateHeadPose
virtual glm::mat4 getHeadPose() const { virtual glm::mat4 getHeadPose() const {
@ -142,6 +142,8 @@ public:
virtual float presentRate() { return -1.0f; } virtual float presentRate() { return -1.0f; }
uint32_t presentCount() const { return _presentedFrameIndex; } uint32_t presentCount() const { return _presentedFrameIndex; }
virtual void cycleDebugOutput() {}
static const QString& MENU_PATH(); static const QString& MENU_PATH();
signals: signals:

View file

@ -538,7 +538,7 @@ void Model::setVisibleInScene(bool newValue, std::shared_ptr<render::Scene> scen
pendingChanges.resetItem(item, _modelMeshRenderItems[item]); pendingChanges.resetItem(item, _modelMeshRenderItems[item]);
} }
foreach (auto item, _collisionRenderItems.keys()) { foreach (auto item, _collisionRenderItems.keys()) {
pendingChanges.resetItem(item, _modelMeshRenderItems[item]); pendingChanges.resetItem(item, _collisionRenderItems[item]);
} }
scene->enqueuePendingChanges(pendingChanges); scene->enqueuePendingChanges(pendingChanges);
} }

View file

@ -16,8 +16,13 @@
using namespace render; using namespace render;
void PendingChanges::resetItem(ItemID id, const PayloadPointer& payload) { void PendingChanges::resetItem(ItemID id, const PayloadPointer& payload) {
_resetItems.push_back(id); if (payload) {
_resetPayloads.push_back(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) { void PendingChanges::removeItem(ItemID id) {

View file

@ -23,6 +23,7 @@
template <typename T> template <typename T>
class ThreadSafeValueCache { class ThreadSafeValueCache {
public: public:
ThreadSafeValueCache() {}
ThreadSafeValueCache(const T& v) : _value { v } {} ThreadSafeValueCache(const T& v) : _value { v } {}
// returns atomic copy of the cached value. // returns atomic copy of the cached value.

View file

@ -12,14 +12,19 @@
#include "OculusHelpers.h" #include "OculusHelpers.h"
void OculusBaseDisplayPlugin::resetSensors() { void OculusBaseDisplayPlugin::resetSensors() {
ovr_RecenterPose(_session); ovr_RecenterTrackingOrigin(_session);
} }
void OculusBaseDisplayPlugin::updateHeadPose(uint32_t frameIndex) { void OculusBaseDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
auto displayTime = ovr_GetPredictedDisplayTime(_session, frameIndex); FrameInfo frame;
auto trackingState = ovr_GetTrackingState(_session, displayTime, true); frame.sensorSampleTime = ovr_GetTimeInSeconds();;
mat4 headPose = toGlm(trackingState.HeadPose.ThePose); frame.predictedDisplayTime = ovr_GetPredictedDisplayTime(_session, frameIndex);
_headPoseCache.set(headPose); 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 { bool OculusBaseDisplayPlugin::isSupported() const {
@ -42,36 +47,30 @@ bool OculusBaseDisplayPlugin::internalActivate() {
_hmdDesc = ovr_GetHmdDesc(_session); _hmdDesc = ovr_GetHmdDesc(_session);
_ipd = ovr_GetFloat(_session, OVR_KEY_IPD, _ipd);
glm::uvec2 eyeSizes[2]; glm::uvec2 eyeSizes[2];
_viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f; _viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
_ipd = 0;
ovr_for_each_eye([&](ovrEyeType eye) { ovr_for_each_eye([&](ovrEyeType eye) {
_eyeFovs[eye] = _hmdDesc.DefaultEyeFov[eye]; _eyeFovs[eye] = _hmdDesc.DefaultEyeFov[eye];
ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_session, eye, _eyeFovs[eye]); ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_session, eye, _eyeFovs[eye]);
ovrMatrix4f ovrPerspectiveProjection = 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); _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)); 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]; auto combinedFov = _eyeFovs[0];
combinedFov.LeftTan = combinedFov.RightTan = std::max(combinedFov.LeftTan, combinedFov.RightTan); 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( _renderTargetSize = uvec2(
eyeSizes[0].x + eyeSizes[1].x, eyeSizes[0].x + eyeSizes[1].x,
std::max(eyeSizes[0].y, eyeSizes[1].y)); 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)); memset(&_sceneLayer, 0, sizeof(ovrLayerEyeFov));
_sceneLayer.Header.Type = ovrLayerType_EyeFov; _sceneLayer.Header.Type = ovrLayerType_EyeFov;
_sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; _sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;

View file

@ -20,7 +20,8 @@ public:
// Stereo specific methods // Stereo specific methods
virtual void resetSensors() override final; virtual void resetSensors() override final;
virtual void updateHeadPose(uint32_t frameIndex) override; virtual void beginFrameRender(uint32_t frameIndex) override;
protected: protected:
void customizeContext() override; void customizeContext() override;
@ -28,9 +29,8 @@ protected:
void internalDeactivate() override; void internalDeactivate() override;
protected: protected:
ovrSession _session; ovrSession _session { nullptr };
ovrGraphicsLuid _luid; ovrGraphicsLuid _luid;
float _ipd{ OVR_DEFAULT_IPD };
ovrEyeRenderDesc _eyeRenderDescs[2]; ovrEyeRenderDesc _eyeRenderDescs[2];
ovrFovPort _eyeFovs[2]; ovrFovPort _eyeFovs[2];
ovrHmdDesc _hmdDesc; ovrHmdDesc _hmdDesc;

View 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;
}

View 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

View file

@ -10,6 +10,23 @@
#include "OculusHelpers.h" #include "OculusHelpers.h"
const QString OculusDisplayPlugin::NAME("Oculus Rift"); 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() { void OculusDisplayPlugin::customizeContext() {
Parent::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() { void OculusDisplayPlugin::hmdPresent() {
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)_currentRenderFrameIndex) PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)_currentRenderFrameIndex)
@ -63,12 +74,15 @@ void OculusDisplayPlugin::hmdPresent() {
} }
blit(_compositeFramebuffer, _sceneFbo); 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; ovrLayerHeader* layers = &_sceneLayer.Header;
ovrResult result = ovr_SubmitFrame(_session, _currentRenderFrameIndex, &_viewScaleDesc, &layers, 1); ovrResult result = ovr_SubmitFrame(_session, _currentRenderFrameIndex, &_viewScaleDesc, &layers, 1);
if (!OVR_SUCCESS(result)) { if (!OVR_SUCCESS(result)) {
logWarning("Failed to present"); logWarning("Failed to present");
} }
} }
_sceneFbo->Increment();
} }

View file

@ -22,12 +22,13 @@ public:
float getTargetFrameRate() override { return TARGET_RATE_Oculus; } float getTargetFrameRate() override { return TARGET_RATE_Oculus; }
protected: protected:
bool internalActivate() override;
void hmdPresent() override; void hmdPresent() override;
// FIXME update with Oculus API call once it's available in the SDK // FIXME update with Oculus API call once it's available in the SDK
bool isHmdMounted() const override { return true; } bool isHmdMounted() const override { return true; }
void customizeContext() override; void customizeContext() override;
void uncustomizeContext() override; void uncustomizeContext() override;
void updateFrameData() override; void cycleDebugOutput() override;
private: private:
static const QString NAME; static const QString NAME;

View file

@ -9,7 +9,10 @@
#include "OculusHelpers.h" #include "OculusHelpers.h"
#include <atomic> #include <atomic>
#include <QtCore/QLoggingCategory> #include <QtCore/QLoggingCategory>
#include <QtCore/QFile>
#include <QtCore/QDir>
using Mutex = std::mutex; using Mutex = std::mutex;
using Lock = std::unique_lock<Mutex>; using Lock = std::unique_lock<Mutex>;
@ -38,9 +41,23 @@ void logFatal(const char* what) {
qFatal(error.c_str()); 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() { bool oculusAvailable() {
ovrDetectResult detect = ovr_Detect(0); 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() { ovrSession acquireOculusSession() {
@ -98,9 +115,9 @@ SwapFramebufferWrapper::~SwapFramebufferWrapper() {
destroyColor(); destroyColor();
} }
void SwapFramebufferWrapper::Increment() { void SwapFramebufferWrapper::Commit() {
++color->CurrentIndex; auto result = ovr_CommitTextureSwapChain(_session, color);
color->CurrentIndex %= color->TextureCount; Q_ASSERT(OVR_SUCCESS(result));
} }
void SwapFramebufferWrapper::Resize(const uvec2 & size) { void SwapFramebufferWrapper::Resize(const uvec2 & size) {
@ -114,7 +131,7 @@ void SwapFramebufferWrapper::Resize(const uvec2 & size) {
void SwapFramebufferWrapper::destroyColor() { void SwapFramebufferWrapper::destroyColor() {
if (color) { if (color) {
ovr_DestroySwapTextureSet(_session, color); ovr_DestroyTextureSwapChain(_session, color);
color = nullptr; color = nullptr;
} }
} }
@ -122,13 +139,30 @@ void SwapFramebufferWrapper::destroyColor() {
void SwapFramebufferWrapper::initColor() { void SwapFramebufferWrapper::initColor() {
destroyColor(); 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"); logFatal("Failed to create swap textures");
} }
for (int i = 0; i < color->TextureCount; ++i) { int length = 0;
ovrGLTexture& ovrTex = (ovrGLTexture&)color->Textures[i]; result = ovr_GetTextureSwapChainLength(_session, color, &length);
glBindTexture(GL_TEXTURE_2D, ovrTex.OGL.TexId); 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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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); 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) { void SwapFramebufferWrapper::onBind(oglplus::Framebuffer::Target target) {
ovrGLTexture& tex = (ovrGLTexture&)(color->Textures[color->CurrentIndex]); int curIndex;
glFramebufferTexture2D(toEnum(target), GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.OGL.TexId, 0); 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) { void SwapFramebufferWrapper::onUnbind(oglplus::Framebuffer::Target target) {

View file

@ -111,10 +111,10 @@ inline ovrPosef ovrPoseFromGlm(const glm::mat4 & m) {
// then submit it and increment to the next texture. // then submit it and increment to the next texture.
// The Oculus SDK manages the creation and destruction of // The Oculus SDK manages the creation and destruction of
// the textures // the textures
struct SwapFramebufferWrapper : public FramebufferWrapper<ovrSwapTextureSet*, void*> { struct SwapFramebufferWrapper : public FramebufferWrapper<ovrTextureSwapChain, void*> {
SwapFramebufferWrapper(const ovrSession& session); SwapFramebufferWrapper(const ovrSession& session);
~SwapFramebufferWrapper(); ~SwapFramebufferWrapper();
void Increment(); void Commit();
void Resize(const uvec2 & size); void Resize(const uvec2 & size);
protected: protected:
void initColor() override final; void initColor() override final;

View file

@ -18,6 +18,7 @@
#include "OculusDisplayPlugin.h" #include "OculusDisplayPlugin.h"
#include "OculusDebugDisplayPlugin.h" #include "OculusDebugDisplayPlugin.h"
#include "OculusControllerManager.h"
class OculusProvider : public QObject, public DisplayProvider, InputProvider class OculusProvider : public QObject, public DisplayProvider, InputProvider
{ {
@ -51,8 +52,6 @@ public:
} }
virtual InputPluginList getInputPlugins() override { virtual InputPluginList getInputPlugins() override {
// FIXME pending full oculus input API and hardware
#if 0
static std::once_flag once; static std::once_flag once;
std::call_once(once, [&] { std::call_once(once, [&] {
InputPluginPointer plugin(new OculusControllerManager()); InputPluginPointer plugin(new OculusControllerManager());
@ -60,7 +59,6 @@ public:
_inputPlugins.push_back(plugin); _inputPlugins.push_back(plugin);
} }
}); });
#endif
return _inputPlugins; return _inputPlugins;
} }

View file

@ -35,10 +35,14 @@ void OculusLegacyDisplayPlugin::resetSensors() {
ovrHmd_RecenterPose(_hmd); 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); Lock lock(_mutex);
_trackingState = ovrHmd_GetTrackingState(_hmd, ovr_GetTimeInSeconds()); _frameInfos[frameIndex] = frame;
_headPoseCache.set(toGlm(_trackingState.HeadPose.ThePose));
} }
bool OculusLegacyDisplayPlugin::isSupported() const { bool OculusLegacyDisplayPlugin::isSupported() const {

View file

@ -26,7 +26,7 @@ public:
// Stereo specific methods // Stereo specific methods
virtual void resetSensors() override; virtual void resetSensors() override;
virtual void updateHeadPose(uint32_t frameIndex) override; virtual void beginFrameRender(uint32_t frameIndex) override;
virtual float getTargetFrameRate() override; virtual float getTargetFrameRate() override;

View file

@ -121,22 +121,23 @@ void OpenVrDisplayPlugin::resetSensors() {
_sensorResetMat = glm::inverse(cancelOutRollAndPitch(m)); _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); double displayFrequency = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_DisplayFrequency_Float);
float frameDuration = 1.f / displayFrequency; double frameDuration = 1.f / displayFrequency;
float vsyncToPhotons = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SecondsFromVsyncToPhotons_Float); double vsyncToPhotons = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SecondsFromVsyncToPhotons_Float);
FrameInfo frame;
#if THREADED_PRESENT #if THREADED_PRESENT
// 3 frames of prediction + vsyncToPhotons = 44ms total // 3 frames of prediction + vsyncToPhotons = 44ms total
const float NUM_PREDICTION_FRAMES = 3.0f; const double NUM_PREDICTION_FRAMES = 3.0f;
float predictedSecondsFromNow = NUM_PREDICTION_FRAMES * frameDuration + vsyncToPhotons; frame.predictedDisplayTime = NUM_PREDICTION_FRAMES * frameDuration + vsyncToPhotons;
#else #else
float predictedSecondsFromNow = frameDuration + vsyncToPhotons; frame.predictedDisplayTime = frameDuration + vsyncToPhotons;
#endif #endif
vr::TrackedDevicePose_t predictedTrackedDevicePose[vr::k_unMaxTrackedDeviceCount]; 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 // copy and process predictedTrackedDevicePoses
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { 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)); _trackedDeviceLinearVelocities[i] = transformVectorFast(_sensorResetMat, toGlm(_trackedDevicePose[i].vVelocity));
_trackedDeviceAngularVelocities[i] = transformVectorFast(_sensorResetMat, toGlm(_trackedDevicePose[i].vAngularVelocity)); _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() { void OpenVrDisplayPlugin::hmdPresent() {

View file

@ -27,7 +27,7 @@ public:
// Stereo specific methods // Stereo specific methods
virtual void resetSensors() override; virtual void resetSensors() override;
virtual void updateHeadPose(uint32_t frameIndex) override; virtual void beginFrameRender(uint32_t frameIndex) override;
protected: protected:
bool internalActivate() override; bool internalActivate() override;

View file

@ -1,5 +1,6 @@
Server\ Console-*/ Server\ Console-*/
server-console-*/ server-console-*/
Sandbox-*/
electron-packager/ electron-packager/
npm-debug.log npm-debug.log
logs/ logs/

View file

@ -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 # set the packaged console folder depending on platform, so we can copy it
if (APPLE) 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) elseif (WIN32)
set(PACKAGED_CONSOLE_FOLDER "server-console-win32-x64") set(PACKAGED_CONSOLE_FOLDER "server-console-win32-x64")
elseif (UNIX) elseif (UNIX)

View file

@ -23,12 +23,12 @@ var options = {
arch: "x64", arch: "x64",
platform: platform, platform: platform,
icon: "resources/" + iconName, 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 EXEC_NAME = "server-console";
const SHORT_NAME = "Server Console"; const SHORT_NAME = "Sandbox";
const FULL_NAME = "High Fidelity Server Console"; const FULL_NAME = "High Fidelity Sandbox";
// setup per OS options // setup per OS options
if (osType == "Darwin") { if (osType == "Darwin") {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -111,8 +111,8 @@ function shutdown() {
dialog.showMessageBox({ dialog.showMessageBox({
type: 'question', type: 'question',
buttons: ['Yes', 'No'], buttons: ['Yes', 'No'],
title: 'Stopping Server Console', title: 'Stopping High Fidelity Sandbox',
message: 'Quitting will stop your Server Console and your Home domain will no longer be running.\nDo you wish to continue?' message: 'Quitting will stop your Sandbox and your Home domain will no longer be running.\nDo you wish to continue?'
}, shutdownCallback); }, shutdownCallback);
} else { } else {
shutdownCallback(0); shutdownCallback(0);
@ -212,7 +212,7 @@ var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory)
}); });
if (shouldQuit) { 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(); app.quit();
return; return;
} }
@ -237,7 +237,7 @@ function binaryMissingMessage(displayName, executableName, required) {
var message = "The " + displayName + " executable was not found.\n"; var message = "The " + displayName + " executable was not found.\n";
if (required) { 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 { } else {
message += "\n"; message += "\n";
} }
@ -250,7 +250,7 @@ function binaryMissingMessage(displayName, executableName, required) {
message += paths.join("\n"); message += paths.join("\n");
} else { } else {
message += "It is expected to be found beside this executable.\n"; 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; 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 logWindow = null;
var labels = { var labels = {
@ -530,12 +402,6 @@ var labels = {
shell.openExternal('http://localhost:40100/settings/?action=share') shell.openExternal('http://localhost:40100/settings/?action=share')
} }
}, },
migrateContent: {
label: 'Migrate Stack Manager Content',
click: function() {
promptToMigrateContent();
}
},
shuttingDown: { shuttingDown: {
label: "Shutting down...", label: "Shutting down...",
enabled: false enabled: false
@ -569,13 +435,6 @@ function buildMenuArray(serverState) {
menuArray.push(labels.share); menuArray.push(labels.share);
menuArray.push(separator); menuArray.push(separator);
menuArray.push(labels.quit); 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({ var window = new BrowserWindow({
icon: appIcon, icon: appIcon,
width: 1600 * zoomFactor, width: 1600 * zoomFactor,
height: 737 * zoomFactor, height: 650 * zoomFactor,
center: true, center: true,
frame: true, frame: true,
useContentSize: true, useContentSize: true,
@ -770,7 +629,7 @@ app.on('ready', function() {
// Create tray icon // Create tray icon
tray = new Tray(trayIcons[ProcessGroupStates.STOPPED]); tray = new Tray(trayIcons[ProcessGroupStates.STOPPED]);
tray.setToolTip('High Fidelity Server Console'); tray.setToolTip('High Fidelity Sandbox');
tray.on('click', function() { tray.on('click', function() {
tray.popUpContextMenu(tray.menu); tray.popUpContextMenu(tray.menu);

View file

@ -122,11 +122,6 @@ h2 {
#main-content { #main-content {
height: 350px; height: 350px;
border-bottom: 2px solid #F5F6F6;
}
#existing-resources-area {
padding-top: 20px;
} }
.footer { .footer {
@ -143,4 +138,4 @@ h2 {
input[type="checkbox"] { input[type="checkbox"] {
-webkit-transform: scale(1.4); -webkit-transform: scale(1.4);
display: inline-block; display: inline-block;
} }

View file

@ -23,7 +23,7 @@ High Fidelity is now installed and your Home domain is ready for you to explore.
</p> </p>
<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> </p>
@ -67,12 +67,6 @@ You can make your home yours by uploading your own models and scripts, and addin
</script> </script>
</div> </div>
</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>
<div class="bottom"> <div class="bottom">
<div class="content footer"> <div class="content footer">

View file

@ -795,3 +795,35 @@ void OctreeTests::modelItemTests() {
#endif #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);
}
}
}

View file

@ -25,6 +25,8 @@ private slots:
// This test is fine // This test is fine
void modelItemTests(); void modelItemTests();
void elementAddChildTests();
// TODO: Break these into separate test functions // TODO: Break these into separate test functions
}; };