merged master

This commit is contained in:
amerhifi 2019-05-03 09:12:21 -07:00
commit 2762597e6a
38 changed files with 1513 additions and 1325 deletions

View file

@ -89,7 +89,7 @@ if (APPLE)
string(REGEX MATCH "^[0-9]+\\.[0-9]+" OSX_VERSION ${OSX_VERSION})
message(STATUS "Detected OS X version = ${OSX_VERSION}")
set(OSX_SDK "${OSX_VERSION}" CACHE String "OS X SDK version to look for inside Xcode bundle or at OSX_SDK_PATH")
set(OSX_SDK "${OSX_VERSION}" CACHE STRING "OS X SDK version to look for inside Xcode bundle or at OSX_SDK_PATH")
# set our OS X deployment target
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)

View file

@ -27,12 +27,12 @@ if (WIN32)
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
set(LIBOVR_DIR ${INSTALL_DIR})
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${LIBOVR_DIR}/Include CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${LIBOVR_DIR}/Lib/LibOVRd.lib CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${LIBOVR_DIR}/Lib/LibOVR.lib CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${LIBOVR_DIR}/Include CACHE STRING INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${LIBOVR_DIR}/Lib/LibOVRd.lib CACHE STRING INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${LIBOVR_DIR}/Lib/LibOVR.lib CACHE STRING INTERNAL)
include(SelectLibraryConfigurations)
select_library_configurations(LIBOVR)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE STRING INTERNAL)
elseif(APPLE)
@ -50,11 +50,11 @@ elseif(APPLE)
# In theory we should use the Headers path inside the framework, as seen here
# but unfortunately Oculus doesn't seem to have figured out automated testing
# so they released a framework with missing headers.
#set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/LibOVR/Lib/Mac/Release/LibOVR.framework/Headers/ CACHE TYPE INTERNAL)
#set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/LibOVR/Lib/Mac/Release/LibOVR.framework/Headers/ CACHE STRING INTERNAL)
# Work around the broken framework by using a different path for the headers.
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/LibOVR/Include CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/LibOVR/Lib/Mac/Release/LibOVR.framework/LibOVR CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/LibOVR/Include CACHE STRING INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/LibOVR/Lib/Mac/Release/LibOVR.framework/LibOVR CACHE STRING INTERNAL)
@ -74,8 +74,8 @@ elseif(NOT ANDROID)
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/libovr.a CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/libovr.a CACHE STRING INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE STRING INTERNAL)
find_package(Threads REQUIRED)
find_package(X11 REQUIRED)
@ -89,8 +89,8 @@ elseif(NOT ANDROID)
select_library_configurations(${EXTERNAL_NAME_UPPER})
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/LibOVR/Include ${SOURCE_DIR}/LibOVR/Src CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARY} ${${EXTERNAL_NAME_UPPER}_LIBRARY_EXTRAS} CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/LibOVR/Include ${SOURCE_DIR}/LibOVR/Src CACHE STRING INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARY} ${${EXTERNAL_NAME_UPPER}_LIBRARY_EXTRAS} CACHE STRING INTERNAL)
endif()
# Hide this external target (for ide users)

View file

@ -20,12 +20,12 @@ if (WIN32)
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/Windows/LibOVRPlatform64_1.lib CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/Windows/LibOVRPlatform64_1.lib CACHE STRING INTERNAL)
else()
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/Windows/LibOVRPlatform32_1.lib CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/Windows/LibOVRPlatform32_1.lib CACHE STRING INTERNAL)
endif()
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/Include CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/Include CACHE STRING INTERNAL)
endif ()
# Hide this external target (for ide users)

View file

@ -36,10 +36,10 @@ set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE STRING INTERNAL)
if (WIN32)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/audio.lib CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/audio.lib CACHE STRING INTERNAL)
else()
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/libaudio.a CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/libaudio.a CACHE STRING INTERNAL)
endif()

View file

@ -21,9 +21,9 @@ set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
# set include dir
if(WIN32)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS "${SOURCE_DIR}/NeuronDataReader_Windows/include" CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS "${SOURCE_DIR}/NeuronDataReader_Windows/include" CACHE STRING INTERNAL)
elseif(APPLE)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS "${SOURCE_DIR}/NeuronDataReader_Mac/include" CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS "${SOURCE_DIR}/NeuronDataReader_Mac/include" CACHE STRING INTERNAL)
else()
# Unsupported
endif()
@ -37,16 +37,16 @@ if(WIN32)
endif()
set(${EXTERNAL_NAME_UPPER}_LIB_PATH "${SOURCE_DIR}/NeuronDataReader_Windows/lib/${ARCH_DIR}")
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/NeuronDataReader.lib" CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/NeuronDataReader.lib" CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/NeuronDataReader.lib" CACHE STRING INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/NeuronDataReader.lib" CACHE STRING INTERNAL)
add_paths_to_fixup_libs("${${EXTERNAL_NAME_UPPER}_LIB_PATH}")
elseif(APPLE)
set(${EXTERNAL_NAME_UPPER}_LIB_PATH "${SOURCE_DIR}/NeuronDataReader_Mac/dylib")
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/NeuronDataReader.dylib" CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/NeuronDataReader.dylib" CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/NeuronDataReader.dylib" CACHE STRING INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/NeuronDataReader.dylib" CACHE STRING INTERNAL)
add_paths_to_fixup_libs("${${EXTERNAL_NAME_UPPER}_LIB_PATH}")

View file

@ -30,7 +30,7 @@ set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE STRING INTERNAL)
if (WIN32)
@ -52,7 +52,7 @@ if (WIN32)
set(${EXTERNAL_NAME_UPPER}_LIB_PATH "${SOURCE_DIR}/lib/${ARCH_DIR}/release_dll")
endif()
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/sixense${ARCH_SUFFIX}.lib" CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/sixense${ARCH_SUFFIX}.lib" CACHE STRING INTERNAL)
add_paths_to_fixup_libs("${${EXTERNAL_NAME_UPPER}_DLL_PATH}")
elseif(APPLE)
@ -62,7 +62,7 @@ elseif(APPLE)
elseif(NOT ANDROID)
# FIXME need to account for different architectures
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/lib/linux_x64/release/libsixense_x64.so CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/lib/linux_x64/release/libsixense_x64.so CACHE STRING INTERNAL)
endif()

View file

@ -21,7 +21,7 @@ set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/public CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/public CACHE STRING INTERNAL)
if (WIN32)
@ -36,12 +36,12 @@ if (WIN32)
set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${ARCH_DIR})
set(${EXTERNAL_NAME_UPPER}_LIB_PATH ${ARCH_DIR})
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/steam_api${ARCH_SUFFIX}.lib" CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE "${${EXTERNAL_NAME_UPPER}_LIB_PATH}/steam_api${ARCH_SUFFIX}.lib" CACHE STRING INTERNAL)
add_paths_to_fixup_libs("${${EXTERNAL_NAME_UPPER}_DLL_PATH}")
elseif(APPLE)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/redistributable_bin/osx32/libsteam_api.dylib CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/redistributable_bin/osx32/libsteam_api.dylib CACHE STRING INTERNAL)
set(_STEAMWORKS_LIB_DIR "${SOURCE_DIR}/redistributable_bin/osx32")
ExternalProject_Add_Step(
@ -57,6 +57,6 @@ elseif(APPLE)
elseif(NOT ANDROID)
# FIXME need to account for different architectures
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/redistributable_bin/linux64/libsteam_api.so CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/redistributable_bin/linux64/libsteam_api.so CACHE STRING INTERNAL)
endif()

View file

@ -102,6 +102,6 @@ if (DEFINED _TBB_LIB_DIR)
endif ()
if (DEFINED ${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE "List of tbb include directories")
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE STRING "List of tbb include directories")
endif ()

View file

@ -8,7 +8,7 @@
macro(TARGET_BREAKPAD)
if (ANDROID)
set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/breakpad)
set(BREAKPAD_INCLUDE_DIRS "${INSTALL_DIR}/include" CACHE TYPE INTERNAL)
set(BREAKPAD_INCLUDE_DIRS "${INSTALL_DIR}/include" CACHE STRING INTERNAL)
set(LIB_DIR ${INSTALL_DIR}/lib)
list(APPEND BREAKPAD_LIBRARIES ${LIB_DIR}/libbreakpad_client.a)
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BREAKPAD_INCLUDE_DIRS})

View file

@ -8,7 +8,7 @@
macro(TARGET_BULLET)
if (ANDROID)
set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/bullet)
set(BULLET_INCLUDE_DIRS "${INSTALL_DIR}/include/bullet" CACHE TYPE INTERNAL)
set(BULLET_INCLUDE_DIRS "${INSTALL_DIR}/include/bullet" CACHE STRING INTERNAL)
set(LIB_DIR ${INSTALL_DIR}/lib)
list(APPEND BULLET_LIBRARIES ${LIB_DIR}/libBulletDynamics.a)

View file

@ -3,7 +3,7 @@ macro(TARGET_DRACO)
find_library(LIBPATH ${LIB} PATHS )
if (ANDROID)
set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/draco)
set(DRACO_INCLUDE_DIRS "${INSTALL_DIR}/include" CACHE TYPE INTERNAL)
set(DRACO_INCLUDE_DIRS "${INSTALL_DIR}/include" CACHE STRING INTERNAL)
set(LIB_DIR ${INSTALL_DIR}/lib)
list(APPEND DRACO_LIBRARIES ${LIB_DIR}/libdraco.a)
list(APPEND DRACO_LIBRARIES ${LIB_DIR}/libdracodec.a)
@ -21,4 +21,4 @@ macro(TARGET_DRACO)
select_library_configurations(DRACO)
target_link_libraries(${TARGET_NAME} ${DRACO_LIBRARY})
endif()
endmacro()
endmacro()

View file

@ -9,9 +9,9 @@ macro(TARGET_HIFIAUDIOCODEC)
if (ANDROID)
set(HIFIAC_INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/hifiAC/codecSDK)
set(HIFIAC_LIB_DIR "${HIFIAC_INSTALL_DIR}/Release")
set(HIFIAC_INCLUDE_DIRS "${HIFIAC_INSTALL_DIR}/include" CACHE TYPE INTERNAL)
set(HIFIAC_INCLUDE_DIRS "${HIFIAC_INSTALL_DIR}/include" CACHE STRING INTERNAL)
list(APPEND HIFIAC_LIBS "${HIFIAC_LIB_DIR}/libaudio.a")
set(HIFIAC_LIBRARIES ${HIFIAC_LIBS} CACHE TYPE INTERNAL)
set(HIFIAC_LIBRARIES ${HIFIAC_LIBS} CACHE STRING INTERNAL)
else()
add_dependency_external_projects(hifiAudioCodec)
target_include_directories(${TARGET_NAME} PRIVATE ${HIFIAUDIOCODEC_INCLUDE_DIRS})

View file

@ -9,12 +9,12 @@ macro(TARGET_NVTT)
if (ANDROID)
set(NVTT_INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/nvtt)
set(NVTT_LIB_DIR "${NVTT_INSTALL_DIR}/lib")
set(NVTT_INCLUDE_DIRS "${NVTT_INSTALL_DIR}/include" CACHE TYPE INTERNAL)
set(NVTT_INCLUDE_DIRS "${NVTT_INSTALL_DIR}/include" CACHE STRING INTERNAL)
list(APPEND NVTT_LIBS "${NVTT_LIB_DIR}/libnvcore.so")
list(APPEND NVTT_LIBS "${NVTT_LIB_DIR}/libnvmath.so")
list(APPEND NVTT_LIBS "${NVTT_LIB_DIR}/libnvimage.so")
list(APPEND NVTT_LIBS "${NVTT_LIB_DIR}/libnvtt.so")
set(NVTT_LIBRARIES ${NVTT_LIBS} CACHE TYPE INTERNAL)
set(NVTT_LIBRARIES ${NVTT_LIBS} CACHE STRING INTERNAL)
target_include_directories(${TARGET_NAME} PRIVATE ${NVTT_INCLUDE_DIRS})
else()
find_library(NVTT_LIBRARY_RELEASE nvtt PATHS ${VCPKG_INSTALL_ROOT}/lib NO_DEFAULT_PATH)

View file

@ -8,8 +8,8 @@
macro(TARGET_OPENSSL)
if (ANDROID)
set(OPENSSL_INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/openssl)
set(OPENSSL_INCLUDE_DIR "${OPENSSL_INSTALL_DIR}/include" CACHE TYPE INTERNAL)
set(OPENSSL_LIBRARIES "${OPENSSL_INSTALL_DIR}/lib/libcrypto.a;${OPENSSL_INSTALL_DIR}/lib/libssl.a" CACHE TYPE INTERNAL)
set(OPENSSL_INCLUDE_DIR "${OPENSSL_INSTALL_DIR}/include" CACHE STRING INTERNAL)
set(OPENSSL_LIBRARIES "${OPENSSL_INSTALL_DIR}/lib/libcrypto.a;${OPENSSL_INSTALL_DIR}/lib/libssl.a" CACHE STRING INTERNAL)
else()
# using VCPKG for OpenSSL
find_package(OpenSSL REQUIRED)

View file

@ -8,7 +8,7 @@
macro(TARGET_POLYVOX)
if (ANDROID)
set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/polyvox)
set(POLYVOX_INCLUDE_DIRS "${INSTALL_DIR}/include" CACHE TYPE INTERNAL)
set(POLYVOX_INCLUDE_DIRS "${INSTALL_DIR}/include" CACHE STRING INTERNAL)
set(LIB_DIR ${INSTALL_DIR}/lib)
list(APPEND POLYVOX_LIBRARIES ${LIB_DIR}/libPolyVoxUtil.so)
list(APPEND POLYVOX_LIBRARIES ${LIB_DIR}/Release/libPolyVoxCore.so)

File diff suppressed because it is too large Load diff

View file

@ -20,37 +20,40 @@
#include <display-plugins/hmd/HmdDisplayPlugin.h>
static const int HMD_TARGET_RATE = 90;
static const int VR_TARGET_RATE = 90;
static const std::array<std::string, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> REFRESH_RATE_PROFILE_TO_STRING =
{ { "Eco", "Interactive", "Realtime" } };
static const std::array<std::string, RefreshRateManager::RefreshRateRegime::REGIME_NUM> REFRESH_RATE_REGIME_TO_STRING =
{ { "Running", "Unfocus", "Minimized", "StartUp", "ShutDown" } };
{ { "FocusActive", "FocusInactive", "Unfocus", "Minimized", "StartUp", "ShutDown" } };
static const std::array<std::string, RefreshRateManager::UXMode::UX_NUM> UX_MODE_TO_STRING =
{ { "Desktop", "HMD" } };
{ { "Desktop", "VR" } };
static const std::map<std::string, RefreshRateManager::RefreshRateProfile> REFRESH_RATE_PROFILE_FROM_STRING =
{ { "Eco", RefreshRateManager::RefreshRateProfile::ECO },
{ "Interactive", RefreshRateManager::RefreshRateProfile::INTERACTIVE },
{ "Realtime", RefreshRateManager::RefreshRateProfile::REALTIME } };
static const std::array<int, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> RUNNING_REGIME_PROFILES =
{ { 5, 20, 60 } };
static const std::array<int, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> UNFOCUS_REGIME_PROFILES =
{ { 5, 5, 10 } };
// Porfile regimes are:
// { { "FocusActive", "FocusInactive", "Unfocus", "Minimized", "StartUp", "ShutDown" } }
static const std::array<int, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> MINIMIZED_REGIME_PROFILE =
{ { 2, 2, 2 } };
static const std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM> ECO_PROFILE =
{ { 20, 10, 5, 2, 30, 30 } };
static const std::array<int, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> START_AND_SHUTDOWN_REGIME_PROFILES =
{ { 30, 30, 30 } };
static const std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM> INTERACTIVE_PROFILE =
{ { 30, 20, 10, 2, 30, 30 } };
static const std::array<std::array<int, RefreshRateManager::RefreshRateProfile::PROFILE_NUM>, RefreshRateManager::RefreshRateRegime::REGIME_NUM> REFRESH_RATE_REGIMES =
{ { RUNNING_REGIME_PROFILES, UNFOCUS_REGIME_PROFILES, MINIMIZED_REGIME_PROFILE,
START_AND_SHUTDOWN_REGIME_PROFILES, START_AND_SHUTDOWN_REGIME_PROFILES } };
static const std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM> REALTIME_PROFILE =
{ { 60, 60, 10, 2, 30, 30} };
static const std::array<std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM>, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> REFRESH_RATE_PROFILES =
{ { ECO_PROFILE, INTERACTIVE_PROFILE, REALTIME_PROFILE } };
static const int INACTIVE_TIMER_LIMIT = 3000;
std::string RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile refreshRateProfile) {
@ -70,14 +73,36 @@ std::string RefreshRateManager::uxModeToString(RefreshRateManager::RefreshRateMa
}
RefreshRateManager::RefreshRateManager() {
_refreshRateProfile = (RefreshRateManager::RefreshRateProfile) _refreshRateMode.get();
_refreshRateProfile = (RefreshRateManager::RefreshRateProfile) _refreshRateProfileSetting.get();
_inactiveTimer->setInterval(INACTIVE_TIMER_LIMIT);
_inactiveTimer->setSingleShot(true);
QObject::connect(_inactiveTimer.get(), &QTimer::timeout, [&] {
toggleInactive();
});
}
void RefreshRateManager::resetInactiveTimer() {
if (_uxMode == RefreshRateManager::UXMode::DESKTOP) {
auto regime = getRefreshRateRegime();
if (regime == RefreshRateRegime::FOCUS_ACTIVE || regime == RefreshRateRegime::FOCUS_INACTIVE) {
_inactiveTimer->start();
setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::FOCUS_ACTIVE);
}
}
}
void RefreshRateManager::toggleInactive() {
if (_uxMode == RefreshRateManager::UXMode::DESKTOP &&
getRefreshRateRegime() == RefreshRateManager::RefreshRateRegime::FOCUS_ACTIVE) {
setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::FOCUS_INACTIVE);
}
}
void RefreshRateManager::setRefreshRateProfile(RefreshRateManager::RefreshRateProfile refreshRateProfile) {
if (_refreshRateProfile != refreshRateProfile) {
_refreshRateModeLock.withWriteLock([&] {
_refreshRateProfileSettingLock.withWriteLock([&] {
_refreshRateProfile = refreshRateProfile;
_refreshRateMode.set((int) refreshRateProfile);
_refreshRateProfileSetting.set((int) refreshRateProfile);
});
updateRefreshRateController();
}
@ -86,9 +111,9 @@ void RefreshRateManager::setRefreshRateProfile(RefreshRateManager::RefreshRatePr
RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile() const {
RefreshRateManager::RefreshRateProfile profile = RefreshRateManager::RefreshRateProfile::REALTIME;
if (getUXMode() != RefreshRateManager::UXMode::HMD) {
profile =(RefreshRateManager::RefreshRateProfile) _refreshRateModeLock.resultWithReadLock<int>([&] {
return _refreshRateMode.get();
if (getUXMode() != RefreshRateManager::UXMode::VR) {
profile =(RefreshRateManager::RefreshRateProfile) _refreshRateProfileSettingLock.resultWithReadLock<int>([&] {
return _refreshRateProfileSetting.get();
});
}
@ -96,8 +121,11 @@ RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile
}
RefreshRateManager::RefreshRateRegime RefreshRateManager::getRefreshRateRegime() const {
return getUXMode() == RefreshRateManager::UXMode::HMD ? RefreshRateManager::RefreshRateRegime::RUNNING :
_refreshRateRegime;
if (getUXMode() == RefreshRateManager::UXMode::VR) {
return RefreshRateManager::RefreshRateRegime::FOCUS_ACTIVE;
} else {
return _refreshRateRegime;
}
}
void RefreshRateManager::setRefreshRateRegime(RefreshRateManager::RefreshRateRegime refreshRateRegime) {
@ -119,31 +147,12 @@ void RefreshRateManager::updateRefreshRateController() const {
if (_refreshRateOperator) {
int targetRefreshRate;
if (_uxMode == RefreshRateManager::UXMode::DESKTOP) {
if (_refreshRateRegime == RefreshRateManager::RefreshRateRegime::RUNNING &&
_refreshRateProfile == RefreshRateManager::RefreshRateProfile::INTERACTIVE) {
targetRefreshRate = getInteractiveRefreshRate();
} else {
targetRefreshRate = REFRESH_RATE_REGIMES[_refreshRateRegime][_refreshRateProfile];
}
targetRefreshRate = REFRESH_RATE_PROFILES[_refreshRateProfile][_refreshRateRegime];
} else {
targetRefreshRate = HMD_TARGET_RATE;
targetRefreshRate = VR_TARGET_RATE;
}
_refreshRateOperator(targetRefreshRate);
_activeRefreshRate = targetRefreshRate;
}
}
void RefreshRateManager::setInteractiveRefreshRate(int refreshRate) {
_refreshRateLock.withWriteLock([&] {
_interactiveRefreshRate.set(refreshRate);
});
updateRefreshRateController();
}
int RefreshRateManager::getInteractiveRefreshRate() const {
return _refreshRateLock.resultWithReadLock<int>([&] {
return _interactiveRefreshRate.get();
});
}

View file

@ -15,6 +15,8 @@
#include <map>
#include <string>
#include <QTimer>
#include <SettingHandle.h>
#include <shared/ReadWriteLockable.h>
@ -28,7 +30,8 @@ public:
};
enum RefreshRateRegime {
RUNNING = 0,
FOCUS_ACTIVE = 0,
FOCUS_INACTIVE,
UNFOCUS,
MINIMIZED,
STARTUP,
@ -38,7 +41,7 @@ public:
enum UXMode {
DESKTOP = 0,
HMD,
VR,
UX_NUM
};
@ -57,8 +60,9 @@ public:
void setRefreshRateOperator(std::function<void(int)> refreshRateOperator) { _refreshRateOperator = refreshRateOperator; }
int getActiveRefreshRate() const { return _activeRefreshRate; }
void updateRefreshRateController() const;
void setInteractiveRefreshRate(int refreshRate);
int getInteractiveRefreshRate() const;
void resetInactiveTimer();
void toggleInactive();
static std::string refreshRateProfileToString(RefreshRateProfile refreshRateProfile);
static RefreshRateProfile refreshRateProfileFromString(std::string refreshRateProfile);
@ -66,18 +70,17 @@ public:
static std::string refreshRateRegimeToString(RefreshRateRegime refreshRateRegime);
private:
mutable ReadWriteLockable _refreshRateLock;
mutable ReadWriteLockable _refreshRateModeLock;
mutable int _activeRefreshRate { 20 };
RefreshRateProfile _refreshRateProfile { RefreshRateProfile::INTERACTIVE};
RefreshRateRegime _refreshRateRegime { RefreshRateRegime::STARTUP };
UXMode _uxMode;
Setting::Handle<int> _interactiveRefreshRate { "interactiveRefreshRate", 20};
Setting::Handle<int> _refreshRateMode { "refreshRateProfile", INTERACTIVE };
mutable ReadWriteLockable _refreshRateProfileSettingLock;
Setting::Handle<int> _refreshRateProfileSetting { "refreshRateProfile", RefreshRateProfile::INTERACTIVE };
std::function<void(int)> _refreshRateOperator { nullptr };
std::shared_ptr<QTimer> _inactiveTimer { std::make_shared<QTimer>() };
};
#endif

View file

@ -18,7 +18,7 @@
#include <EntityItemID.h>
/**jsdoc
* The Clipboard API enables you to export and import entities to and from JSON files.
* The <code>Clipboard</code> API enables you to export and import entities to and from JSON files.
*
* @namespace Clipboard
*
@ -33,56 +33,92 @@ public:
public:
/**jsdoc
* Compute the extents of the contents held in the clipboard.
* Gets the extents of the entities held in the clipboard.
* @function Clipboard.getContentsDimensions
* @returns {Vec3} The extents of the contents held in the clipboard.
* @returns {Vec3} The extents of the content held in the clipboard.
* @example <caption>Import entities to the clipboard and report their overall dimensions.</caption>
* var filename = Window.browse("Import entities to clipboard", "", "*.json");
* if (filename) {
* if (Clipboard.importEntities(filename)) {
* print("Clipboard dimensions: " + JSON.stringify(Clipboard.getContentsDimensions()));
* }
* }
*/
Q_INVOKABLE glm::vec3 getContentsDimensions();
/**jsdoc
* Compute the largest dimension of the extents of the contents held in the clipboard.
* Gets the largest dimension of the extents of the entities held in the clipboard.
* @function Clipboard.getClipboardContentsLargestDimension
* @returns {number} The largest dimension computed.
* @returns {number} The largest dimension of the extents of the content held in the clipboard.
*/
Q_INVOKABLE float getClipboardContentsLargestDimension();
/**jsdoc
* Import entities from a JSON file containing entity data into the clipboard.
* You can generate a JSON file using {@link Clipboard.exportEntities}.
* Imports entities from a JSON file into the clipboard.
* @function Clipboard.importEntities
* @param {string} filename Path and name of file to import.
* @param {boolean} does the ResourceRequestObserver observe this request?
* @param {number} optional internal id of object causing this import.
* @param {string} filename - The path and name of the JSON file to import.
* @param {boolean} [isObservable=true] - <code>true</code> if the {@link ResourceRequestObserver} can observe this
* request, <code>false</code> if it can't.
* @param {number} [callerID=-1] - An integer ID that is passed through to the {@link ResourceRequestObserver}.
* @returns {boolean} <code>true</code> if the import was successful, otherwise <code>false</code>.
* @example <caption>Import entities and paste into the domain.</caption>
* var filename = Window.browse("Import entities to clipboard", "", "*.json");
* if (filename) {
* if (Clipboard.importEntities(filename)) {
* pastedEntities = Clipboard.pasteEntities(Vec3.sum(MyAvatar.position,
* Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -3 })));
* print("Entities pasted: " + JSON.stringify(pastedEntities));
* }
* }
*/
Q_INVOKABLE bool importEntities(const QString& filename, const bool isObservable = true, const qint64 callerId = -1);
/**jsdoc
* Export the entities specified to a JSON file.
* Exports specified entities to a JSON file.
* @function Clipboard.exportEntities
* @param {string} filename Path and name of the file to export the entities to. Should have the extension ".json".
* @param {Uuid[]} entityIDs Array of IDs of the entities to export.
* @returns {boolean} <code>true</code> if the export was successful, otherwise <code>false</code>.
* @param {string} filename - Path and name of the file to export the entities to. Should have the extension ".json".
* @param {Uuid[]} entityIDs - The IDs of the entities to export.
* @returns {boolean} <code>true</code> if entities were found and the file was written, otherwise <code>false</code>.
* @example <caption>Create and export a cube and a sphere.</caption>
* // Create entities.
* var box = Entities.addEntity({
* type: "Box",
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: -0.2, y: 0, z: -3 })),
* lifetime: 300 // Delete after 5 minutes.
* });
* var sphere = Entities.addEntity({
* type: "Sphere",
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0.2, y: 0, z: -3 })),
* lifetime: 300 // Delete after 5 minutes.
* });
*
* // Export entities.
* var filename = Window.save("Export entities to JSON file", Paths.resources, "*.json");
* if (filename) {
* Clipboard.exportEntities(filename, [box, sphere]);
* }
*/
Q_INVOKABLE bool exportEntities(const QString& filename, const QVector<QUuid>& entityIDs);
/**jsdoc
* Export the entities with centers within a cube to a JSON file.
* Exports all entities that have centers within a cube to a JSON file.
* @function Clipboard.exportEntities
* @param {string} filename Path and name of the file to export the entities to. Should have the extension ".json".
* @param {number} x X-coordinate of the cube center.
* @param {number} y Y-coordinate of the cube center.
* @param {number} z Z-coordinate of the cube center.
* @param {number} scale Half dimension of the cube.
* @returns {boolean} <code>true</code> if the export was successful, otherwise <code>false</code>.
* @variation 0
* @param {string} filename - Path and name of the file to export the entities to. Should have the extension ".json".
* @param {number} x - X-coordinate of the cube center.
* @param {number} y - Y-coordinate of the cube center.
* @param {number} z - Z-coordinate of the cube center.
* @param {number} scale - Half dimension of the cube.
* @returns {boolean} <code>true</code> if entities were found and the file was written, otherwise <code>false</code>.
*/
Q_INVOKABLE bool exportEntities(const QString& filename, float x, float y, float z, float scale);
/**jsdoc
* Paste the contents of the clipboard into the world.
* Pastes the contents of the clipboard into the domain.
* @function Clipboard.pasteEntities
* @param {Vec3} position Position to paste the clipboard contents at.
* @returns {Uuid[]} Array of entity IDs for the new entities that were created as a result of the paste operation.
* @param {Vec3} position - The position to paste the clipboard contents at.
* @returns {Uuid[]} The IDs of the new entities that were created as a result of the paste operation. If entities couldn't
* be created then an empty array is returned.
*/
Q_INVOKABLE QVector<EntityItemID> pasteEntities(glm::vec3 position);
};

View file

@ -26,18 +26,20 @@ class ScriptEngine;
/**jsdoc
* The Controller API provides facilities to interact with computer and controller hardware.
* The <code>Controller</code> API provides facilities to interact with computer and controller hardware.
*
* <h5>Functions</h5>
* <h3>Facilities</h3>
*
* <p>Properties</p>
* <h4>Properties</h4>
* <p>Get <code>Controller</code> property trees.</p>
* <ul>
* <li>{@link Controller.getActions|getActions}</li>
* <li>{@link Controller.getHardware|getHardware}</li>
* <li>{@link Controller.getStandard|getStandard}</li>
* </ul>
*
* <p>Mappings</p>
* <h4>Mappings</h4>
* <p>Create and enable or disable <code>Controller</code> mappings.</p>
* <ul>
* <li>{@link Controller.disableMapping|disableMapping}</li>
* <li>{@link Controller.enableMapping|enableMapping}</li>
@ -46,7 +48,8 @@ class ScriptEngine;
* <li>{@link Controller.parseMapping|parseMapping}</li>
* </ul>
*
* <p>Input, Hardware, and Action Reflection</p>
* <h4>Input, Hardware, and Action Reflection</h4>
* <p>Information on the devices and actions available.</p>
* <ul>
* <li>{@link Controller.findAction|findAction}</li>
* <li>{@link Controller.findDevice|findDevice}</li>
@ -55,16 +58,20 @@ class ScriptEngine;
* <li>{@link Controller.getAvailableInputs|getAvailableInputs}</li>
* <li>{@link Controller.getDeviceName|getDeviceName}</li>
* <li>{@link Controller.getDeviceNames|getDeviceNames}</li>
* <li>{@link Controller.getRunningInputDevices|getRunningInputDevices}</li>
* </ul>
*
* <p>Input, Hardware, and Action Events</p>
* <h4>Input, Hardware, and Action Signals</h4>
* <p>Notifications of device and action events.</p>
* <ul>
* <li>{@link Controller.actionEvent|actionEvent}</li>
* <li>{@link Controller.hardwareChanged|hardwareChanged}</li>
* <li>{@link Controller.inputDeviceRunningChanged|inputDeviceRunningChanged}</li>
* <li>{@link Controller.inputEvent|inputEvent}</li>
* </ul>
*
* <p>Mouse, Keyboard, and Touch Events</p>
* <h4>Mouse, Keyboard, and Touch Signals</h4>
* <p>Notifications of mouse, keyboard, and touch events.</p>
* <ul>
* <li>{@link Controller.keyPressEvent|keyPressEvent}</li>
* <li>{@link Controller.keyReleaseEvent|keyReleaseEvent}</li>
@ -78,29 +85,32 @@ class ScriptEngine;
* <li>{@link Controller.wheelEvent|wheelEvent}</li>
* </ul>
*
* <p>Control Capturing</p>
* <h4>Control Capturing</h4>
* <p>Disable and enable the processing of mouse and touch events.</p>
* <ul>
* <li>{@link Controller.captureMouseEvents|captureMouseEvents}</li>
* <li>{@link Controller.captureTouchEvents|captureTouchEvents}</li>
* <li>{@link Controller.captureWheelEvents|captureWheelEvents}</li>
* <li>{@link Controller.captureTouchEvents|captureTouchEvents}</li>
* <li>{@link Controller.releaseMouseEvents|releaseMouseEvents}</li>
* <li>{@link Controller.releaseTouchEvents|releaseTouchEvents}</li>
* <li>{@link Controller.releaseWheelEvents|releaseWheelEvents}</li>
* <li>{@link Controller.releaseTouchEvents|releaseTouchEvents}</li>
* </ul>
*
* <p>Action Capturing</p>
* <h4>Action Capturing</h4>
* <p>Disable and enable controller actions.</p>
* <ul>
* <li>{@link Controller.captureActionEvents|captureActionEvents}</li>
* <li>{@link Controller.captureEntityClickEvents|captureEntityClickEvents}</li>
* <li>{@link Controller.captureJoystick|captureJoystick}</li>
* <li>{@link Controller.captureKeyEvents|captureKeyEvents}</li>
* <li>{@link Controller.captureJoystick|captureJoystick}</li>
* <li>{@link Controller.captureEntityClickEvents|captureEntityClickEvents}</li>
* <li>{@link Controller.releaseActionEvents|releaseActionEvents}</li>
* <li>{@link Controller.releaseEntityClickEvents|releaseEntityClickEvents}</li>
* <li>{@link Controller.releaseJoystick|releaseJoystick}</li>
* <li>{@link Controller.releaseKeyEvents|releaseKeyEvents}</li>
* <li>{@link Controller.releaseJoystick|releaseJoystick}</li>
* <li>{@link Controller.releaseEntityClickEvents|releaseEntityClickEvents}</li>
* </ul>
*
* <p>Controller and Action Values</p>
* <h4>Controller and Action Values</h4>
* <p>Get the current value of controller outputs and actions.</p>
* <ul>
* <li>{@link Controller.getValue|getValue}</li>
* <li>{@link Controller.getAxisValue|getAxisValue}</li>
@ -108,7 +118,8 @@ class ScriptEngine;
* <li>{@link Controller.getActionValue|getActionValue}</li>
* </ul>
*
* <p>Haptics</p>
* <h4>Haptics</h4>
* <p>Trigger haptic pulses.</p>
* <ul>
* <li>{@link Controller.triggerHapticPulse|triggerHapticPulse}</li>
* <li>{@link Controller.triggerHapticPulseOnDevice|triggerHapticPulseOnDevice}</li>
@ -116,20 +127,23 @@ class ScriptEngine;
* <li>{@link Controller.triggerShortHapticPulseOnDevice|triggerShortHapticPulseOnDevice}</li>
* </ul>
*
* <p>Display Information</p>
* <h4>Display Information</h4>
* <p>Get information on the display.</p>
* <ul>
* <li>{@link Controller.getViewportDimensions|getViewportDimensions}</li>
* <li>{@link Controller.getRecommendedHUDRect|getRecommendedHUDRect}</li>
* </ul>
*
* <p>Virtual Game Pad</p>
* <h4>Virtual Game Pad</h4>
* <p>Use the virtual game pad which is available on some devices.</p>
* <ul>
* <li>{@link Controller.setVPadEnabled|setVPadEnabled}</li>
* <li>{@link Controller.setVPadHidden|setVPadHidden}</li>
* <li>{@link Controller.setVPadExtraBottomMargin|setVPadExtraBottomMargin}</li>
* </ul>
*
* <p>Input Recordings</p>
* <h4>Input Recordings</h4>
* <p>Create and play input recordings.</p>
* <ul>
* <li>{@link Controller.startInputRecording|startInputRecording}</li>
* <li>{@link Controller.stopInputRecording|stopInputRecording}</li>
@ -140,10 +154,10 @@ class ScriptEngine;
* <li>{@link Controller.stopInputPlayback|stopInputPlayback}</li>
* </ul>
*
* <h5>Entity Methods:</h5>
* <h3>Entity Methods</h3>
*
* <p>The default scripts implement hand controller actions that use {@link Entities.callEntityMethod} to call entity script
* methods, if present in the entity being interacted with.</p>
* methods, if present, in the entity being interacted with.</p>
*
* <table>
* <thead>
@ -203,7 +217,7 @@ class ScriptEngine;
*
* @property {Controller.Actions} Actions - Predefined actions on Interface and the user's avatar. These can be used as end
* points in a {@link RouteObject} mapping. A synonym for <code>Controller.Hardware.Actions</code>.
* <em>Read-only.</em><br />
* <em>Read-only.</em><br /><br />
* Default mappings are provided from the <code>Controller.Hardware.Keyboard</code> and <code>Controller.Standard</code> to
* actions in
* <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/keyboardMouse.json">
@ -217,7 +231,7 @@ class ScriptEngine;
* controller outputs. <em>Read-only.</em>
*
* @property {Controller.Standard} Standard - Standard controller outputs that can be mapped to <code>Actions</code> or
* functions in a {@link RouteObject} mapping. <em>Read-only.</em><br />
* functions in a {@link RouteObject} mapping. <em>Read-only.</em><br /><br />
* Each hardware device has a mapping from its outputs to <code>Controller.Standard</code> items, specified in a JSON file.
* For example, <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/leapmotion.json">
* leapmotion.json</a> and
@ -253,7 +267,7 @@ public:
public slots:
/**jsdoc
* Disable default Interface actions for a particular key event.
* Disables default Interface actions for a particular key event.
* @function Controller.captureKeyEvents
* @param {KeyEvent} event - Details of the key event to be captured. The <code>key</code> property must be specified. The
* <code>text</code> property is ignored. The other properties default to <code>false</code>.
@ -272,7 +286,7 @@ public slots:
virtual void captureKeyEvents(const KeyEvent& event);
/**jsdoc
* Re-enable default Interface actions for a particular key event that has been disabled using
* Re-enables default Interface actions for a particular key event that has been disabled using
* {@link Controller.captureKeyEvents|captureKeyEvents}.
* @function Controller.releaseKeyEvents
* @param {KeyEvent} event - Details of the key event to release from capture. The <code>key</code> property must be
@ -281,7 +295,7 @@ public slots:
virtual void releaseKeyEvents(const KeyEvent& event);
/**jsdoc
* Disable default Interface actions for a joystick.
* Disables default Interface actions for a joystick.
* @function Controller.captureJoystick
* @param {number} joystickID - The integer ID of the joystick.
* @deprecated This function is deprecated and will be removed. It no longer has any effect.
@ -289,7 +303,7 @@ public slots:
virtual void captureJoystick(int joystickIndex);
/**jsdoc
* Re-enable default Interface actions for a joystick that has been disabled using
* Re-enables default Interface actions for a joystick that has been disabled using
* {@link Controller.captureJoystick|captureJoystick}.
* @function Controller.releaseJoystick
* @param {number} joystickID - The integer ID of the joystick.
@ -298,7 +312,7 @@ public slots:
virtual void releaseJoystick(int joystickIndex);
/**jsdoc
* Disable {@link Entities.mousePressOnEntity} and {@link Entities.mouseDoublePressOnEntity} events on entities.
* Disables {@link Entities.mousePressOnEntity} and {@link Entities.mouseDoublePressOnEntity} events on entities.
* @function Controller.captureEntityClickEvents
* @example <caption>Disable entity click events for a short period.</caption>
* Entities.mousePressOnEntity.connect(function (entityID, event) {
@ -316,7 +330,7 @@ public slots:
virtual void captureEntityClickEvents();
/**jsdoc
* Re-enable {@link Entities.mousePressOnEntity} and {@link Entities.mouseDoublePressOnEntity} events on entities that were
* Re-enables {@link Entities.mousePressOnEntity} and {@link Entities.mouseDoublePressOnEntity} events on entities that were
* disabled using {@link Controller.captureEntityClickEvents|captureEntityClickEvents}.
* @function Controller.releaseEntityClickEvents
*/
@ -324,14 +338,14 @@ public slots:
/**jsdoc
* Get the dimensions of the Interface window's interior if in desktop mode or the HUD surface if in HMD mode.
* Gets the dimensions of the Interface window's interior if in desktop mode or the HUD surface if in HMD mode.
* @function Controller.getViewportDimensions
* @returns {Vec2} The dimensions of the Interface window interior if in desktop mode or HUD surface if in HMD mode.
*/
virtual glm::vec2 getViewportDimensions() const;
/**jsdoc
* Get the recommended area to position UI on the HUD surface if in HMD mode or Interface's window interior if in desktop
* Gets the recommended area to position UI on the HUD surface if in HMD mode or Interface's window interior if in desktop
* mode.
* @function Controller.getRecommendedHUDRect
* @returns {Rect} The recommended area in which to position UI.

View file

@ -35,9 +35,9 @@ namespace controller {
/**jsdoc
* <p>The <code>Controller.Actions</code> object has properties representing predefined actions on the user's avatar and
* Interface. The property values are integer IDs, uniquely identifying each action. <em>Read-only.</em> These can be used
* as end points in the routes of a {@link MappingObject}. The data routed to each action is either a number or a
* {@link Pose}.</p>
* Interface. The property values are integer IDs, uniquely identifying each action. <em>Read-only.</em></p>
* <p>These actions can be used as end points in the routes of a {@link MappingObject}. The data item routed to each action
* is either a number or a {@link Pose}.</p>
*
* <table>
* <thead>
@ -178,7 +178,7 @@ namespace controller {
* person view.</td></tr>
* <tr><td><code>CycleCamera</code></td><td>number</td><td>number</td><td>Cycle the camera view from first person, to
* third person, to full screen mirror, then back to first person and repeat.</td></tr>
* <tr><td><code>ContextMenu</code></td><td>number</td><td>number</td><td>Show / hide the tablet.</td></tr>
* <tr><td><code>ContextMenu</code></td><td>number</td><td>number</td><td>Show/hide the tablet.</td></tr>
* <tr><td><code>ToggleMute</code></td><td>number</td><td>number</td><td>Toggle the microphone mute.</td></tr>
* <tr><td><code>TogglePushToTalk</code></td><td>number</td><td>number</td><td>Toggle push to talk.</td></tr>
* <tr><td><code>ToggleOverlay</code></td><td>number</td><td>number</td><td>Toggle the display of overlays.</td></tr>
@ -238,71 +238,49 @@ namespace controller {
* <tr><td><code>LEFT_HAND</code></td><td>number</td><td>{@link Pose}</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use <code>LeftHand</code> instead.</span></td></tr>
* <tr><td><code>RIGHT_HAND</code></td><td>number</td><td>{@link Pose}</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>RightHand</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>RightHand</code> instead.</span></td></tr>
* <tr><td><code>BOOM_IN</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>BoomIn</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>BoomIn</code> instead.</span></td></tr>
* <tr><td><code>BOOM_OUT</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>BoomOut</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>BoomOut</code> instead.</span></td></tr>
* <tr><td><code>CONTEXT_MENU</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>ContextMenu</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>ContextMenu</code> instead.</span></td></tr>
* <tr><td><code>TOGGLE_MUTE</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>ToggleMute</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>ToggleMute</code> instead.</span></td></tr>
* <tr><td><code>TOGGLE_PUSHTOTALK</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>TogglePushToTalk</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>TogglePushToTalk</code> instead.</span></td></tr>
* <tr><td><code>SPRINT</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>Sprint</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>Sprint</code> instead.</span></td></tr>
* <tr><td><code>LONGITUDINAL_BACKWARD</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>Backward</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>Backward</code> instead.</span></td></tr>
* <tr><td><code>LONGITUDINAL_FORWARD</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>Forward</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>Forward</code> instead.</span></td></tr>
* <tr><td><code>LATERAL_LEFT</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>StrafeLeft</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>StrafeLeft</code> instead.</span></td></tr>
* <tr><td><code>LATERAL_RIGHT</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>StrafeRight</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>StrafeRight</code> instead.</span></td></tr>
* <tr><td><code>VERTICAL_UP</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>Up</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>Up</code> instead.</span></td></tr>
* <tr><td><code>VERTICAL_DOWN</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>Down</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>Down</code> instead.</span></td></tr>
* <tr><td><code>PITCH_DOWN</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>PitchDown</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>PitchDown</code> instead.</span></td></tr>
* <tr><td><code>PITCH_UP</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>PitchUp</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>PitchUp</code> instead.</span></td></tr>
* <tr><td><code>YAW_LEFT</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>YawLeft</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>YawLeft</code> instead.</span></td></tr>
* <tr><td><code>YAW_RIGHT</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>YawRight</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>YawRight</code> instead.</span></td></tr>
* <tr><td><code>LEFT_HAND_CLICK</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>LeftHandClick</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>LeftHandClick</code> instead.</span></td></tr>
* <tr><td><code>RIGHT_HAND_CLICK</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>RightHandClick</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>RightHandClick</code> instead.</span></td></tr>
* <tr><td><code>SHIFT</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>Shift</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>Shift</code> instead.</span></td></tr>
* <tr><td><code>ACTION1</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>PrimaryAction</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>PrimaryAction</code> instead.</span></td></tr>
* <tr><td><code>ACTION2</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
* action is deprecated and will be removed. Use
* <code>SecondaryAction</code> instead.</span></td></tr>
* action is deprecated and will be removed. Use <code>SecondaryAction</code> instead.</span></td></tr>
*
* <tr><td colSpan=4><strong>Deprecated Trackers</strong></td>
* <tr><td><code>TrackedObject00</code></td><td>number</td><td>{@link Pose}</td><td><span class="important">Deprecated:

View file

@ -54,10 +54,9 @@ enum Hand {
/**jsdoc
* <p>The <code>Controller.Hardware</code> object has properties representing standard and hardware-specific controller and
* computer outputs, plus predefined actions on Interface and the user's avatar. <em>Read-only.</em> The outputs can be mapped
* to actions or functions in a {@link RouteObject} mapping. Additionally, hardware-specific controller outputs can be mapped
* to standard controller outputs.
*
* computer outputs, plus predefined actions on Interface and the user's avatar. <em>Read-only.</em></p>
* <p>The outputs can be mapped to actions or functions in a {@link RouteObject} mapping. Additionally, hardware-specific
* controller outputs can be mapped to standard controller outputs.
* <p>Controllers typically implement a subset of the {@link Controller.Standard} controls, plus they may implement some extras.
* Some common controllers are included in the table. You can see the outputs provided by these and others by
* viewing their {@link Controller.MappingJSON|MappingJSON} files at

View file

@ -227,6 +227,7 @@ namespace controller {
}
QObject* ScriptingInterface::loadMapping(const QString& jsonUrl) {
// FIXME: Implement. https://highfidelity.manuscript.com/f/cases/14188/Implement-Controller-loadMappping
return nullptr;
}

View file

@ -73,7 +73,7 @@ namespace controller {
virtual ~ScriptingInterface() {};
/**jsdoc
* Get a list of all available actions.
* Gets a list of all available actions.
* @function Controller.getAllActions
* @returns {Action[]} All available actions.
* @deprecated This function is deprecated and will be removed. It no longer works.
@ -82,7 +82,7 @@ namespace controller {
Q_INVOKABLE QVector<Action> getAllActions();
/**jsdoc
* Get a list of all available inputs for a hardware device.
* Gets a list of all available inputs for a hardware device.
* @function Controller.getAvailableInputs
* @param {number} deviceID - Integer ID of the hardware device.
* @returns {NamedPair[]} All available inputs for the device.
@ -92,7 +92,7 @@ namespace controller {
Q_INVOKABLE QVector<Input::NamedPair> getAvailableInputs(unsigned int device);
/**jsdoc
* Find the name of a particular controller from its device ID.
* Finds the name of a particular controller from its device ID.
* @function Controller.getDeviceName
* @param {number} deviceID - The integer ID of the device.
* @returns {string} The name of the device if found, otherwise <code>"unknown"</code>.
@ -106,7 +106,7 @@ namespace controller {
Q_INVOKABLE QString getDeviceName(unsigned int device);
/**jsdoc
* Get the current value of an action.
* Gets the current value of an action.
* @function Controller.getActionValue
* @param {number} actionID - The integer ID of the action.
* @returns {number} The current value of the action.
@ -121,7 +121,7 @@ namespace controller {
Q_INVOKABLE float getActionValue(int action);
/**jsdoc
* Find the ID of a specific controller from its device name.
* Finds the ID of a specific controller from its device name.
* @function Controller.findDevice
* @param {string} deviceName - The name of the device to find.
* @returns {number} The integer ID of the device if available, otherwise <code>65535</code>.
@ -132,7 +132,7 @@ namespace controller {
Q_INVOKABLE int findDevice(QString name);
/**jsdoc
* Get the names of all currently available controller devices plus "Actions", "Application", and "Standard".
* Gets the names of all currently available controller devices plus "Actions", "Application", and "Standard".
* @function Controller.getDeviceNames
* @returns {string[]} An array of device names.
* @example <caption>Get the names of all currently available controller devices.</caption>
@ -143,7 +143,7 @@ namespace controller {
Q_INVOKABLE QVector<QString> getDeviceNames();
/**jsdoc
* Find the ID of an action from its name.
* Finds the ID of an action from its name.
* @function Controller.findAction
* @param {string} actionName - The name of the action: one of the {@link Controller.Actions} property names.
* @returns {number} The integer ID of the action if found, otherwise <code>4095</code>. Note that this value is not
@ -156,7 +156,7 @@ namespace controller {
Q_INVOKABLE int findAction(QString actionName);
/**jsdoc
* Get the names of all actions available as properties of {@link Controller.Actions}.
* Gets the names of all actions available as properties of {@link Controller.Actions}.
* @function Controller.getActionNames
* @returns {string[]} An array of action names.
* @example <caption>Get the names of all actions.</caption>
@ -167,7 +167,7 @@ namespace controller {
Q_INVOKABLE QVector<QString> getActionNames() const;
/**jsdoc
* Get the value of a controller button or axis output. Note: Also gets the value of a controller axis output.
* Gets the value of a controller button or axis output. Note: Also gets the value of a controller axis output.
* @function Controller.getValue
* @param {number} source - The {@link Controller.Standard} or {@link Controller.Hardware} item.
* @returns {number} The current value of the controller item output if <code>source</code> is valid, otherwise
@ -186,7 +186,7 @@ namespace controller {
Q_INVOKABLE float getValue(const int& source) const;
/**jsdoc
* Get the value of a controller axis output. Note: Also gets the value of a controller button output.
* Gets the value of a controller axis output. Note: Also gets the value of a controller button output.
* @function Controller.getAxisValue
* @param {number} source - The {@link Controller.Standard} or {@link Controller.Hardware} item.
* @returns {number} The current value of the controller item output if <code>source</code> is valid, otherwise
@ -196,7 +196,7 @@ namespace controller {
Q_INVOKABLE float getAxisValue(int source) const;
/**jsdoc
* Get the value of a controller pose output.
* Gets the value of a controller pose output.
* @function Controller.getPoseValue
* @param {number} source - The {@link Controller.Standard} or {@link Controller.Hardware} pose output.
* @returns {Pose} The current value of the controller pose output if <code>source</code> is a pose output, otherwise
@ -210,9 +210,9 @@ namespace controller {
/**jsdoc
* Triggers a haptic pulse on connected and enabled devices that have the capability.
* @function Controller.triggerHapticPulse
* @param {number} strength - The strength of the haptic pulse, <code>0.0</code> &ndash; <code>1.0</code>.
* @param {number} strength - The strength of the haptic pulse, range <code>0.0</code> &ndash; <code>1.0</code>.
* @param {number} duration - The duration of the haptic pulse, in milliseconds.
* @param {Controller.Hand} hand=2 - The hand or hands to trigger the haptic pulse on.
* @param {Controller.Hand} [hand=2] - The hand or hands to trigger the haptic pulse on.
* @example <caption>Trigger a haptic pulse on the right hand.</caption>
* var HAPTIC_STRENGTH = 0.5;
* var HAPTIC_DURATION = 10;
@ -224,8 +224,8 @@ namespace controller {
/**jsdoc
* Triggers a 250ms haptic pulse on connected and enabled devices that have the capability.
* @function Controller.triggerShortHapticPulse
* @param {number} strength - The strength of the haptic pulse, <code>0.0</code> &ndash; <code>1.0</code>.
* @param {Controller.Hand} hand=2 - The hand or hands to trigger the haptic pulse on.
* @param {number} strength - The strength of the haptic pulse, range <code>0.0</code> &ndash; <code>1.0</code>.
* @param {Controller.Hand} [hand=2] - The hand or hands to trigger the haptic pulse on.
*/
Q_INVOKABLE bool triggerShortHapticPulse(float strength, controller::Hand hand = BOTH) const;
@ -233,9 +233,9 @@ namespace controller {
* Triggers a haptic pulse on a particular device if connected and enabled and it has the capability.
* @function Controller.triggerHapticPulseOnDevice
* @param {number} deviceID - The ID of the device to trigger the haptic pulse on.
* @param {number} strength - The strength of the haptic pulse, <code>0.0</code> &ndash; <code>1.0</code>.
* @param {number} strength - The strength of the haptic pulse, range <code>0.0</code> &ndash; <code>1.0</code>.
* @param {number} duration - The duration of the haptic pulse, in milliseconds.
* @param {Controller.Hand} hand=2 - The hand or hands to trigger the haptic pulse on.
* @param {Controller.Hand} [hand=2] - The hand or hands to trigger the haptic pulse on.
* @example <caption>Trigger a haptic pulse on an Oculus Touch controller.</caption>
* var HAPTIC_STRENGTH = 0.5;
* var deviceID = Controller.findDevice("OculusTouch");
@ -250,19 +250,19 @@ namespace controller {
* Triggers a 250ms haptic pulse on a particular device if connected and enabled and it has the capability.
* @function Controller.triggerShortHapticPulseOnDevice
* @param {number} deviceID - The ID of the device to trigger the haptic pulse on.
* @param {number} strength - The strength of the haptic pulse, <code>0.0</code> &ndash; <code>1.0</code>.
* @param {Controller.Hand} hand=2 - The hand or hands to trigger the haptic pulse on.
* @param {number} strength - The strength of the haptic pulse, range <code>0.0</code> &ndash; <code>1.0</code>.
* @param {Controller.Hand} [hand=2] - The hand or hands to trigger the haptic pulse on.
*/
Q_INVOKABLE bool triggerShortHapticPulseOnDevice(unsigned int device, float strength, controller::Hand hand = BOTH)
const;
/**jsdoc
* Create a new controller mapping. Routes can then be added to the mapping using {@link MappingObject} methods and
* Creates a new controller mapping. Routes can then be added to the mapping using {@link MappingObject} methods and
* routed to <code>Standard</code> controls, <code>Actions</code>, or script functions using {@link RouteObject}
* methods. The mapping can then be enabled using {@link Controller.enableMapping|enableMapping} for it to take effect.
* @function Controller.newMapping
* @param {string} mappingName=Uuid.generate() - A unique name for the mapping. If not specified a new UUID generated
* @param {string} [mappingName=Uuid.generate()] - A unique name for the mapping. If not specified a new UUID generated
* by {@link Uuid.generate} is used.
* @returns {MappingObject} A controller mapping object.
* @example <caption>Create a simple mapping that makes the right trigger move your avatar up.</caption>
@ -279,22 +279,22 @@ namespace controller {
Q_INVOKABLE QObject* newMapping(const QString& mappingName = QUuid::createUuid().toString());
/**jsdoc
* Enable or disable a controller mapping. When enabled, the routes in the mapping have effect.
* Enables or disables a controller mapping. When enabled, the routes in the mapping have effect.
* @function Controller.enableMapping
* @param {string} mappingName - The name of the mapping.
* @param {boolean} enable=true - If <code>true</code> then the mapping is enabled, otherwise it is disabled.
* @param {boolean} [[enable=true] - If <code>true</code> then the mapping is enabled, otherwise it is disabled.
*/
Q_INVOKABLE void enableMapping(const QString& mappingName, bool enable = true);
/**jsdoc
* Disable a controller mapping. When disabled, the routes in the mapping have no effect.
* Disables a controller mapping. When disabled, the routes in the mapping have no effect.
* @function Controller.disableMapping
* @param {string} mappingName - The name of the mapping.
*/
Q_INVOKABLE void disableMapping(const QString& mappingName) { enableMapping(mappingName, false); }
/**jsdoc
* Create a new controller mapping from a {@link Controller.MappingJSON|MappingJSON} string. Use
* Creates a new controller mapping from a {@link Controller.MappingJSON|MappingJSON} string. Use
* {@link Controller.enableMapping|enableMapping} to enable the mapping for it to take effect.
* @function Controller.parseMapping
* @param {string} jsonString - A JSON string of the {@link Controller.MappingJSON|MappingJSON}.
@ -317,19 +317,19 @@ namespace controller {
Q_INVOKABLE QObject* parseMapping(const QString& json);
/**jsdoc
* Create a new controller mapping from a {@link Controller.MappingJSON|MappingJSON} JSON file at a URL. Use
* Creates a new controller mapping from a {@link Controller.MappingJSON|MappingJSON} JSON file at a URL. Use
* {@link Controller.enableMapping|enableMapping} to enable the mapping for it to take effect.
* <p><strong>Warning:</strong> This function is not yet implemented; it doesn't load a mapping and just returns
* <code>null</code>.
* @function Controller.loadMapping
* @param {string} jsonURL - The URL the {@link Controller.MappingJSON|MappingJSON} JSON file.
* @returns {MappingObject} A controller mapping object.
* @todo <em>Implement this function. It currently does not load the mapping from the file; it just returns
* <code>null</code>.</em>
*/
Q_INVOKABLE QObject* loadMapping(const QString& jsonUrl);
/**jsdoc
* Get the {@link Controller.Hardware} property tree. Calling this function is the same as using the {@link Controller}
* Gets the {@link Controller.Hardware} property tree. Calling this function is the same as using the {@link Controller}
* property, <code>Controller.Hardware</code>.
* @function Controller.getHardware
* @returns {Controller.Hardware} The {@link Controller.Hardware} property tree.
@ -337,7 +337,7 @@ namespace controller {
Q_INVOKABLE const QVariantMap getHardware() { return _hardware; }
/**jsdoc
* Get the {@link Controller.Actions} property tree. Calling this function is the same as using the {@link Controller}
* Gets the {@link Controller.Actions} property tree. Calling this function is the same as using the {@link Controller}
* property, <code>Controller.Actions</code>.
* @function Controller.getActions
* @returns {Controller.Actions} The {@link Controller.Actions} property tree.
@ -345,7 +345,7 @@ namespace controller {
Q_INVOKABLE const QVariantMap getActions() { return _actions; } //undefined
/**jsdoc
* Get the {@link Controller.Standard} property tree. Calling this function is the same as using the {@link Controller}
* Gets the {@link Controller.Standard} property tree. Calling this function is the same as using the {@link Controller}
* property, <code>Controller.Standard</code>.
* @function Controller.getStandard
* @returns {Controller.Standard} The {@link Controller.Standard} property tree.
@ -354,7 +354,7 @@ namespace controller {
/**jsdoc
* Start making a recording of currently active controllers.
* Starts making a recording of currently active controllers.
* @function Controller.startInputRecording
* @example <caption>Make a controller recording.</caption>
* // Delay start of recording for 2s.
@ -374,13 +374,13 @@ namespace controller {
Q_INVOKABLE void startInputRecording();
/**jsdoc
* Stop making a recording started by {@link Controller.startInputRecording|startInputRecording}.
* Stops making a recording started by {@link Controller.startInputRecording|startInputRecording}.
* @function Controller.stopInputRecording
*/
Q_INVOKABLE void stopInputRecording();
/**jsdoc
* Play back the current recording from the beginning. The current recording may have been recorded by
* Plays back the current recording from the beginning. The current recording may have been recorded by
* {@link Controller.startInputRecording|startInputRecording} and
* {@link Controller.stopInputRecording|stopInputRecording}, or loaded by
* {@link Controller.loadInputRecording|loadInputRecording}. Playback repeats in a loop until
@ -403,13 +403,13 @@ namespace controller {
Q_INVOKABLE void startInputPlayback();
/**jsdoc
* Stop play back of a recording started by {@link Controller.startInputPlayback|startInputPlayback}.
* Stops play back of a recording started by {@link Controller.startInputPlayback|startInputPlayback}.
* @function Controller.stopInputPlayback
*/
Q_INVOKABLE void stopInputPlayback();
/**jsdoc
* Save the current recording to a file. The current recording may have been recorded by
* Saves the current recording to a file. The current recording may have been recorded by
* {@link Controller.startInputRecording|startInputRecording} and
* {@link Controller.stopInputRecording|stopInputRecording}, or loaded by
* {@link Controller.loadInputRecording|loadInputRecording}. It is saved in the directory returned by
@ -419,24 +419,26 @@ namespace controller {
Q_INVOKABLE void saveInputRecording();
/**jsdoc
* Load an input recording, ready for play back.
* Loads an input recording, ready for play back.
* @function Controller.loadInputRecording
* @param {string} file - The path to the recording file, prefixed by <code>"file:///"</code>.
*/
Q_INVOKABLE void loadInputRecording(const QString& file);
/**jsdoc
* Get the directory in which input recordings are saved.
* Gets the directory in which input recordings are saved.
* @function Controller.getInputRecorderSaveDirectory
* @returns {string} The directory in which input recordings are saved.
*/
Q_INVOKABLE QString getInputRecorderSaveDirectory();
/**jsdoc
* Get all the active and enabled (running) input devices
* @function Controller.getRunningInputDevices
* @returns {string[]} An array of strings with the names
*/
* Gets the names of all the active and running (enabled) input devices.
* @function Controller.getRunningInputDevices
* @returns {string[]} The list of current active and running input devices.
* @example <caption>List all active and running input devices.</caption>
* print("Running devices: " + JSON.stringify(Controller.getRunningInputDeviceNames()));
*/
Q_INVOKABLE QStringList getRunningInputDeviceNames();
bool isMouseCaptured() const { return _mouseCaptured; }
@ -447,7 +449,7 @@ namespace controller {
public slots:
/**jsdoc
* Disable processing of mouse "move", "press", "double-press", and "release" events into
* Disables processing of mouse "move", "press", "double-press", and "release" events into
* {@link Controller.Hardware|Controller.Hardware.Keyboard} outputs.
* @function Controller.captureMouseEvents
* @example <caption>Disable Controller.Hardware.Keyboard mouse events for a short period.</caption>
@ -475,7 +477,7 @@ namespace controller {
virtual void captureMouseEvents() { _mouseCaptured = true; }
/**jsdoc
* Enable processing of mouse "move", "press", "double-press", and "release" events into
* Enables processing of mouse "move", "press", "double-press", and "release" events into
* {@link Controller.Hardware-Keyboard|Controller.Hardware.Keyboard} outputs that were disabled using
* {@link Controller.captureMouseEvents|captureMouseEvents}.
* @function Controller.releaseMouseEvents
@ -484,7 +486,7 @@ namespace controller {
/**jsdoc
* Disable processing of touch "begin", "update", and "end" events into
* Disables processing of touch "begin", "update", and "end" events into
* {@link Controller.Hardware|Controller.Hardware.Keyboard},
* {@link Controller.Hardware|Controller.Hardware.Touchscreen}, and
* {@link Controller.Hardware|Controller.Hardware.TouchscreenVirtualPad} outputs.
@ -493,7 +495,7 @@ namespace controller {
virtual void captureTouchEvents() { _touchCaptured = true; }
/**jsdoc
* Enable processing of touch "begin", "update", and "end" events into
* Enables processing of touch "begin", "update", and "end" events into
* {@link Controller.Hardware|Controller.Hardware.Keyboard},
* {@link Controller.Hardware|Controller.Hardware.Touchscreen}, and
* {@link Controller.Hardware|Controller.Hardware.TouchscreenVirtualPad} outputs that were disabled using
@ -504,14 +506,14 @@ namespace controller {
/**jsdoc
* Disable processing of mouse wheel rotation events into {@link Controller.Hardware|Controller.Hardware.Keyboard}
* Disables processing of mouse wheel rotation events into {@link Controller.Hardware|Controller.Hardware.Keyboard}
* outputs.
* @function Controller.captureWheelEvents
*/
virtual void captureWheelEvents() { _wheelCaptured = true; }
/**jsdoc
* Enable processing of mouse wheel rotation events into {@link Controller.Hardware|Controller.Hardware.Keyboard}
* Enables processing of mouse wheel rotation events into {@link Controller.Hardware|Controller.Hardware.Keyboard}
* outputs that wer disabled using {@link Controller.captureWheelEvents|captureWheelEvents}.
* @function Controller.releaseWheelEvents
*/
@ -519,7 +521,7 @@ namespace controller {
/**jsdoc
* Disable translating and rotating the user's avatar in response to keyboard and controller controls.
* Disables translating and rotating the user's avatar in response to keyboard and controller controls.
* @function Controller.captureActionEvents
* @example <caption>Disable avatar translation and rotation for a short period.</caption>
* Script.setTimeout(function () {
@ -533,12 +535,19 @@ namespace controller {
virtual void captureActionEvents() { _actionsCaptured = true; }
/**jsdoc
* Enable translating and rotating the user's avatar in response to keyboard and controller controls that were disabled
* Enables translating and rotating the user's avatar in response to keyboard and controller controls that were disabled
* using {@link Controller.captureActionEvents|captureActionEvents}.
* @function Controller.releaseActionEvents
*/
virtual void releaseActionEvents() { _actionsCaptured = false; }
/**jsdoc
* @function Controller.updateRunningInputDevices
* @param {string} deviceName - Device name.
* @param {boolean} isRunning - Is running.
* @param {string[]} runningDevices - Running devices.
* @deprecated This function is deprecated and will be removed.
*/
void updateRunningInputDevices(const QString& deviceName, bool isRunning, const QStringList& runningDevices);
signals:
@ -593,7 +602,7 @@ namespace controller {
/**jsdoc
* Triggered when a device is registered or unregistered by a plugin. Not all plugins generate
* <code>hardwareChanged</code> events: for example connecting or disconnecting a mouse will not generate an event but
* <code>hardwareChanged</code> events: for example, connecting or disconnecting a mouse will not generate an event but
* connecting or disconnecting an Xbox controller will.
* @function Controller.hardwareChanged
* @returns {Signal}
@ -601,13 +610,13 @@ namespace controller {
void hardwareChanged();
/**jsdoc
* Triggered when a device is enabled/disabled
* Enabling/Disabling Leapmotion on settings/controls will trigger this signal.
* @function Controller.deviceRunningChanged
* @param {string} deviceName - The name of the device that is getting enabled/disabled
* @param {boolean} isEnabled - Return if the device is enabled.
* @returns {Signal}
*/
* Triggered when an input device starts or stops being active and running (enabled). For example, enabling or
* disabling the LeapMotion in Settings &gt; Controls &gt; Calibration will trigger this signal.
* @function Controller.inputDeviceRunningChanged
* @param {string} deviceName - The name of the device.
* @param {boolean} isRunning - <code>true</code> if the device is active and running, <code>false</code> if it isn't.
* @returns {Signal}
*/
void inputDeviceRunningChanged(QString deviceName, bool isRunning);

View file

@ -30,17 +30,16 @@ void StandardController::focusOutEvent() {
/**jsdoc
* <p>The <code>Controller.Standard</code> object has properties representing standard controller outputs. Those for physical
* controllers are based on the XBox controller, with aliases for PlayStation. The property values are integer IDs, uniquely
* identifying each output. <em>Read-only.</em> These can be mapped to actions or functions in a {@link RouteObject}
* mapping.</p>
*
* <p>The data value provided by each control is either a number or a {@link Pose}. Numbers are typically normalized to
* <code>0.0</code> or <code>1.0</code> for button states, the range <code>0.0 &ndash; 1.0</code> for unidirectional scales,
* and the range <code>-1.0 &ndash; 1.0</code> for bidirectional scales.</p>
*
* <p>Each hardware device has a mapping from its outputs to <code>Controller.Standard</code> items, specified in a JSON file.
* For example, <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/leapmotion.json">
* leapmotion.json</a> and
* <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/vive.json">vive.json</a>.</p>
* identifying each output. <em>Read-only.</em></p>
* <p>These outputs can be mapped to actions or functions in a {@link RouteObject} mapping. The data value provided by each
* control is either a number or a {@link Pose}. Numbers are typically normalized to <code>0.0</code> or <code>1.0</code> for
* button states, the range <code>0.0</code> &ndash; </code>1.0</code> for unidirectional scales, and the range
* <code>-1.0</code> &ndash; <code>1.0</code> for bidirectional scales.</p>
* <p>Each hardware device has a mapping from its outputs to a subset of <code>Controller.Standard</code> items, specified in a
* JSON file. For example,
* <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/vive.json">vive.json</a>
* and <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/leapmotion.json">
* leapmotion.json</a>.</p>
*
* <table>
* <thead>
@ -119,12 +118,12 @@ void StandardController::focusOutEvent() {
* button.</td></tr>
* <tr><td><code>RightThumbUp</code></td><td>number</td><td>number</td><td>Right thumb not touching primary or secondary
* thumb buttons.</td></tr>
* <tr><td><code>LeftPrimaryIndex</code></td><td>number</td><td>number</td><td>Left primary index control pressed.
* <strong>To Do:</strong> <em>Implement this for current controllers.</em></td></tr>
* <tr><td><code>LeftPrimaryIndex</code></td><td>number</td><td>number</td><td>Left primary index control
* pressed.</em></td></tr>
* <tr><td><code>LeftSecondaryIndex</code></td><td>number</td><td>number</td><td>Left secondary index control pressed.
* </td></tr>
* <tr><td><code>RightPrimaryIndex</code></td><td>number</td><td>number</td><td>Right primary index control pressed.
* <strong>To Do:</strong> <em>Implement this for current controllers.</em></td></tr>
* </td></tr>
* <tr><td><code>RightSecondaryIndex</code></td><td>number</td><td>number</td><td>Right secondary index control pressed.
* </td></tr>
* <tr><td><code>LeftPrimaryIndexTouch</code></td><td>number</td><td>number</td><td>Left index finger is touching primary

View file

@ -84,12 +84,12 @@ class UserInputMapper;
/**jsdoc
* A route in a {@link Controller.MappingJSON}.
* @typedef {object} Controller.MappingJSONRoute
* @property {string|Controller.MappingJSONAxis} from - The name of a {@link Controller.Hardware} property name or an axis
* made from them. If a property name, the leading <code>"Controller.Hardware."</code> can be omitted.
* @property {boolean} [peek=false] - If <codd>true</code> then peeking is enabled per {@link RouteObject#peek}.
* @property {boolean} [debug=false] - If <code>true</code> then debug is enabled per {@link RouteObject#debug}.
* @property {string|Controller.MappingJSONAxis} from - The name of a {@link Controller.Hardware} property or an axis made from
* them. If a property name, the leading <code>"Controller.Hardware."</code> can be omitted.
* @property {boolean} [peek=false] - If <codd>true</code>, then peeking is enabled per {@link RouteObject#peek}.
* @property {boolean} [debug=false] - If <code>true</code>, then debug is enabled per {@link RouteObject#debug}.
* @property {string|string[]} [when=[]] - One or more numeric {@link Controller.Hardware} property names which are evaluated
* as booleans and ANDed together. Prepend with a <code>!</code> to use the logical NOT of the property value. The leading
* as booleans and ANDed together. Prepend a property name with a <code>!</code> to do a logical NOT. The leading
* <code>"Controller.Hardware."</code> can be omitted from the property names.
* @property {Controller.MappingJSONFilter|Controller.MappingJSONFilter[]} [filters=[]] - One or more filters in the route.
* @property {string} to - The name of a {@link Controller.Actions} or {@link Controller.Standard} property. The leading
@ -134,7 +134,7 @@ public:
: _parent(parent), _mapping(mapping) { }
/**jsdoc
* Create a new {@link RouteObject} from a controller output, ready to be mapped to a standard control, action, or
* Creates a new {@link RouteObject} from a controller output, ready to be mapped to a standard control, action, or
* function.<br />
* This is a QML-specific version of {@link MappingObject#from|from}: use this version in QML files.
* @function MappingObject#fromQml
@ -145,7 +145,7 @@ public:
Q_INVOKABLE QObject* fromQml(const QJSValue& source);
/**jsdoc
* Create a new {@link RouteObject} from two numeric {@link Controller.Hardware} outputs, one applied in the negative
* Creates a new {@link RouteObject} from two numeric {@link Controller.Hardware} outputs, one applied in the negative
* direction and the other in the positive direction, ready to be mapped to a standard control, action, or function.<br />
* This is a QML-specific version of {@link MappingObject#makeAxis|makeAxis}: use this version in QML files.
* @function MappingObject#makeAxisQml
@ -157,7 +157,7 @@ public:
Q_INVOKABLE QObject* makeAxisQml(const QJSValue& source1, const QJSValue& source2);
/**jsdoc
* Create a new {@link RouteObject} from a controller output, ready to be mapped to a standard control, action, or
* Creates a new {@link RouteObject} from a controller output, ready to be mapped to a standard control, action, or
* function.
* @function MappingObject#from
* @param {Controller.Standard|Controller.Hardware|function} source - The controller output or function that is the source
@ -167,7 +167,7 @@ public:
Q_INVOKABLE QObject* from(const QScriptValue& source);
/**jsdoc
* Create a new {@link RouteObject} from two numeric {@link Controller.Hardware} outputs, one applied in the negative
* Creates a new {@link RouteObject} from two numeric {@link Controller.Hardware} outputs, one applied in the negative
* direction and the other in the positive direction, ready to be mapped to a standard control, action, or function.
* @function MappingObject#makeAxis
* @param {Controller.Hardware} source1 - The first, negative-direction controller output.
@ -189,7 +189,7 @@ public:
Q_INVOKABLE QObject* makeAxis(const QScriptValue& source1, const QScriptValue& source2);
/**jsdoc
* Enable or disable the mapping. When enabled, the routes in the mapping take effect.<br />
* Enables or disables the mapping. When enabled, the routes in the mapping take effect.<br />
* Synonymous with {@link Controller.enableMapping}.
* @function MappingObject#enable
* @param {boolean} enable=true - If <code>true</code> then the mapping is enabled, otherwise it is disabled.
@ -198,7 +198,7 @@ public:
Q_INVOKABLE QObject* enable(bool enable = true);
/**jsdoc
* Disable the mapping. When disabled, the routes in the mapping have no effect.<br />
* Disables the mapping. When disabled, the routes in the mapping have no effect.<br />
* Synonymous with {@link Controller.disableMapping}.
* @function MappingObject#disable
* @returns {MappingObject} The mapping object, so that further routes can be added.

View file

@ -66,6 +66,8 @@ QObject* RouteBuilderProxy::peek(bool enable) {
}
QObject* RouteBuilderProxy::when(const QScriptValue& expression) {
// FIXME: Support "!" conditional in simple expression and array expression.
// Note that "!" is supported when parsing a JSON file, in UserInputMapper::parseConditional().
auto newConditional = _parent.conditionalFor(expression);
if (_route->conditional) {
_route->conditional = ConditionalPointer(new AndConditional(_route->conditional, newConditional));

View file

@ -51,7 +51,7 @@ class RouteBuilderProxy : public QObject {
: _parent(parent), _mapping(mapping), _route(route) { }
/**jsdoc
* Terminate the route with a standard control, an action, or a script function. The output value from the route is
* Terminates the route with a standard control, an action, or a script function. The output value from the route is
* sent to the specified destination.<br />
* This is a QML-specific version of {@link MappingObject#to|to}: use this version in QML files.
* @function RouteObject#toQml
@ -62,7 +62,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE void toQml(const QJSValue& destination);
/**jsdoc
* Process the route only if a condition is satisfied. The condition is evaluated before the route input is read, and
* Processes the route only if a condition is satisfied. The condition is evaluated before the route input is read, and
* the input is read only if the condition is <code>true</code>. Thus, if the condition is not met then subsequent
* routes using the same input are processed.<br />
* This is a QML-specific version of {@link MappingObject#to|to}: use this version in QML files.
@ -81,7 +81,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* whenQml(const QJSValue& expression);
/**jsdoc
* Terminate the route with a standard control, an action, or a script function. The output value from the route is
* Terminates the route with a standard control, an action, or a script function. The output value from the route is
* sent to the specified destination.
* @function RouteObject#to
* @param {Controller.Standard|Controller.Actions|function} destination - The standard control, action, or JavaScript
@ -117,7 +117,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE void to(const QScriptValue& destination);
/**jsdoc
* Enable and disabling writing debug information for a route to the program log.
* Enables or disables writing debug information for a route to the program log.
* @function RouteObject#debug
* @param {boolean} [enable=true] - If <code>true</code> then writing debug information is enabled for the route,
* otherwise it is disabled.
@ -147,7 +147,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* debug(bool enable = true);
/**jsdoc
* Process the route without marking the controller output as having been read, so that other routes from the same
* Processes the route without marking the controller output as having been read, so that other routes from the same
* controller output can also process.
* @function RouteObject#peek
* @param {boolean} [enable=true] - If <code>true</code> then the route is processed without marking the route's
@ -157,7 +157,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* peek(bool enable = true);
/**jsdoc
* Process the route only if a condition is satisfied. The condition is evaluated before the route input is read, and
* Processes the route only if a condition is satisfied. The condition is evaluated before the route input is read, and
* the input is read only if the condition is <code>true</code>. Thus, if the condition is not met then subsequent
* routes using the same input are processed.
* @function RouteObject#when
@ -170,6 +170,8 @@ class RouteBuilderProxy : public QObject {
* definition.</li>
* </ul>
* <p>If an array of conditions is provided, their values are ANDed together.</p>
* <p><strong>Warning:</strong> The use of <code>!</code> is not currently supported in JavaScript <code>.when()</code>
* calls.</p>
* @returns {RouteObject} The <code>RouteObject</code> with the condition added.
* @example <caption>Process the right trigger differently in HMD and desktop modes.</caption>
* var MAPPING_NAME = "com.highfidelity.controllers.example.newMapping";
@ -193,7 +195,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* when(const QScriptValue& expression);
/**jsdoc
* Filter numeric route values to lie between two values; values outside this range are not passed on through the
* Filters numeric route values to lie between two values; values outside this range are not passed on through the
* route.
* @function RouteObject#clamp
* @param {number} min - The minimum value to pass through.
@ -214,7 +216,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* clamp(float min, float max);
/**jsdoc
* Filter numeric route values such that they are rounded to <code>0</code> or <code>1</code> without output values
* Filters numeric route values such that they are rounded to <code>0</code> or <code>1</code> without output values
* flickering when the input value hovers around <code>0.5</code>. For example, this enables you to use an analog input
* as if it were a toggle.
* @function RouteObject#hysteresis
@ -239,7 +241,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* hysteresis(float min, float max);
/**jsdoc
* Filter numeric route values to send at a specified interval.
* Filters numeric route values to send at a specified interval.
* @function RouteObject#pulse
* @param {number} interval - The interval between sending values, in seconds.
* @returns {RouteObject} The <code>RouteObject</code> with the filter applied.
@ -258,7 +260,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* pulse(float interval);
/**jsdoc
* Filter numeric and {@link Pose} route values to be scaled by a constant amount.
* Filters numeric and {@link Pose} route values to be scaled by a constant amount.
* @function RouteObject#scale
* @param {number} multiplier - The scale to multiply the value by.
* @returns {RouteObject} The <code>RouteObject</code> with the filter applied.
@ -280,7 +282,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* scale(float multiplier);
/**jsdoc
* Filter numeric and {@link Pose} route values to have the opposite sign, e.g., <code>0.5</code> is changed to
* Filters numeric and {@link Pose} route values to have the opposite sign, e.g., <code>0.5</code> is changed to
* <code>-0.5</code>.
* @function RouteObject#invert
* @returns {RouteObject} The <code>RouteObject</code> with the filter applied.
@ -302,7 +304,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* invert();
/**jsdoc
* Filter numeric route values such that they're sent only when the input value is outside a dead-zone. When the input
* Filters numeric route values such that they're sent only when the input value is outside a dead-zone. When the input
* passes the dead-zone value, output is sent starting at <code>0.0</code> and catching up with the input value. As the
* input returns toward the dead-zone value, output values reduce to <code>0.0</code> at the dead-zone value.
* @function RouteObject#deadZone
@ -324,7 +326,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* deadZone(float min);
/**jsdoc
* Filter numeric route values such that they are rounded to <code>-1</code>, <code>0</code>, or <code>1</code>.
* Filters numeric route values such that they are rounded to <code>-1</code>, <code>0</code>, or <code>1</code>.
* For example, this enables you to use an analog input as if it were a toggle or, in the case of a bidirectional axis,
* a tri-state switch.
* @function RouteObject#constrainToInteger
@ -345,7 +347,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* constrainToInteger();
/**jsdoc
* Filter numeric route values such that they are rounded to <code>0</code> or <code>1</code>. For example, this
* Filters numeric route values such that they are rounded to <code>0</code> or <code>1</code>. For example, this
* enables you to use an analog input as if it were a toggle.
* @function RouteObject#constrainToPositiveInteger
* @returns {RouteObject} The <code>RouteObject</code> with the filter applied.
@ -364,7 +366,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* constrainToPositiveInteger();
/**jsdoc
* Filter {@link Pose} route values to have a pre-translation applied.
* Filters {@link Pose} route values to have a pre-translation applied.
* @function RouteObject#translate
* @param {Vec3} translate - The pre-translation to add to the pose.
* @returns {RouteObject} The <code>RouteObject</code> with the pre-translation applied.
@ -373,7 +375,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* translate(glm::vec3 translate);
/**jsdoc
* Filter {@link Pose} route values to have a pre-transform applied.
* Filters {@link Pose} route values to have a pre-transform applied.
* @function RouteObject#transform
* @param {Mat4} transform - The pre-transform to apply.
* @returns {RouteObject} The <code>RouteObject</code> with the pre-transform applied.
@ -382,7 +384,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* transform(glm::mat4 transform);
/**jsdoc
* Filter {@link Pose} route values to have a post-transform applied.
* Filters {@link Pose} route values to have a post-transform applied.
* @function RouteObject#postTransform
* @param {Mat4} transform - The post-transform to apply.
* @returns {RouteObject} The <code>RouteObject</code> with the post-transform applied.
@ -391,7 +393,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* postTransform(glm::mat4 transform);
/**jsdoc
* Filter {@link Pose} route values to have a pre-rotation applied.
* Filters {@link Pose} route values to have a pre-rotation applied.
* @function RouteObject#rotate
* @param {Quat} rotation - The pre-rotation to add to the pose.
* @returns {RouteObject} The <code>RouteObject</code> with the pre-rotation applied.
@ -400,7 +402,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* rotate(glm::quat rotation);
/**jsdoc
* Filter {@link Pose} route values to be smoothed by a low velocity filter. The filter's rotation and translation
* Filters {@link Pose} route values to be smoothed by a low velocity filter. The filter's rotation and translation
* values are calculated as: <code>(1 - f) * currentValue + f * previousValue</code> where
* <code>f = currentVelocity / filterConstant</code>. At low velocities, the filter value is largely the previous
* value; at high velocities the value is wholly the current controller value.
@ -415,7 +417,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* lowVelocity(float rotationConstant, float translationConstant);
/**jsdoc
* Filter {@link Pose} route values to be smoothed by an exponential decay filter. The filter's rotation and
* Filters {@link Pose} route values to be smoothed by an exponential decay filter. The filter's rotation and
* translation values are calculated as: <code>filterConstant * currentValue + (1 - filterConstant) *
* previousValue</code>. Values near 1 are less smooth with lower latency; values near 0 are more smooth with higher
* latency.
@ -428,7 +430,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* exponentialSmoothing(float rotationConstant, float translationConstant);
/**jsdoc
* Filter numeric route values such that a value of <code>0.0</code> is changed to <code>1.0</code>, and other values
* Filters numeric route values such that a value of <code>0.0</code> is changed to <code>1.0</code>, and other values
* are changed to <code>0.0</code>.
* @function RouteObject#logicalNot
* @returns {RouteObject} The <code>RouteObject</code> with the filter applied.

View file

@ -205,8 +205,11 @@ void EntityTreeRenderer::stopDomainAndNonOwnedEntities() {
foreach (const EntityItemID& entityID, entitiesWithEntityScripts) {
EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID);
if (entityItem) {
if (entityItem && !entityItem->getScript().isEmpty()) {
if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) {
if (entityItem->contains(_avatarPosition)) {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
}
_entitiesScriptEngine->unloadEntityScript(entityID, true);
}
}
@ -534,7 +537,7 @@ void EntityTreeRenderer::handleSpaceUpdate(std::pair<int32_t, glm::vec4> proxyUp
_spaceUpdates.emplace_back(proxyUpdate.first, proxyUpdate.second);
}
bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityItemID>* entitiesContainingAvatar) {
bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar) {
bool didUpdate = false;
float radius = 0.01f; // for now, assume 0.01 meter radius, because we actually check the point inside later
QVector<QUuid> entityIDs;
@ -580,9 +583,7 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityIt
}
if ((!hasScript && isZone) || scriptHasLoaded) {
if (entitiesContainingAvatar) {
*entitiesContainingAvatar << entity->getEntityItemID();
}
entitiesContainingAvatar << entity->getEntityItemID();
}
}
}
@ -616,36 +617,36 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
auto movedEnough = glm::distance(avatarPosition, _avatarPosition) > ZONE_CHECK_DISTANCE;
auto enoughTimeElapsed = (now - _lastZoneCheck) > ZONE_CHECK_INTERVAL;
if (movedEnough || enoughTimeElapsed) {
if (_forceRecheckEntities || movedEnough || enoughTimeElapsed) {
_avatarPosition = avatarPosition;
_lastZoneCheck = now;
QVector<EntityItemID> entitiesContainingAvatar;
didUpdate = findBestZoneAndMaybeContainingEntities(&entitiesContainingAvatar);
_forceRecheckEntities = false;
QSet<EntityItemID> entitiesContainingAvatar;
didUpdate = findBestZoneAndMaybeContainingEntities(entitiesContainingAvatar);
// Note: at this point we don't need to worry about the tree being locked, because we only deal with
// EntityItemIDs from here. The callEntityScriptMethod() method is robust against attempting to call scripts
// for entity IDs that no longer exist.
// for all of our previous containing entities, if they are no longer containing then send them a leave event
foreach(const EntityItemID& entityID, _currentEntitiesInside) {
if (!entitiesContainingAvatar.contains(entityID)) {
emit leaveEntity(entityID);
if (_entitiesScriptEngine) {
if (_entitiesScriptEngine) {
// for all of our previous containing entities, if they are no longer containing then send them a leave event
foreach(const EntityItemID& entityID, _currentEntitiesInside) {
if (!entitiesContainingAvatar.contains(entityID)) {
emit leaveEntity(entityID);
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
}
}
}
// for all of our new containing entities, if they weren't previously containing then send them an enter event
foreach(const EntityItemID& entityID, entitiesContainingAvatar) {
if (!_currentEntitiesInside.contains(entityID)) {
emit enterEntity(entityID);
if (_entitiesScriptEngine) {
// for all of our new containing entities, if they weren't previously containing then send them an enter event
foreach(const EntityItemID& entityID, entitiesContainingAvatar) {
if (!_currentEntitiesInside.contains(entityID)) {
emit enterEntity(entityID);
_entitiesScriptEngine->callEntityScriptMethod(entityID, "enterEntity");
}
}
_currentEntitiesInside = entitiesContainingAvatar;
}
_currentEntitiesInside = entitiesContainingAvatar;
}
}
return didUpdate;
@ -653,7 +654,7 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() {
if (_tree && !_shuttingDown) {
QVector<EntityItemID> currentEntitiesInsideToSave;
QSet<EntityItemID> currentEntitiesInsideToSave;
foreach (const EntityItemID& entityID, _currentEntitiesInside) {
EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID);
if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) {
@ -662,7 +663,7 @@ void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
}
} else {
currentEntitiesInsideToSave.push_back(entityID);
currentEntitiesInsideToSave.insert(entityID);
}
}
@ -687,9 +688,7 @@ void EntityTreeRenderer::leaveAllEntities() {
}
void EntityTreeRenderer::forceRecheckEntities() {
// make sure our "last avatar position" is something other than our current position,
// so that on our next chance, we'll check for enter/leave entity events.
_avatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE);
_forceRecheckEntities = true;
}
bool EntityTreeRenderer::applyLayeredZones() {
@ -992,7 +991,10 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
return;
}
if (_tree && !_shuttingDown && _entitiesScriptEngine) {
if (_tree && !_shuttingDown && _entitiesScriptEngine && !itr->second->getEntity()->getScript().isEmpty()) {
if (itr->second->getEntity()->contains(_avatarPosition)) {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
}
_entitiesScriptEngine->unloadEntityScript(entityID, true);
}
@ -1038,6 +1040,9 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool
QString scriptUrl = entity->getScript();
if ((shouldLoad && unloadFirst) || scriptUrl.isEmpty()) {
if (_entitiesScriptEngine) {
if (entity->contains(_avatarPosition)) {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
}
_entitiesScriptEngine->unloadEntityScript(entityID);
}
entity->scriptHasUnloaded();

View file

@ -169,7 +169,7 @@ private:
void resetEntitiesScriptEngine();
bool findBestZoneAndMaybeContainingEntities(QVector<EntityItemID>* entitiesContainingAvatar = nullptr);
bool findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar);
bool applyLayeredZones();
void stopDomainAndNonOwnedEntities();
@ -186,7 +186,8 @@ private:
void forceRecheckEntities();
glm::vec3 _avatarPosition { 0.0f };
QVector<EntityItemID> _currentEntitiesInside;
bool _forceRecheckEntities { true };
QSet<EntityItemID> _currentEntitiesInside;
bool _wantScripts;
ScriptEnginePointer _entitiesScriptEngine;

View file

@ -219,9 +219,10 @@ controller::Input KeyboardMouseDevice::InputDevice::makeInput(KeyboardMouseDevic
/**jsdoc
* <p>The <code>Controller.Hardware.Keyboard</code> object has properties representing keyboard, mouse, and display touch
* events. The property values are integer IDs, uniquely identifying each output. <em>Read-only.</em> These can be mapped to
* actions or functions or <code>Controller.Standard</code> items in a {@link RouteObject} mapping. For presses, each data
* value is either <code>1.0</code> for "true" or <code>0.0</code> for "false".</p>
* events. The property values are integer IDs, uniquely identifying each output. <em>Read-only.</em></p>
* <p>These events can be mapped to actions or functions or <code>Controller.Standard</code> items in a {@link RouteObject}
* mapping. For presses, each data value is either <code>1.0</code> for "true" or <code>0.0</code> for "false".</p>
*
* <table>
* <thead>
* <tr><th>Property</th><th>Type</th><td>Data</th><th>Description</th></tr>
@ -269,14 +270,18 @@ controller::Input KeyboardMouseDevice::InputDevice::makeInput(KeyboardMouseDevic
* new x-coordinate value.</td></tr>
* <tr><td><code>MouseY</code></td><td>number</td><td>number</td><td>The mouse y-coordinate changed. The data value is its
* new y-coordinate value.</td></tr>
* <tr><td><code>MouseWheelRight</code></td><td>number</td><td>number</td><td>The mouse wheel rotated left. The data value
* <tr><td><code>MouseWheelRight</code></td><td>number</td><td>number</td><td>The mouse wheel rotated right. The data value
* is the number of units rotated (typically <code>1.0</code>).</td></tr>
* <tr><td><code>MouseWheelLeft</code></td><td>number</td><td>number</td><td>The mouse wheel rotated left. The data value
* is the number of units rotated (typically <code>1.0</code>).</td></tr>
* <tr><td><code>MouseWheelUp</code></td><td>number</td><td>number</td><td>The mouse wheel rotated up. The data value
* is the number of units rotated (typically <code>1.0</code>).</td></tr>
* is the number of units rotated (typically <code>1.0</code>).<br />
* <strong>Warning:</strong> The mouse wheel in an ordinary mouse generates left/right wheel events instead of
* up/down.</td></tr>
* <tr><td><code>MouseWheelDown</code></td><td>number</td><td>number</td><td>The mouse wheel rotated down. The data value
* is the number of units rotated (typically <code>1.0</code>).</td></tr>
* is the number of units rotated (typically <code>1.0</code>).<br />
* <strong>Warning:</strong> The mouse wheel in an ordinary mouse generates left/right wheel events instead of
* up/down.</td></tr>
* <tr><td><code>TouchpadRight</code></td><td>number</td><td>number</td><td>The average touch on a touch-enabled device
* moved right. The data value is how far the average position of all touch points moved.</td></tr>
* <tr><td><code>TouchpadLeft</code></td><td>number</td><td>number</td><td>The average touch on a touch-enabled device
@ -288,7 +293,6 @@ controller::Input KeyboardMouseDevice::InputDevice::makeInput(KeyboardMouseDevic
* </tbody>
* </table>
* @typedef {object} Controller.Hardware-Keyboard
* @todo <em>Currently, the mouse wheel in an ordinary mouse generates left/right wheel events instead of up/down.</em>
*/
controller::Input::NamedVector KeyboardMouseDevice::InputDevice::getAvailableInputs() const {
using namespace controller;

View file

@ -776,11 +776,14 @@ scriptable::ScriptableModelBase Model::getScriptableModel() {
auto& materialName = _modelMeshMaterialNames[shapeID];
result.appendMaterial(graphics::MaterialLayer(getGeometry()->getShapeMaterial(shapeID), 0), shapeID, materialName);
auto mappedMaterialIter = _materialMapping.find(shapeID);
if (mappedMaterialIter != _materialMapping.end()) {
auto mappedMaterials = mappedMaterialIter->second;
for (auto& mappedMaterial : mappedMaterials) {
result.appendMaterial(mappedMaterial, shapeID, materialName);
{
std::unique_lock<std::mutex> lock(_materialMappingMutex);
auto mappedMaterialIter = _materialMapping.find(shapeID);
if (mappedMaterialIter != _materialMapping.end()) {
auto mappedMaterials = mappedMaterialIter->second;
for (auto& mappedMaterial : mappedMaterials) {
result.appendMaterial(mappedMaterial, shapeID, materialName);
}
}
}
shapeID++;
@ -1558,6 +1561,13 @@ void Model::applyMaterialMapping() {
auto renderItemsKey = _renderItemKeyGlobalFlags;
PrimitiveMode primitiveMode = getPrimitiveMode();
bool useDualQuaternionSkinning = _useDualQuaternionSkinning;
auto modelMeshRenderItemIDs = _modelMeshRenderItemIDs;
auto modelMeshRenderItemShapes = _modelMeshRenderItemShapes;
std::unordered_map<int, bool> shouldInvalidatePayloadShapeKeyMap;
for (auto& shape : _modelMeshRenderItemShapes) {
shouldInvalidatePayloadShapeKeyMap[shape.meshIndex] = shouldInvalidatePayloadShapeKey(shape.meshIndex);
}
auto& materialMapping = getMaterialMapping();
for (auto& mapping : materialMapping) {
@ -1577,7 +1587,8 @@ void Model::applyMaterialMapping() {
priorityMapPerResource[shapeID] = ++_priorityMap[shapeID];
}
auto materialLoaded = [this, networkMaterialResource, shapeIDs, priorityMapPerResource, renderItemsKey, primitiveMode, useDualQuaternionSkinning]() {
auto materialLoaded = [this, networkMaterialResource, shapeIDs, priorityMapPerResource, renderItemsKey, primitiveMode, useDualQuaternionSkinning,
modelMeshRenderItemIDs, modelMeshRenderItemShapes, shouldInvalidatePayloadShapeKeyMap]() {
if (networkMaterialResource->isFailed() || networkMaterialResource->parsedMaterials.names.size() == 0) {
return;
}
@ -1600,12 +1611,15 @@ void Model::applyMaterialMapping() {
}
}
for (auto shapeID : shapeIDs) {
if (shapeID < _modelMeshRenderItemIDs.size()) {
auto itemID = _modelMeshRenderItemIDs[shapeID];
auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex;
bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex);
if (shapeID < modelMeshRenderItemIDs.size()) {
auto itemID = modelMeshRenderItemIDs[shapeID];
auto meshIndex = modelMeshRenderItemShapes[shapeID].meshIndex;
bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKeyMap.at(meshIndex);
graphics::MaterialLayer material = graphics::MaterialLayer(networkMaterial, priorityMapPerResource.at(shapeID));
_materialMapping[shapeID].push_back(material);
{
std::unique_lock<std::mutex> lock(_materialMappingMutex);
_materialMapping[shapeID].push_back(material);
}
transaction.updateItem<ModelMeshPartPayload>(itemID, [material, renderItemsKey,
invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning](ModelMeshPartPayload& data) {
data.addMaterial(material);

View file

@ -379,6 +379,7 @@ protected:
std::unordered_map<unsigned int, quint16> _priorityMap; // only used for materialMapping
std::unordered_map<unsigned int, std::vector<graphics::MaterialLayer>> _materialMapping; // generated during applyMaterialMapping
std::mutex _materialMappingMutex;
void applyMaterialMapping();
void setBlendshapeCoefficients(const QVector<float>& coefficients) { _blendshapeCoefficients = coefficients; }

View file

@ -16,6 +16,13 @@
#include <QString>
#include <QUrl>
/**jsdoc
* Information about a resource request.
* @typedef {object} ResourceRequestObserver.ResourceRequest
* @property {string} url - The URL of the resource request.
* @property {number} callerId - An ID identifying the request.
* @property {string} extra - Extra information about the request.
*/
void ResourceRequestObserver::update(const QUrl& requestUrl,
const qint64 callerId,
const QString& extra) {

View file

@ -16,7 +16,15 @@
#include "DependencyManager.h"
/**jsdoc
* The <code>ResourceRequestObserver</code> API provides notifications when an observable resource request is made.
*
* @namespace ResourceRequestObserver
*
* @hifi-interface
* @hifi-client-entity
* @hifi-avatar
*/
class ResourceRequestObserver : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
@ -25,5 +33,29 @@ public:
void update(const QUrl& requestUrl, const qint64 callerId = -1, const QString& extra = "");
signals:
/**jsdoc
* Triggered when an observable resource request is made.
* @function ResourceRequestObserver.resourceRequestEvent
* @param {ResourceRequestObserver.ResourceRequest} request - Information about the resource request.
* @returns {Signal}
* @example <caption>Report when a particular Clipboard.importEntities() resource request is made.</caption>
* ResourceRequestObserver.resourceRequestEvent.connect(function (request) {
* if (request.callerId === 100) {
* print("Resource request: " + JSON.stringify(request));
* }
* });
*
* function importEntities() {
* var filename = Window.browse("Import entities to clipboard", "", "*.json");
* if (filename) {
* Clipboard.importEntities(filename, true, 100);
* pastedEntities = Clipboard.pasteEntities(Vec3.sum(MyAvatar.position,
* Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -3 })));
* print("Entities pasted: " + JSON.stringify(pastedEntities));
* }
* }
*
* Script.setTimeout(importEntities, 2000);
*/
void resourceRequestEvent(QVariantMap result);
};

View file

@ -409,9 +409,10 @@ void OculusControllerManager::TouchDevice::stopHapticPulse(bool leftHand) {
}
/**jsdoc
* <p>The <code>Controller.Hardware.OculusTouch</code> object has properties representing Oculus Rift. The property values are
* integer IDs, uniquely identifying each output. <em>Read-only.</em> These can be mapped to actions or functions or
* <code>Controller.Standard</code> items in a {@link RouteObject} mapping.</p>
* <p>The <code>Controller.Hardware.OculusTouch</code> object has properties representing the Oculus Rift. The property values
* are integer IDs, uniquely identifying each output. <em>Read-only.</em></p>
* <p>These outputs can be mapped to actions or functions or <code>Controller.Standard</code> items in a {@link RouteObject}
* mapping.</p>
* <table>
* <thead>
* <tr><th>Property</th><th>Type</th><th>Data</th><th>Description</th></tr>

View file

@ -1299,14 +1299,20 @@ void ViveControllerManager::InputDevice::setConfigFromString(const QString& valu
}
/**jsdoc
* <p>The <code>Controller.Hardware.Vive</code> object has properties representing Vive. The property values are integer IDs,
* uniquely identifying each output. <em>Read-only.</em> These can be mapped to actions or functions or
* <code>Controller.Standard</code> items in a {@link RouteObject} mapping.</p>
* <p>The <code>Controller.Hardware.Vive</code> object has properties representing the Vive. The property values are integer
* IDs, uniquely identifying each output. <em>Read-only.</em></p>
* <p>These outputs can be mapped to actions or functions or <code>Controller.Standard</code> items in a {@link RouteObject}
* mapping.</p>
* <table>
* <thead>
* <tr><th>Property</th><th>Type</th><th>Data</th><th>Description</th></tr>
* </thead>
* <tbody>
* <tr><td colspan="4"><strong>Buttons</strong></td></tr>
* <tr><td><code>LeftApplicationMenu</code></td><td>number</td><td>number</td><td>Left application menu button pressed.
* </td></tr>
* <tr><td><code>RightApplicationMenu</code></td><td>number</td><td>number</td><td>Right application menu button pressed.
* </td></tr>
* <tr><td colspan="4"><strong>Touch Pad (Sticks)</strong></td></tr>
* <tr><td><code>LX</code></td><td>number</td><td>number</td><td>Left touch pad x-axis scale.</td></tr>
* <tr><td><code>LY</code></td><td>number</td><td>number</td><td>Left touch pad y-axis scale.</td></tr>

View file

@ -94,7 +94,7 @@ def parse_args():
parser.add_argument('--vcpkg-root', type=str, help='The location of the vcpkg distribution')
parser.add_argument('--build-root', required=True, type=str, help='The location of the cmake build')
parser.add_argument('--ports-path', type=str, default=defaultPortsPath)
parser.add_argument('--ci-build', action='store_true')
parser.add_argument('--ci-build', action='store_true', default=os.getenv('CI_BUILD') is not None)
if True:
args = parser.parse_args()
else: