mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 20:23:06 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into 20638
This commit is contained in:
commit
9af7205672
32 changed files with 818 additions and 764 deletions
|
@ -187,6 +187,7 @@ option(GET_OPENVR "Get OpenVR library automatically as external project" 1)
|
||||||
option(GET_BOOSTCONFIG "Get Boost-config library automatically as external project" 1)
|
option(GET_BOOSTCONFIG "Get Boost-config library automatically as external project" 1)
|
||||||
option(GET_OGLPLUS "Get OGLplus library automatically as external project" 1)
|
option(GET_OGLPLUS "Get OGLplus library automatically as external project" 1)
|
||||||
option(GET_GLEW "Get GLEW library automatically as external project" 1)
|
option(GET_GLEW "Get GLEW library automatically as external project" 1)
|
||||||
|
option(GET_SIXENSE "Get Sixense library automatically as external project" 1)
|
||||||
|
|
||||||
option(USE_NSIGHT "Attempt to find the nSight libraries" 1)
|
option(USE_NSIGHT "Attempt to find the nSight libraries" 1)
|
||||||
|
|
||||||
|
|
|
@ -971,12 +971,7 @@ void OctreeServer::readConfiguration() {
|
||||||
strcpy(_persistFilename, qPrintable(persistFilename));
|
strcpy(_persistFilename, qPrintable(persistFilename));
|
||||||
qDebug("persistFilename=%s", _persistFilename);
|
qDebug("persistFilename=%s", _persistFilename);
|
||||||
|
|
||||||
QString persistAsFileType;
|
_persistAsFileType = "json.gz";
|
||||||
if (!readOptionString(QString("persistAsFileType"), settingsSectionObject, persistAsFileType)) {
|
|
||||||
persistAsFileType = "svo";
|
|
||||||
}
|
|
||||||
_persistAsFileType = persistAsFileType;
|
|
||||||
qDebug() << "persistAsFileType=" << _persistAsFileType;
|
|
||||||
|
|
||||||
_persistInterval = OctreePersistThread::DEFAULT_PERSIST_INTERVAL;
|
_persistInterval = OctreePersistThread::DEFAULT_PERSIST_INTERVAL;
|
||||||
readOptionInt(QString("persistInterval"), settingsSectionObject, _persistInterval);
|
readOptionInt(QString("persistInterval"), settingsSectionObject, _persistInterval);
|
||||||
|
|
62
cmake/externals/Sixense/CMakeLists.txt
vendored
Normal file
62
cmake/externals/Sixense/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
include(ExternalProject)
|
||||||
|
include(SelectLibraryConfigurations)
|
||||||
|
|
||||||
|
set(EXTERNAL_NAME Sixense)
|
||||||
|
|
||||||
|
ExternalProject_Add(
|
||||||
|
${EXTERNAL_NAME}
|
||||||
|
URL http://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_071615.zip
|
||||||
|
URL_MD5 752a3901f334124e9cffc2ba4136ef7d
|
||||||
|
CONFIGURE_COMMAND ""
|
||||||
|
BUILD_COMMAND ""
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
LOG_DOWNLOAD 1
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||||
|
|
||||||
|
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
|
||||||
|
|
||||||
|
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||||
|
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE INTERNAL)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||||
|
set(ARCH_DIR "x64/VS2013")
|
||||||
|
set(ARCH_SUFFIX "_x64")
|
||||||
|
else()
|
||||||
|
set(ARCH_DIR "Win32/VS2013")
|
||||||
|
set(ARCH_SUFFIX "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(LIB_DIR "${SOURCE_DIR}/lib/${ARCH_DIR}")
|
||||||
|
set(BIN_DIR "${SOURCE_DIR}/bin/${ARCH_DIR}")
|
||||||
|
set(SIXENSE_LIBRARY_RELEASE "${LIB_DIR}/release_dll/sixense${ARCH_SUFFIX}.lib" CACHE FILEPATH "Sixense release lib")
|
||||||
|
set(SIXENSE_LIBRARY_DEBUG "${LIB_DIR}/debug_dll/sixensed${ARCH_SUFFIX}.lib" CACHE FILEPATH "Sixense debug lib")
|
||||||
|
set(SIXENSE_RELEASE_DLL_PATH "${BIN_DIR}/release_dll" CACHE FILEPATH "Sixense release DLL path")
|
||||||
|
set(SIXENSE_DEBUG_DLL_PATH "${BIN_DIR}/debug_dll" CACHE FILEPATH "Sixense debug DLL path")
|
||||||
|
|
||||||
|
# FIXME need to account for different architectures
|
||||||
|
add_paths_to_fixup_libs(${SIXENSE_DEBUG_DLL_PATH})
|
||||||
|
add_paths_to_fixup_libs(${SIXENSE_RELEASE_DLL_PATH})
|
||||||
|
|
||||||
|
elseif(APPLE)
|
||||||
|
|
||||||
|
set(ARCH_DIR "osx_x64")
|
||||||
|
set(ARCH_SUFFIX "_x64")
|
||||||
|
set(LIB_DIR "${SOURCE_DIR}/lib/${ARCH_DIR}")
|
||||||
|
|
||||||
|
set(SIXENSE_LIBRARY_RELEASE "${LIB_DIR}/release_dll/libsixense${ARCH_SUFFIX}.dylib" CACHE FILEPATH "Sixense release lib")
|
||||||
|
set(SIXENSE_LIBRARY_DEBUG "${LIB_DIR}/debug_dll/libsixensed${ARCH_SUFFIX}.dylib" CACHE FILEPATH "Sixense debug lib")
|
||||||
|
|
||||||
|
elseif(NOT ANDROID)
|
||||||
|
|
||||||
|
set(ARCH_DIR "linux_x64")
|
||||||
|
set(ARCH_SUFFIX "_x64")
|
||||||
|
set(LIB_DIR "${SOURCE_DIR}/lib/${ARCH_DIR}")
|
||||||
|
|
||||||
|
set(SIXENSE_LIBRARY_RELEASE "${LIB_DIR}/release/libsixense${ARCH_SUFFIX}.so" CACHE FILEPATH "Sixense release lib")
|
||||||
|
set(SIXENSE_LIBRARY_DEBUG "${LIB_DIR}/debug/libsixensed${ARCH_SUFFIX}.so" CACHE FILEPATH "Sixense debug lib")
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
60
cmake/externals/sixense/CMakeLists.txt
vendored
60
cmake/externals/sixense/CMakeLists.txt
vendored
|
@ -1,60 +0,0 @@
|
||||||
include(ExternalProject)
|
|
||||||
include(SelectLibraryConfigurations)
|
|
||||||
|
|
||||||
set(EXTERNAL_NAME Sixense)
|
|
||||||
|
|
||||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
|
||||||
|
|
||||||
ExternalProject_Add(
|
|
||||||
${EXTERNAL_NAME}
|
|
||||||
URL ./SixenseSDK_062612.zip
|
|
||||||
URL_MD5 10cc8dc470d2ac1244a88cf04bc549cc
|
|
||||||
CONFIGURE_COMMAND ""
|
|
||||||
BUILD_COMMAND ""
|
|
||||||
INSTALL_COMMAND ""
|
|
||||||
LOG_DOWNLOAD 1
|
|
||||||
)
|
|
||||||
|
|
||||||
if (APPLE)
|
|
||||||
find_library(SIXENSE_LIBRARY_RELEASE lib/osx_x64/release_dll/libsixense_x64.dylib HINTS ${SIXENSE_SEARCH_DIRS})
|
|
||||||
find_library(SIXENSE_LIBRARY_DEBUG lib/osx_x64/debug_dll/libsixensed_x64.dylib HINTS ${SIXENSE_SEARCH_DIRS})
|
|
||||||
elseif (UNIX)
|
|
||||||
find_library(SIXENSE_LIBRARY_RELEASE lib/linux_x64/release/libsixense_x64.so HINTS ${SIXENSE_SEARCH_DIRS})
|
|
||||||
# find_library(SIXENSE_LIBRARY_DEBUG lib/linux_x64/debug/libsixensed_x64.so HINTS ${SIXENSE_SEARCH_DIRS})
|
|
||||||
elseif (WIN32)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
|
|
||||||
|
|
||||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE INTERNAL)
|
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
|
|
||||||
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
|
||||||
set(ARCH_DIR "x64")
|
|
||||||
set(ARCH_SUFFIX "_x64")
|
|
||||||
else()
|
|
||||||
set(ARCH_DIR "Win32")
|
|
||||||
set(ARCH_SUFFIX "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# FIXME need to account for different architectures
|
|
||||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES "${SOURCE_DIR}/lib/${ARCH_DIR}/release_dll/sixense${ARCH_SUFFIX}.lib" CACHE TYPE INTERNAL)
|
|
||||||
add_paths_to_fixup_libs(${SOURCE_DIR}/bin/win32)
|
|
||||||
|
|
||||||
elseif(APPLE)
|
|
||||||
|
|
||||||
# FIXME need to account for different architectures
|
|
||||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/osx32/libopenvr_api.dylib CACHE TYPE INTERNAL)
|
|
||||||
add_paths_to_fixup_libs(${SOURCE_DIR}/bin/osx32)
|
|
||||||
|
|
||||||
elseif(NOT ANDROID)
|
|
||||||
|
|
||||||
# FIXME need to account for different architectures
|
|
||||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/linux32/libopenvr_api.so CACHE TYPE INTERNAL)
|
|
||||||
add_paths_to_fixup_libs(${SOURCE_DIR}/bin/linux32)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ select_library_configurations(SIXENSE)
|
||||||
|
|
||||||
set(SIXENSE_REQUIREMENTS SIXENSE_INCLUDE_DIRS SIXENSE_LIBRARIES)
|
set(SIXENSE_REQUIREMENTS SIXENSE_INCLUDE_DIRS SIXENSE_LIBRARIES)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
list(APPEND SIXENSE_REQUIREMENTS SIXENSE_DEBUG_DLL_PATH SIXENSE_RELEASE_DLL_PATH SIXENSE_DEVICE_DLL_PATH)
|
list(APPEND SIXENSE_REQUIREMENTS SIXENSE_DEBUG_DLL_PATH SIXENSE_RELEASE_DLL_PATH)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(SIXENSE_LIBRARIES "${SIXENSE_LIBRARY}")
|
set(SIXENSE_LIBRARIES "${SIXENSE_LIBRARY}")
|
||||||
|
|
|
@ -371,30 +371,8 @@
|
||||||
"name": "persistFilename",
|
"name": "persistFilename",
|
||||||
"label": "Entities Filename",
|
"label": "Entities Filename",
|
||||||
"help": "the path to the file entities are stored in. Make sure the path exists.",
|
"help": "the path to the file entities are stored in. Make sure the path exists.",
|
||||||
"placeholder": "resources/models.svo",
|
"placeholder": "resources/models.json.gz",
|
||||||
"default": "resources/models.svo",
|
"default": "resources/models.json.gz",
|
||||||
"advanced": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "persistAsFileType",
|
|
||||||
"label": "File format for entity server's persistent data",
|
|
||||||
"help": "This defines how the entity server will save entities to disk.",
|
|
||||||
"default": "svo",
|
|
||||||
"type": "select",
|
|
||||||
"options": [
|
|
||||||
{
|
|
||||||
"value": "svo",
|
|
||||||
"label": "Entity server persists data as SVO"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "json",
|
|
||||||
"label": "Entity server persists data as JSON"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "json.gz",
|
|
||||||
"label": "Entity server persists data as gzipped JSON"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"advanced": true
|
"advanced": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -362,9 +362,12 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit
|
||||||
this.fractionKey = optionalPersistenceKey + '.fraction';
|
this.fractionKey = optionalPersistenceKey + '.fraction';
|
||||||
this.save = function () {
|
this.save = function () {
|
||||||
var screenSize = Controller.getViewportDimensions();
|
var screenSize = Controller.getViewportDimensions();
|
||||||
|
if (screenSize.x > 0 && screenSize.y > 0) {
|
||||||
|
// Guard against invalid screen size that can occur at shut-down.
|
||||||
var fraction = {x: that.x / screenSize.x, y: that.y / screenSize.y};
|
var fraction = {x: that.x / screenSize.x, y: that.y / screenSize.y};
|
||||||
Settings.setValue(this.fractionKey, JSON.stringify(fraction));
|
Settings.setValue(this.fractionKey, JSON.stringify(fraction));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.save = function () { }; // Called on move. Can be overriden or extended by clients.
|
this.save = function () { }; // Called on move. Can be overriden or extended by clients.
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,11 @@ Item {
|
||||||
font.pixelSize: root.fontSize
|
font.pixelSize: root.fontSize
|
||||||
text: "Framerate: " + root.framerate
|
text: "Framerate: " + root.framerate
|
||||||
}
|
}
|
||||||
|
Text {
|
||||||
|
color: root.fontColor;
|
||||||
|
font.pixelSize: root.fontSize
|
||||||
|
text: "Simrate: " + root.simrate
|
||||||
|
}
|
||||||
Text {
|
Text {
|
||||||
color: root.fontColor;
|
color: root.fontColor;
|
||||||
font.pixelSize: root.fontSize
|
font.pixelSize: root.fontSize
|
||||||
|
|
|
@ -112,9 +112,7 @@
|
||||||
#include "InterfaceActionFactory.h"
|
#include "InterfaceActionFactory.h"
|
||||||
|
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
|
|
||||||
#include "audio/AudioScope.h"
|
#include "audio/AudioScope.h"
|
||||||
|
|
||||||
#include "devices/DdeFaceTracker.h"
|
#include "devices/DdeFaceTracker.h"
|
||||||
#include "devices/EyeTracker.h"
|
#include "devices/EyeTracker.h"
|
||||||
#include "devices/Faceshift.h"
|
#include "devices/Faceshift.h"
|
||||||
|
@ -148,6 +146,8 @@
|
||||||
#include "ui/AddressBarDialog.h"
|
#include "ui/AddressBarDialog.h"
|
||||||
#include "ui/UpdateDialog.h"
|
#include "ui/UpdateDialog.h"
|
||||||
|
|
||||||
|
#include "ui/overlays/Cube3DOverlay.h"
|
||||||
|
|
||||||
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||||
// FIXME seems to be broken.
|
// FIXME seems to be broken.
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
|
@ -172,7 +172,6 @@ public:
|
||||||
void call() { _fun(); }
|
void call() { _fun(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Starfield information
|
// Starfield information
|
||||||
|
@ -299,6 +298,13 @@ bool setupEssentials(int& argc, char** argv) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME move to header, or better yet, design some kind of UI manager
|
||||||
|
// to take care of highlighting keyboard focused items, rather than
|
||||||
|
// continuing to overburden Application.cpp
|
||||||
|
Cube3DOverlay* _keyboardFocusHighlight{ nullptr };
|
||||||
|
int _keyboardFocusHighlightID{ -1 };
|
||||||
|
|
||||||
|
|
||||||
Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
QApplication(argc, argv),
|
QApplication(argc, argv),
|
||||||
_dependencyManagerIsSetup(setupEssentials(argc, argv)),
|
_dependencyManagerIsSetup(setupEssentials(argc, argv)),
|
||||||
|
@ -554,7 +560,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
|
|
||||||
|
|
||||||
_toolWindow = new ToolWindow();
|
_toolWindow = new ToolWindow();
|
||||||
_toolWindow->setWindowFlags(_toolWindow->windowFlags() | Qt::WindowStaysOnTopHint);
|
_toolWindow->setWindowFlags((_toolWindow->windowFlags() | Qt::WindowStaysOnTopHint) & ~Qt::WindowMinimizeButtonHint);
|
||||||
_toolWindow->setWindowTitle("Tools");
|
_toolWindow->setWindowTitle("Tools");
|
||||||
|
|
||||||
_offscreenContext->makeCurrent();
|
_offscreenContext->makeCurrent();
|
||||||
|
@ -673,8 +679,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
auto& packetReceiver = nodeList->getPacketReceiver();
|
auto& packetReceiver = nodeList->getPacketReceiver();
|
||||||
packetReceiver.registerListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket");
|
packetReceiver.registerListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket");
|
||||||
|
|
||||||
|
// If the user clicks an an entity, we will check that it's an unlocked web entity, and if so, set the focus to it
|
||||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, [this, entityScriptingInterface](const EntityItemID& entityItemID, const MouseEvent& event) {
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity,
|
||||||
|
[this, entityScriptingInterface](const EntityItemID& entityItemID, const MouseEvent& event) {
|
||||||
if (_keyboardFocusedItem != entityItemID) {
|
if (_keyboardFocusedItem != entityItemID) {
|
||||||
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
||||||
auto properties = entityScriptingInterface->getEntityProperties(entityItemID);
|
auto properties = entityScriptingInterface->getEntityProperties(entityItemID);
|
||||||
|
@ -684,14 +692,49 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
if (webEntity) {
|
if (webEntity) {
|
||||||
webEntity->setProxyWindow(_window->windowHandle());
|
webEntity->setProxyWindow(_window->windowHandle());
|
||||||
_keyboardFocusedItem = entityItemID;
|
_keyboardFocusedItem = entityItemID;
|
||||||
|
_lastAcceptedKeyPress = usecTimestampNow();
|
||||||
|
if (_keyboardFocusHighlightID < 0 || !getOverlays().isAddedOverlay(_keyboardFocusHighlightID)) {
|
||||||
|
_keyboardFocusHighlight = new Cube3DOverlay();
|
||||||
|
_keyboardFocusHighlight->setAlpha(1.0f);
|
||||||
|
_keyboardFocusHighlight->setBorderSize(1.0f);
|
||||||
|
_keyboardFocusHighlight->setColor({ 0xFF, 0xEF, 0x00 });
|
||||||
|
_keyboardFocusHighlight->setIsSolid(false);
|
||||||
|
_keyboardFocusHighlight->setPulseMin(0.5);
|
||||||
|
_keyboardFocusHighlight->setPulseMax(1.0);
|
||||||
|
_keyboardFocusHighlight->setColorPulse(1.0);
|
||||||
|
_keyboardFocusHighlight->setIgnoreRayIntersection(true);
|
||||||
|
_keyboardFocusHighlight->setDrawInFront(true);
|
||||||
}
|
}
|
||||||
|
_keyboardFocusHighlight->setRotation(webEntity->getRotation());
|
||||||
|
_keyboardFocusHighlight->setPosition(webEntity->getPosition());
|
||||||
|
_keyboardFocusHighlight->setDimensions(webEntity->getDimensions() * 1.05f);
|
||||||
|
_keyboardFocusHighlight->setVisible(true);
|
||||||
|
_keyboardFocusHighlightID = getOverlays().addOverlay(_keyboardFocusHighlight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_keyboardFocusedItem == UNKNOWN_ENTITY_ID && _keyboardFocusHighlight) {
|
||||||
|
_keyboardFocusHighlight->setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::deletingEntity,
|
||||||
|
[=](const EntityItemID& entityItemID) {
|
||||||
|
if (entityItemID == _keyboardFocusedItem) {
|
||||||
|
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
||||||
|
if (_keyboardFocusHighlight) {
|
||||||
|
_keyboardFocusHighlight->setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, [=](const EntityItemID& entityItemID, const MouseEvent& event) {
|
// If the user clicks somewhere where there is NO entity at all, we will release focus
|
||||||
if (_keyboardFocusedItem == entityItemID) {
|
connect(getEntities(), &EntityTreeRenderer::mousePressOffEntity,
|
||||||
|
[=](const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId) {
|
||||||
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
||||||
|
if (_keyboardFocusHighlight) {
|
||||||
|
_keyboardFocusHighlight->setVisible(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -704,6 +747,11 @@ void Application::aboutToQuit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::cleanupBeforeQuit() {
|
void Application::cleanupBeforeQuit() {
|
||||||
|
if (_keyboardFocusHighlightID > 0) {
|
||||||
|
getOverlays().deleteOverlay(_keyboardFocusHighlightID);
|
||||||
|
_keyboardFocusHighlightID = -1;
|
||||||
|
}
|
||||||
|
_keyboardFocusHighlight = nullptr;
|
||||||
|
|
||||||
_entities.clear(); // this will allow entity scripts to properly shutdown
|
_entities.clear(); // this will allow entity scripts to properly shutdown
|
||||||
|
|
||||||
|
@ -1270,6 +1318,7 @@ bool Application::event(QEvent* event) {
|
||||||
event->setAccepted(false);
|
event->setAccepted(false);
|
||||||
QCoreApplication::sendEvent(webEntity->getEventHandler(), event);
|
QCoreApplication::sendEvent(webEntity->getEventHandler(), event);
|
||||||
if (event->isAccepted()) {
|
if (event->isAccepted()) {
|
||||||
|
_lastAcceptedKeyPress = usecTimestampNow();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1965,10 +2014,19 @@ void Application::checkFPS() {
|
||||||
void Application::idle() {
|
void Application::idle() {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
static SimpleAverage<float> interIdleDurations;
|
static SimpleAverage<float> interIdleDurations;
|
||||||
|
|
||||||
|
static uint64_t lastIdleStart{ 0 };
|
||||||
static uint64_t lastIdleEnd{ 0 };
|
static uint64_t lastIdleEnd{ 0 };
|
||||||
|
uint64_t now = usecTimestampNow();
|
||||||
|
uint64_t idleStartToStartDuration = now - lastIdleStart;
|
||||||
|
|
||||||
|
if (lastIdleStart > 0 && idleStartToStartDuration > 0) {
|
||||||
|
_simsPerSecond.updateAverage((float)USECS_PER_SECOND / (float)idleStartToStartDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastIdleStart = now;
|
||||||
|
|
||||||
if (lastIdleEnd != 0) {
|
if (lastIdleEnd != 0) {
|
||||||
uint64_t now = usecTimestampNow();
|
|
||||||
interIdleDurations.update(now - lastIdleEnd);
|
interIdleDurations.update(now - lastIdleEnd);
|
||||||
static uint64_t lastReportTime = now;
|
static uint64_t lastReportTime = now;
|
||||||
if ((now - lastReportTime) >= (USECS_PER_SECOND)) {
|
if ((now - lastReportTime) >= (USECS_PER_SECOND)) {
|
||||||
|
@ -1986,6 +2044,15 @@ void Application::idle() {
|
||||||
return; // bail early, nothing to do here.
|
return; // bail early, nothing to do here.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drop focus from _keyboardFocusedItem if no keyboard messages for 30 seconds
|
||||||
|
if (!_keyboardFocusedItem.isInvalidID()) {
|
||||||
|
const quint64 LOSE_FOCUS_AFTER_ELAPSED_TIME = 30 * USECS_PER_SECOND; // if idle for 30 seconds, drop focus
|
||||||
|
quint64 elapsedSinceAcceptedKeyPress = usecTimestampNow() - _lastAcceptedKeyPress;
|
||||||
|
if (elapsedSinceAcceptedKeyPress > LOSE_FOCUS_AFTER_ELAPSED_TIME) {
|
||||||
|
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
|
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
|
||||||
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
|
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
|
||||||
// details normally.
|
// details normally.
|
||||||
|
@ -2054,6 +2121,16 @@ void Application::idle() {
|
||||||
lastIdleEnd = usecTimestampNow();
|
lastIdleEnd = usecTimestampNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Application::getAverageSimsPerSecond() {
|
||||||
|
uint64_t now = usecTimestampNow();
|
||||||
|
|
||||||
|
if (now - _lastSimsPerSecondUpdate > USECS_PER_SECOND) {
|
||||||
|
_simsPerSecondReport = _simsPerSecond.getAverage();
|
||||||
|
_lastSimsPerSecondUpdate = now;
|
||||||
|
}
|
||||||
|
return _simsPerSecondReport;
|
||||||
|
}
|
||||||
|
|
||||||
void Application::setLowVelocityFilter(bool lowVelocityFilter) {
|
void Application::setLowVelocityFilter(bool lowVelocityFilter) {
|
||||||
InputDevice::setLowVelocityFilter(lowVelocityFilter);
|
InputDevice::setLowVelocityFilter(lowVelocityFilter);
|
||||||
}
|
}
|
||||||
|
@ -2402,6 +2479,10 @@ void Application::updateMouseRay() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called during Application::update immediately before AvatarManager::updateMyAvatar, updating my data that is then sent to everyone.
|
||||||
|
// (Maybe this code should be moved there?)
|
||||||
|
// The principal result is to call updateLookAtTargetAvatar() and then setLookAtPosition().
|
||||||
|
// Note that it is called BEFORE we update position or joints based on sensors, etc.
|
||||||
void Application::updateMyAvatarLookAtPosition() {
|
void Application::updateMyAvatarLookAtPosition() {
|
||||||
PerformanceTimer perfTimer("lookAt");
|
PerformanceTimer perfTimer("lookAt");
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <ViewFrustum.h>
|
#include <ViewFrustum.h>
|
||||||
#include <plugins/PluginContainer.h>
|
#include <plugins/PluginContainer.h>
|
||||||
#include <plugins/PluginManager.h>
|
#include <plugins/PluginManager.h>
|
||||||
|
#include <SimpleMovingAverage.h>
|
||||||
|
|
||||||
#include "AudioClient.h"
|
#include "AudioClient.h"
|
||||||
#include "Bookmarks.h"
|
#include "Bookmarks.h"
|
||||||
|
@ -350,6 +351,8 @@ public:
|
||||||
|
|
||||||
const QRect& getMirrorViewRect() const { return _mirrorViewRect; }
|
const QRect& getMirrorViewRect() const { return _mirrorViewRect; }
|
||||||
|
|
||||||
|
float getAverageSimsPerSecond();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
/// Fired when we're simulating; allows external parties to hook in.
|
/// Fired when we're simulating; allows external parties to hook in.
|
||||||
|
@ -680,6 +683,11 @@ private:
|
||||||
DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface();
|
DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface();
|
||||||
|
|
||||||
EntityItemID _keyboardFocusedItem;
|
EntityItemID _keyboardFocusedItem;
|
||||||
|
quint64 _lastAcceptedKeyPress = 0;
|
||||||
|
|
||||||
|
SimpleMovingAverage _simsPerSecond{10};
|
||||||
|
int _simsPerSecondReport = 0;
|
||||||
|
quint64 _lastSimsPerSecondUpdate = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Application_h
|
#endif // hifi_Application_h
|
||||||
|
|
|
@ -258,7 +258,7 @@ Menu::Menu() {
|
||||||
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true);
|
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true);
|
||||||
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::BlueSpeechSphere, 0, true);
|
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::BlueSpeechSphere, 0, true);
|
||||||
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::EnableCharacterController, 0, true,
|
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::EnableCharacterController, 0, true,
|
||||||
avatar, SLOT(updateMotionBehavior()));
|
avatar, SLOT(updateMotionBehaviorFromMenu()));
|
||||||
|
|
||||||
MenuWrapper* viewMenu = addMenu("View");
|
MenuWrapper* viewMenu = addMenu("View");
|
||||||
addActionToQMenuAndActionHash(viewMenu, MenuOption::ReloadContent, 0, qApp, SLOT(reloadResourceCaches()));
|
addActionToQMenuAndActionHash(viewMenu, MenuOption::ReloadContent, 0, qApp, SLOT(reloadResourceCaches()));
|
||||||
|
|
|
@ -563,6 +563,9 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::fixupModelsInScene() {
|
void Avatar::fixupModelsInScene() {
|
||||||
|
if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// check to see if when we added our models to the scene they were ready, if they were not ready, then
|
// check to see if when we added our models to the scene they were ready, if they were not ready, then
|
||||||
// fix them up in the scene
|
// fix them up in the scene
|
||||||
|
@ -688,6 +691,23 @@ glm::vec3 Avatar::getDisplayNamePosition() const {
|
||||||
const float HEAD_PROPORTION = 0.75f;
|
const float HEAD_PROPORTION = 0.75f;
|
||||||
namePosition = _position + getBodyUpDirection() * (getBillboardSize() * HEAD_PROPORTION);
|
namePosition = _position + getBodyUpDirection() * (getBillboardSize() * HEAD_PROPORTION);
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
// TODO: Temporary logging to track cause of invalid scale value; remove once cause has been fixed.
|
||||||
|
// See other TODO below.
|
||||||
|
if (glm::isnan(namePosition.x) || glm::isnan(namePosition.y) || glm::isnan(namePosition.z)
|
||||||
|
|| glm::isinf(namePosition.x) || glm::isinf(namePosition.y) || glm::isinf(namePosition.z)) {
|
||||||
|
qDebug() << "namePosition =" << namePosition;
|
||||||
|
glm::vec3 tempPosition(0.0f);
|
||||||
|
if (getSkeletonModel().getNeckPosition(tempPosition)) {
|
||||||
|
qDebug() << "getBodyUpDirection() =" << getBodyUpDirection();
|
||||||
|
qDebug() << "getHeadHeight() =" << getHeadHeight();
|
||||||
|
} else {
|
||||||
|
qDebug() << "_position =" << _position;
|
||||||
|
qDebug() << "getBodyUpDirection() =" << getBodyUpDirection();
|
||||||
|
qDebug() << "getBillboardSize() =" << getBillboardSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return namePosition;
|
return namePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -722,7 +742,8 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, floa
|
||||||
// Compute correct scale to apply
|
// Compute correct scale to apply
|
||||||
float scale = DESIRED_HIGHT_ON_SCREEN / (fontSize * pixelHeight) * devicePixelRatio;
|
float scale = DESIRED_HIGHT_ON_SCREEN / (fontSize * pixelHeight) * devicePixelRatio;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// TODO: Temporary logging to track cause of invalid scale vale; remove once cause has been fixed.
|
// TODO: Temporary logging to track cause of invalid scale value; remove once cause has been fixed.
|
||||||
|
// Problem is probably due to an invalid getDisplayNamePosition(). See extra logging above.
|
||||||
if (scale == 0.0f || glm::isnan(scale) || glm::isinf(scale)) {
|
if (scale == 0.0f || glm::isnan(scale) || glm::isinf(scale)) {
|
||||||
if (scale == 0.0f) {
|
if (scale == 0.0f) {
|
||||||
qDebug() << "ASSERT because scale == 0.0f";
|
qDebug() << "ASSERT because scale == 0.0f";
|
||||||
|
@ -733,6 +754,7 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, floa
|
||||||
if (glm::isinf(scale)) {
|
if (glm::isinf(scale)) {
|
||||||
qDebug() << "ASSERT because isinf(scale)";
|
qDebug() << "ASSERT because isinf(scale)";
|
||||||
}
|
}
|
||||||
|
qDebug() << "textPosition =" << textPosition;
|
||||||
qDebug() << "windowSizeY =" << windowSizeY;
|
qDebug() << "windowSizeY =" << windowSizeY;
|
||||||
qDebug() << "p1.y =" << p1.y;
|
qDebug() << "p1.y =" << p1.y;
|
||||||
qDebug() << "p1.w =" << p1.w;
|
qDebug() << "p1.w =" << p1.w;
|
||||||
|
|
|
@ -344,6 +344,20 @@ glm::quat Head::getFinalOrientationInLocalFrame() const {
|
||||||
return glm::quat(glm::radians(glm::vec3(getFinalPitch(), getFinalYaw(), getFinalRoll() )));
|
return glm::quat(glm::radians(glm::vec3(getFinalPitch(), getFinalYaw(), getFinalRoll() )));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Everyone else's head keeps track of a lookAtPosition that everybody sees the same, and refers to where that head
|
||||||
|
// is looking in model space -- e.g., at someone's eyeball, or between their eyes, or mouth, etc. Everyon's Interface
|
||||||
|
// will have the same value for the lookAtPosition of any given head.
|
||||||
|
//
|
||||||
|
// Everyone else's head also keeps track of a correctedLookAtPosition that may be different for the same head within
|
||||||
|
// different Interfaces. If that head is not looking at me, the correctedLookAtPosition is the same as the lookAtPosition.
|
||||||
|
// However, if that head is looking at me, then I will attempt to adjust the lookAtPosition by the difference between
|
||||||
|
// my (singular) eye position and my actual camera position. This adjustment is used on their eyeballs during rendering
|
||||||
|
// (and also on any lookAt vector display for that head, during rendering). Note that:
|
||||||
|
// 1. this adjustment can be made directly to the other head's eyeball joints, because we won't be send their joint information to others.
|
||||||
|
// 2. the corrected position is a separate ivar, so the common/uncorrected value is still available
|
||||||
|
//
|
||||||
|
// There is a pun here: The two lookAtPositions will always be the same for my own avatar in my own Interface, because I
|
||||||
|
// will not be looking at myself. (Even in a mirror, I will be looking at the camera.)
|
||||||
glm::vec3 Head::getCorrectedLookAtPosition() {
|
glm::vec3 Head::getCorrectedLookAtPosition() {
|
||||||
if (isLookingAtMe()) {
|
if (isLookingAtMe()) {
|
||||||
return _correctedLookAtPosition;
|
return _correctedLookAtPosition;
|
||||||
|
@ -364,7 +378,7 @@ void Head::setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition) {
|
||||||
bool Head::isLookingAtMe() {
|
bool Head::isLookingAtMe() {
|
||||||
// Allow for outages such as may be encountered during avatar movement
|
// Allow for outages such as may be encountered during avatar movement
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
const quint64 LOOKING_AT_ME_GAP_ALLOWED = 1000000; // microseconds
|
const quint64 LOOKING_AT_ME_GAP_ALLOWED = (5 * 1000 * 1000) / 60; // n frames, in microseconds
|
||||||
return _isLookingAtMe || (now - _wasLastLookingAtMe) < LOOKING_AT_ME_GAP_ALLOWED;
|
return _isLookingAtMe || (now - _wasLastLookingAtMe) < LOOKING_AT_ME_GAP_ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ void SkeletonModel::initJointStates(QVector<JointState> states) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const float PALM_PRIORITY = DEFAULT_PRIORITY;
|
const float PALM_PRIORITY = DEFAULT_PRIORITY;
|
||||||
|
// Called within Model::simulate call, below.
|
||||||
void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
||||||
if (_owningAvatar->isMyAvatar()) {
|
if (_owningAvatar->isMyAvatar()) {
|
||||||
_rig->computeMotionAnimationState(deltaTime, _owningAvatar->getPosition(), _owningAvatar->getVelocity(), _owningAvatar->getOrientation());
|
_rig->computeMotionAnimationState(deltaTime, _owningAvatar->getPosition(), _owningAvatar->getVelocity(), _owningAvatar->getOrientation());
|
||||||
|
@ -105,26 +105,43 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
||||||
Model::updateRig(deltaTime, parentTransform);
|
Model::updateRig(deltaTime, parentTransform);
|
||||||
if (_owningAvatar->isMyAvatar()) {
|
if (_owningAvatar->isMyAvatar()) {
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
|
Head* head = _owningAvatar->getHead();
|
||||||
|
|
||||||
Rig::HeadParameters params;
|
Rig::HeadParameters params;
|
||||||
params.modelRotation = getRotation();
|
params.modelRotation = getRotation();
|
||||||
params.modelTranslation = getTranslation();
|
params.modelTranslation = getTranslation();
|
||||||
params.leanSideways = _owningAvatar->getHead()->getFinalLeanSideways();
|
params.leanSideways = head->getFinalLeanSideways();
|
||||||
params.leanForward = _owningAvatar->getHead()->getFinalLeanForward();
|
params.leanForward = head->getFinalLeanForward();
|
||||||
params.torsoTwist = _owningAvatar->getHead()->getTorsoTwist();
|
params.torsoTwist = head->getTorsoTwist();
|
||||||
params.localHeadOrientation = _owningAvatar->getHead()->getFinalOrientationInLocalFrame();
|
params.localHeadOrientation = head->getFinalOrientationInLocalFrame();
|
||||||
params.worldHeadOrientation = _owningAvatar->getHead()->getFinalOrientationInWorldFrame();
|
params.worldHeadOrientation = head->getFinalOrientationInWorldFrame();
|
||||||
params.eyeLookAt = _owningAvatar->getHead()->getLookAtPosition();
|
params.eyeLookAt = head->getLookAtPosition();
|
||||||
params.eyeSaccade = _owningAvatar->getHead()->getSaccade();
|
params.eyeSaccade = head->getSaccade();
|
||||||
params.leanJointIndex = geometry.leanJointIndex;
|
params.leanJointIndex = geometry.leanJointIndex;
|
||||||
params.neckJointIndex = geometry.neckJointIndex;
|
params.neckJointIndex = geometry.neckJointIndex;
|
||||||
params.leftEyeJointIndex = geometry.leftEyeJointIndex;
|
params.leftEyeJointIndex = geometry.leftEyeJointIndex;
|
||||||
params.rightEyeJointIndex = geometry.rightEyeJointIndex;
|
params.rightEyeJointIndex = geometry.rightEyeJointIndex;
|
||||||
|
|
||||||
_rig->updateFromHeadParameters(params);
|
_rig->updateFromHeadParameters(params);
|
||||||
|
} else {
|
||||||
|
// This is a little more work than we really want.
|
||||||
|
//
|
||||||
|
// Other avatars joint, including their eyes, should already be set just like any other joints
|
||||||
|
// from the wire data. But when looking at me, we want the eyes to use the corrected lookAt.
|
||||||
|
//
|
||||||
|
// Thus this should really only be ... else if (_owningAvatar->getHead()->isLookingAtMe()) {...
|
||||||
|
// However, in the !isLookingAtMe case, the eyes aren't rotating the way they should right now.
|
||||||
|
// (They latch their looking at me position.) We will revisit that as priorities allow.
|
||||||
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
|
Head* head = _owningAvatar->getHead();
|
||||||
|
_rig->updateEyeJoints(geometry.leftEyeJointIndex, geometry.rightEyeJointIndex,
|
||||||
|
getTranslation(), getRotation(),
|
||||||
|
head->getFinalOrientationInWorldFrame(), head->getCorrectedLookAtPosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called by Avatar::simulate after it has set the joint states (fullUpdate true if changed),
|
||||||
|
// but just before head has been simulated.
|
||||||
void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
|
void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
|
||||||
setTranslation(_owningAvatar->getSkeletonPosition());
|
setTranslation(_owningAvatar->getSkeletonPosition());
|
||||||
static const glm::quat refOrientation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
|
static const glm::quat refOrientation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
|
|
@ -153,21 +153,20 @@ void EyeTracker::onStreamStarted() {
|
||||||
qCDebug(interfaceapp) << "Eye Tracker: Started streaming";
|
qCDebug(interfaceapp) << "Eye Tracker: Started streaming";
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Re-enable once saving / loading calibrations is working
|
if (_isStreaming) {
|
||||||
//if (_isStreaming) {
|
// Automatically load calibration if one has been saved.
|
||||||
// // Automatically load calibration if one has been saved.
|
QString availableCalibrations = QString(smi_getAvailableCalibrations());
|
||||||
// QString availableCalibrations = QString(smi_getAvailableCalibrations());
|
if (availableCalibrations.contains(HIGH_FIDELITY_EYE_TRACKER_CALIBRATION)) {
|
||||||
// if (availableCalibrations.contains(HIGH_FIDELITY_EYE_TRACKER_CALIBRATION)) {
|
result = smi_loadCalibration(HIGH_FIDELITY_EYE_TRACKER_CALIBRATION);
|
||||||
// result = smi_loadCalibration(HIGH_FIDELITY_EYE_TRACKER_CALIBRATION);
|
if (result != SMI_RET_SUCCESS) {
|
||||||
// if (result != SMI_RET_SUCCESS) {
|
qCWarning(interfaceapp) << "Eye Tracker: Error loading calibration:" << smiReturnValueToString(result);
|
||||||
// qCWarning(interfaceapp) << "Eye Tracker: Error loading calibration:" << smiReturnValueToString(result);
|
QMessageBox::warning(nullptr, "Eye Tracker Error", "Error loading calibration"
|
||||||
// QMessageBox::warning(nullptr, "Eye Tracker Error", "Error loading calibration"
|
+ smiReturnValueToString(result));
|
||||||
// + smiReturnValueToString(result));
|
} else {
|
||||||
// } else {
|
qCDebug(interfaceapp) << "Eye Tracker: Loaded calibration";
|
||||||
// qCDebug(interfaceapp) << "Eye Tracker: Loaded calibration";
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -260,11 +259,10 @@ void EyeTracker::calibrate(int points) {
|
||||||
if (result != SMI_RET_SUCCESS) {
|
if (result != SMI_RET_SUCCESS) {
|
||||||
qCWarning(interfaceapp) << "Eye Tracker: Error performing calibration:" << smiReturnValueToString(result);
|
qCWarning(interfaceapp) << "Eye Tracker: Error performing calibration:" << smiReturnValueToString(result);
|
||||||
} else {
|
} else {
|
||||||
// TODO: Re - enable once saving / loading calibrations is working
|
result = smi_saveCalibration(HIGH_FIDELITY_EYE_TRACKER_CALIBRATION);
|
||||||
//result = smi_saveCalibration(HIGH_FIDELITY_EYE_TRACKER_CALIBRATION);
|
if (result != SMI_RET_SUCCESS) {
|
||||||
//if (result != SMI_RET_SUCCESS) {
|
qCWarning(interfaceapp) << "Eye Tracker: Error saving calibration:" << smiReturnValueToString(result);
|
||||||
// qCWarning(interfaceapp) << "Eye Tracker: Error saving calibration:" << smiReturnValueToString(result);
|
}
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,11 +290,10 @@ QString EyeTracker::smiReturnValueToString(int value) {
|
||||||
return "Eye cameras not available";
|
return "Eye cameras not available";
|
||||||
case smi_ErrorReturnValue::SMI_ERROR_OCULUS_RUNTIME_NOT_SUPPORTED:
|
case smi_ErrorReturnValue::SMI_ERROR_OCULUS_RUNTIME_NOT_SUPPORTED:
|
||||||
return "Oculus runtime not supported";
|
return "Oculus runtime not supported";
|
||||||
// TODO: Re-enable once saving / loading calibrations is working
|
case smi_ErrorReturnValue::SMI_ERROR_FILE_NOT_FOUND:
|
||||||
//case smi_ErrorReturnValue::SMI_ERROR_FILE_NOT_FOUND:
|
return "File not found";
|
||||||
// return "File not found";
|
case smi_ErrorReturnValue::SMI_ERROR_FILE_EMPTY:
|
||||||
//case smi_ErrorReturnValue::SMI_ERROR_FILE_EMPTY:
|
return "File empty";
|
||||||
// return "File empty";
|
|
||||||
case smi_ErrorReturnValue::SMI_ERROR_UNKNOWN:
|
case smi_ErrorReturnValue::SMI_ERROR_UNKNOWN:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -114,6 +114,7 @@ void Stats::updateStats() {
|
||||||
STAT_UPDATE(avatarCount, avatarManager->size() - 1);
|
STAT_UPDATE(avatarCount, avatarManager->size() - 1);
|
||||||
STAT_UPDATE(serverCount, nodeList->size());
|
STAT_UPDATE(serverCount, nodeList->size());
|
||||||
STAT_UPDATE(framerate, (int)qApp->getFps());
|
STAT_UPDATE(framerate, (int)qApp->getFps());
|
||||||
|
STAT_UPDATE(simrate, (int)Application::getInstance()->getAverageSimsPerSecond());
|
||||||
|
|
||||||
auto bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
|
auto bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
|
||||||
STAT_UPDATE(packetInCount, bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond());
|
STAT_UPDATE(packetInCount, bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond());
|
||||||
|
|
|
@ -30,6 +30,7 @@ class Stats : public QQuickItem {
|
||||||
|
|
||||||
STATS_PROPERTY(int, serverCount, 0)
|
STATS_PROPERTY(int, serverCount, 0)
|
||||||
STATS_PROPERTY(int, framerate, 0)
|
STATS_PROPERTY(int, framerate, 0)
|
||||||
|
STATS_PROPERTY(int, simrate, 0)
|
||||||
STATS_PROPERTY(int, avatarCount, 0)
|
STATS_PROPERTY(int, avatarCount, 0)
|
||||||
STATS_PROPERTY(int, packetInCount, 0)
|
STATS_PROPERTY(int, packetInCount, 0)
|
||||||
STATS_PROPERTY(int, packetOutCount, 0)
|
STATS_PROPERTY(int, packetOutCount, 0)
|
||||||
|
@ -95,6 +96,7 @@ signals:
|
||||||
void timingExpandedChanged();
|
void timingExpandedChanged();
|
||||||
void serverCountChanged();
|
void serverCountChanged();
|
||||||
void framerateChanged();
|
void framerateChanged();
|
||||||
|
void simrateChanged();
|
||||||
void avatarCountChanged();
|
void avatarCountChanged();
|
||||||
void packetInCountChanged();
|
void packetInCountChanged();
|
||||||
void packetOutCountChanged();
|
void packetOutCountChanged();
|
||||||
|
|
|
@ -786,8 +786,8 @@ glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) {
|
||||||
void Rig::updateFromHeadParameters(const HeadParameters& params) {
|
void Rig::updateFromHeadParameters(const HeadParameters& params) {
|
||||||
updateLeanJoint(params.leanJointIndex, params.leanSideways, params.leanForward, params.torsoTwist);
|
updateLeanJoint(params.leanJointIndex, params.leanSideways, params.leanForward, params.torsoTwist);
|
||||||
updateNeckJoint(params.neckJointIndex, params.localHeadOrientation, params.leanSideways, params.leanForward, params.torsoTwist);
|
updateNeckJoint(params.neckJointIndex, params.localHeadOrientation, params.leanSideways, params.leanForward, params.torsoTwist);
|
||||||
updateEyeJoint(params.leftEyeJointIndex, params.modelTranslation, params.modelRotation, params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade);
|
updateEyeJoints(params.leftEyeJointIndex, params.rightEyeJointIndex, params.modelTranslation, params.modelRotation,
|
||||||
updateEyeJoint(params.rightEyeJointIndex, params.modelTranslation, params.modelRotation, params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade);
|
params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist) {
|
void Rig::updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist) {
|
||||||
|
@ -828,6 +828,11 @@ void Rig::updateNeckJoint(int index, const glm::quat& localHeadOrientation, floa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Rig::updateEyeJoints(int leftEyeIndex, int rightEyeIndex, const glm::vec3& modelTranslation, const glm::quat& modelRotation,
|
||||||
|
const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) {
|
||||||
|
updateEyeJoint(leftEyeIndex, modelTranslation, modelRotation, worldHeadOrientation, lookAtSpot, saccade);
|
||||||
|
updateEyeJoint(rightEyeIndex, modelTranslation, modelRotation, worldHeadOrientation, lookAtSpot, saccade);
|
||||||
|
}
|
||||||
void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) {
|
void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) {
|
||||||
if (index >= 0 && _jointStates[index].getParentIndex() >= 0) {
|
if (index >= 0 && _jointStates[index].getParentIndex() >= 0) {
|
||||||
auto& state = _jointStates[index];
|
auto& state = _jointStates[index];
|
||||||
|
|
|
@ -157,6 +157,8 @@ public:
|
||||||
void setEnableRig(bool isEnabled) { _enableRig = isEnabled; }
|
void setEnableRig(bool isEnabled) { _enableRig = isEnabled; }
|
||||||
|
|
||||||
void updateFromHeadParameters(const HeadParameters& params);
|
void updateFromHeadParameters(const HeadParameters& params);
|
||||||
|
void updateEyeJoints(int leftEyeIndex, int rightEyeIndex, const glm::vec3& modelTranslation, const glm::quat& modelRotation,
|
||||||
|
const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade = glm::vec3(0.0f));
|
||||||
|
|
||||||
virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation,
|
virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation,
|
||||||
float scale, float priority) = 0;
|
float scale, float priority) = 0;
|
||||||
|
|
|
@ -861,6 +861,8 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event, unsigned int device
|
||||||
if (entityScript.property("clickDownOnEntity").isValid()) {
|
if (entityScript.property("clickDownOnEntity").isValid()) {
|
||||||
entityScript.property("clickDownOnEntity").call(entityScript, entityScriptArgs);
|
entityScript.property("clickDownOnEntity").call(entityScript, entityScriptArgs);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
emit mousePressOffEntity(rayPickResult, event, deviceID);
|
||||||
}
|
}
|
||||||
_lastMouseEvent = MouseEvent(*event, deviceID);
|
_lastMouseEvent = MouseEvent(*event, deviceID);
|
||||||
_lastMouseEventValid = true;
|
_lastMouseEventValid = true;
|
||||||
|
|
|
@ -95,6 +95,7 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void mousePressOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
|
void mousePressOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
|
||||||
|
void mousePressOffEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
|
||||||
void mouseMoveOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
|
void mouseMoveOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
|
||||||
void mouseReleaseOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
|
void mouseReleaseOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,16 @@ RenderableWebEntityItem::~RenderableWebEntityItem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableWebEntityItem::render(RenderArgs* args) {
|
void RenderableWebEntityItem::render(RenderArgs* args) {
|
||||||
|
|
||||||
|
#ifdef WANT_EXTRA_DEBUGGING
|
||||||
|
{
|
||||||
|
gpu::Batch& batch = *args->_batch;
|
||||||
|
batch.setModelTransform(getTransformToCenter()); // we want to include the scale as well
|
||||||
|
glm::vec4 cubeColor{ 1.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(batch, 1.0f, cubeColor);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QOpenGLContext * currentContext = QOpenGLContext::currentContext();
|
QOpenGLContext * currentContext = QOpenGLContext::currentContext();
|
||||||
QSurface * currentSurface = currentContext->surface();
|
QSurface * currentSurface = currentContext->surface();
|
||||||
if (!_webSurface) {
|
if (!_webSurface) {
|
||||||
|
|
|
@ -36,9 +36,9 @@ void main(void) {
|
||||||
float inPositionY = (_inPosition.y - 0.5) / voxelVolumeSize.y;
|
float inPositionY = (_inPosition.y - 0.5) / voxelVolumeSize.y;
|
||||||
float inPositionZ = (_inPosition.z - 0.5) / voxelVolumeSize.z;
|
float inPositionZ = (_inPosition.z - 0.5) / voxelVolumeSize.z;
|
||||||
|
|
||||||
vec4 xyDiffuse = texture2D(xMap, vec2(-inPositionX, -inPositionY));
|
vec4 xyDiffuse = texture(xMap, vec2(-inPositionX, -inPositionY));
|
||||||
vec4 xzDiffuse = texture2D(yMap, vec2(-inPositionX, inPositionZ));
|
vec4 xzDiffuse = texture(yMap, vec2(-inPositionX, inPositionZ));
|
||||||
vec4 yzDiffuse = texture2D(zMap, vec2(inPositionZ, -inPositionY));
|
vec4 yzDiffuse = texture(zMap, vec2(inPositionZ, -inPositionY));
|
||||||
|
|
||||||
vec3 xyDiffuseScaled = xyDiffuse.rgb * abs(worldNormal.z);
|
vec3 xyDiffuseScaled = xyDiffuse.rgb * abs(worldNormal.z);
|
||||||
vec3 xzDiffuseScaled = xzDiffuse.rgb * abs(worldNormal.y);
|
vec3 xzDiffuseScaled = xzDiffuse.rgb * abs(worldNormal.y);
|
||||||
|
|
|
@ -154,9 +154,9 @@ public:
|
||||||
DEFINE_PROPERTY_REF(PROP_HREF, Href, href, QString);
|
DEFINE_PROPERTY_REF(PROP_HREF, Href, href, QString);
|
||||||
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString);
|
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString);
|
||||||
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
|
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
|
||||||
|
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
|
||||||
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>);
|
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>);
|
||||||
DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>);
|
DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>);
|
||||||
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
|
|
||||||
DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
|
DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
|
||||||
DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
|
DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
|
||||||
DEFINE_PROPERTY_REF(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString);
|
DEFINE_PROPERTY_REF(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString);
|
||||||
|
|
|
@ -170,9 +170,10 @@ bool PolyLineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
|
||||||
|
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
glm::vec3 point = points.at(i);
|
glm::vec3 point = points.at(i);
|
||||||
glm::vec3 pos = getPosition();
|
|
||||||
glm::vec3 halfBox = getDimensions() * 0.5f;
|
glm::vec3 halfBox = getDimensions() * 0.5f;
|
||||||
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) {
|
if ((point.x < - halfBox.x || point.x > halfBox.x) ||
|
||||||
|
(point.y < -halfBox.y || point.y > halfBox.y) ||
|
||||||
|
(point.z < - halfBox.z || point.z > halfBox.z)) {
|
||||||
qDebug() << "Point is outside entity's bounding box";
|
qDebug() << "Point is outside entity's bounding box";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1108,13 +1108,12 @@ ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex) {
|
||||||
if (subdata.name == "Materials") {
|
if (subdata.name == "Materials") {
|
||||||
materials = getIntVector(subdata);
|
materials = getIntVector(subdata);
|
||||||
} else if (subdata.name == "MappingInformationType") {
|
} else if (subdata.name == "MappingInformationType") {
|
||||||
if (subdata.properties.at(0) == "ByPolygon") {
|
if (subdata.properties.at(0) == "ByPolygon")
|
||||||
isMaterialPerPolygon = true;
|
isMaterialPerPolygon = true;
|
||||||
} else {
|
} else {
|
||||||
isMaterialPerPolygon = false;
|
isMaterialPerPolygon = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} else if (child.name == "LayerElementTexture") {
|
} else if (child.name == "LayerElementTexture") {
|
||||||
|
@ -1126,7 +1125,6 @@ ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool isMultiMaterial = false;
|
bool isMultiMaterial = false;
|
||||||
if (isMaterialPerPolygon) {
|
if (isMaterialPerPolygon) {
|
||||||
isMultiMaterial = true;
|
isMultiMaterial = true;
|
||||||
|
|
|
@ -123,9 +123,9 @@ public:
|
||||||
DepthTest(bool enabled = false, bool writeMask = true, ComparisonFunction func = LESS) :
|
DepthTest(bool enabled = false, bool writeMask = true, ComparisonFunction func = LESS) :
|
||||||
_function(func), _writeMask(writeMask), _enabled(enabled) {}
|
_function(func), _writeMask(writeMask), _enabled(enabled) {}
|
||||||
|
|
||||||
bool isEnabled() const { return _enabled; }
|
bool isEnabled() const { return _enabled != 0; }
|
||||||
ComparisonFunction getFunction() const { return ComparisonFunction(_function); }
|
ComparisonFunction getFunction() const { return ComparisonFunction(_function); }
|
||||||
bool getWriteMask() const { return _writeMask; }
|
uint8 getWriteMask() const { return _writeMask; }
|
||||||
|
|
||||||
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
|
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
|
||||||
DepthTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
DepthTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
||||||
|
@ -301,7 +301,7 @@ public:
|
||||||
DepthTest getDepthTest() const { return _values.depthTest; }
|
DepthTest getDepthTest() const { return _values.depthTest; }
|
||||||
|
|
||||||
bool isDepthTestEnabled() const { return getDepthTest().isEnabled(); }
|
bool isDepthTestEnabled() const { return getDepthTest().isEnabled(); }
|
||||||
bool getDepthTestWriteMask() const { return getDepthTest().getWriteMask(); }
|
uint8 getDepthTestWriteMask() const { return getDepthTest().getWriteMask(); }
|
||||||
ComparisonFunction getDepthTestFunc() const { return getDepthTest().getFunction(); }
|
ComparisonFunction getDepthTestFunc() const { return getDepthTest().getFunction(); }
|
||||||
|
|
||||||
// Stencil test
|
// Stencil test
|
||||||
|
|
|
@ -28,10 +28,11 @@ if (WIN32)
|
||||||
target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES})
|
target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#add_dependency_external_projects(Sixense)
|
add_dependency_external_projects(Sixense)
|
||||||
#find_package(Sixense REQUIRED)
|
find_package(Sixense REQUIRED)
|
||||||
#target_include_directories(${TARGET_NAME} PRIVATE ${SIXENSE_INCLUDE_DIRS})
|
target_include_directories(${TARGET_NAME} PRIVATE ${SIXENSE_INCLUDE_DIRS})
|
||||||
#target_link_libraries(${TARGET_NAME} ${SIXENSE_LIBRARIES})
|
target_link_libraries(${TARGET_NAME} ${SIXENSE_LIBRARIES})
|
||||||
|
message( ${SIXENSE_INCLUDE_DIRS})
|
||||||
|
|
||||||
# perform standard include and linking for found externals
|
# perform standard include and linking for found externals
|
||||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||||
|
|
|
@ -92,7 +92,7 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
|
||||||
// dQ = Q1 * Q0^
|
// dQ = Q1 * Q0^
|
||||||
btQuaternion deltaQ = target * bodyRotation.inverse();
|
btQuaternion deltaQ = target * bodyRotation.inverse();
|
||||||
float angle = deltaQ.getAngle();
|
float angle = deltaQ.getAngle();
|
||||||
const float MIN_ANGLE = 1.0e-4;
|
const float MIN_ANGLE = 1.0e-4f;
|
||||||
if (angle > MIN_ANGLE) {
|
if (angle > MIN_ANGLE) {
|
||||||
targetVelocity = (angle / _angularTimeScale) * deltaQ.getAxis();
|
targetVelocity = (angle / _angularTimeScale) * deltaQ.getAxis();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1808,7 +1808,6 @@ void Model::segregateMeshGroups() {
|
||||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||||
const MeshState& state = _meshStates.at(i);
|
const MeshState& state = _meshStates.at(i);
|
||||||
|
|
||||||
|
|
||||||
bool translucentMesh = networkMesh.getTranslucentPartCount(mesh) == networkMesh.parts.size();
|
bool translucentMesh = networkMesh.getTranslucentPartCount(mesh) == networkMesh.parts.size();
|
||||||
bool hasTangents = !mesh.tangents.isEmpty();
|
bool hasTangents = !mesh.tangents.isEmpty();
|
||||||
bool hasSpecular = mesh.hasSpecularTexture();
|
bool hasSpecular = mesh.hasSpecularTexture();
|
||||||
|
|
|
@ -44,7 +44,7 @@ const int16_t COLLISION_GROUP_OTHER_AVATAR = 1 << 6;
|
||||||
const int16_t COLLISION_GROUP_MY_ATTACHMENT = 1 << 7;
|
const int16_t COLLISION_GROUP_MY_ATTACHMENT = 1 << 7;
|
||||||
const int16_t COLLISION_GROUP_OTHER_ATTACHMENT = 1 << 8;
|
const int16_t COLLISION_GROUP_OTHER_ATTACHMENT = 1 << 8;
|
||||||
// ...
|
// ...
|
||||||
const int16_t COLLISION_GROUP_COLLISIONLESS = 1 << 15;
|
const int16_t COLLISION_GROUP_COLLISIONLESS = 1 << 14;
|
||||||
|
|
||||||
|
|
||||||
/* Note: In order for objectA to collide with objectB at the filter stage
|
/* Note: In order for objectA to collide with objectB at the filter stage
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
|
||||||
|
#include <GLHelpers.h>
|
||||||
|
|
||||||
#include "../model/Skybox_vert.h"
|
#include "../model/Skybox_vert.h"
|
||||||
#include "../model/Skybox_frag.h"
|
#include "../model/Skybox_frag.h"
|
||||||
|
|
||||||
|
@ -112,85 +114,22 @@
|
||||||
#include "paintStroke_vert.h"
|
#include "paintStroke_vert.h"
|
||||||
#include "paintStroke_frag.h"
|
#include "paintStroke_frag.h"
|
||||||
|
|
||||||
class RateCounter {
|
#include "polyvox_vert.h"
|
||||||
std::vector<float> times;
|
#include "polyvox_frag.h"
|
||||||
QElapsedTimer timer;
|
|
||||||
public:
|
|
||||||
RateCounter() {
|
|
||||||
timer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
times.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int count() const {
|
|
||||||
return times.size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
float elapsed() const {
|
|
||||||
if (times.size() < 1) {
|
|
||||||
return 0.0f;
|
|
||||||
}
|
|
||||||
float elapsed = *times.rbegin() - *times.begin();
|
|
||||||
return elapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment() {
|
|
||||||
times.push_back(timer.elapsed() / 1000.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
float rate() const {
|
|
||||||
if (elapsed() == 0.0f) {
|
|
||||||
return 0.0f;
|
|
||||||
}
|
|
||||||
return (float) count() / elapsed();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const QString& getQmlDir() {
|
|
||||||
static QString dir;
|
|
||||||
if (dir.isEmpty()) {
|
|
||||||
QDir path(__FILE__);
|
|
||||||
path.cdUp();
|
|
||||||
dir = path.cleanPath(path.absoluteFilePath("../../../interface/resources/qml/")) + "/";
|
|
||||||
qDebug() << "Qml Path: " << dir;
|
|
||||||
}
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a simple OpenGL window that renders text in various ways
|
// Create a simple OpenGL window that renders text in various ways
|
||||||
class QTestWindow : public QWindow {
|
class QTestWindow : public QWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
QOpenGLContext* _context{ nullptr };
|
QOpenGLContext* _context{ nullptr };
|
||||||
QSize _size;
|
|
||||||
//TextRenderer* _textRenderer[4];
|
|
||||||
RateCounter fps;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void renderText();
|
void renderText();
|
||||||
|
|
||||||
private:
|
|
||||||
void resizeWindow(const QSize& size) {
|
|
||||||
_size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QTestWindow() {
|
QTestWindow() {
|
||||||
setSurfaceType(QSurface::OpenGLSurface);
|
setSurfaceType(QSurface::OpenGLSurface);
|
||||||
|
QSurfaceFormat format = getDefaultOpenGlSurfaceFormat();
|
||||||
QSurfaceFormat format;
|
|
||||||
// Qt Quick may need a depth and stencil buffer. Always make sure these are available.
|
|
||||||
format.setDepthBufferSize(16);
|
|
||||||
format.setStencilBufferSize(8);
|
|
||||||
format.setVersion(4, 1);
|
|
||||||
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
|
|
||||||
format.setOption(QSurfaceFormat::DebugContext);
|
|
||||||
|
|
||||||
setFormat(format);
|
setFormat(format);
|
||||||
|
|
||||||
_context = new QOpenGLContext;
|
_context = new QOpenGLContext;
|
||||||
_context->setFormat(format);
|
_context->setFormat(format);
|
||||||
_context->create();
|
_context->create();
|
||||||
|
@ -199,8 +138,6 @@ public:
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
|
|
||||||
gpu::Context::init<gpu::GLBackend>();
|
gpu::Context::init<gpu::GLBackend>();
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
QOpenGLDebugLogger* logger = new QOpenGLDebugLogger(this);
|
QOpenGLDebugLogger* logger = new QOpenGLDebugLogger(this);
|
||||||
logger->initialize(); // initializes in the current context, i.e. ctx
|
logger->initialize(); // initializes in the current context, i.e. ctx
|
||||||
|
@ -208,25 +145,8 @@ public:
|
||||||
connect(logger, &QOpenGLDebugLogger::messageLogged, this, [&](const QOpenGLDebugMessage & debugMessage) {
|
connect(logger, &QOpenGLDebugLogger::messageLogged, this, [&](const QOpenGLDebugMessage & debugMessage) {
|
||||||
qDebug() << debugMessage;
|
qDebug() << debugMessage;
|
||||||
});
|
});
|
||||||
// logger->startLogging(QOpenGLDebugLogger::SynchronousLogging);
|
|
||||||
}
|
}
|
||||||
qDebug() << (const char*)glGetString(GL_VERSION);
|
|
||||||
|
|
||||||
//_textRenderer[0] = TextRenderer::getInstance(SANS_FONT_FAMILY, 12, false);
|
|
||||||
//_textRenderer[1] = TextRenderer::getInstance(SERIF_FONT_FAMILY, 12, false,
|
|
||||||
// TextRenderer::SHADOW_EFFECT);
|
|
||||||
//_textRenderer[2] = TextRenderer::getInstance(MONO_FONT_FAMILY, 48, -1,
|
|
||||||
// false, TextRenderer::OUTLINE_EFFECT);
|
|
||||||
//_textRenderer[3] = TextRenderer::getInstance(INCONSOLATA_FONT_FAMILY, 24);
|
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
glClearColor(0.2f, 0.2f, 0.2f, 1);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
|
|
||||||
// setFramePosition(QPoint(-1000, 0));
|
|
||||||
resize(QSize(800, 600));
|
resize(QSize(800, 600));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,18 +157,15 @@ public:
|
||||||
void makeCurrent() {
|
void makeCurrent() {
|
||||||
_context->makeCurrent(this);
|
_context->makeCurrent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
void resizeEvent(QResizeEvent* ev) override {
|
|
||||||
resizeWindow(ev->size());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void testShaderBuild(const char* vs_src, const char * fs_src) {
|
void testShaderBuild(const char* vs_src, const char * fs_src) {
|
||||||
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(vs_src)));
|
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(vs_src)));
|
||||||
auto fs = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(fs_src)));
|
auto fs = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(fs_src)));
|
||||||
auto pr = gpu::ShaderPointer(gpu::Shader::createProgram(vs, fs));
|
auto pr = gpu::ShaderPointer(gpu::Shader::createProgram(vs, fs));
|
||||||
gpu::Shader::makeProgram(*pr);
|
if (!gpu::Shader::makeProgram(*pr)) {
|
||||||
|
throw std::runtime_error("Failed to compile shader");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestWindow::draw() {
|
void QTestWindow::draw() {
|
||||||
|
@ -257,8 +174,8 @@ void QTestWindow::draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
|
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glViewport(0, 0, _size.width() * devicePixelRatio(), _size.height() * devicePixelRatio());
|
|
||||||
|
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
std::call_once(once, [&]{
|
std::call_once(once, [&]{
|
||||||
|
@ -328,17 +245,10 @@ void QTestWindow::draw() {
|
||||||
testShaderBuild(Skybox_vert, Skybox_frag);
|
testShaderBuild(Skybox_vert, Skybox_frag);
|
||||||
|
|
||||||
testShaderBuild(paintStroke_vert,paintStroke_frag);
|
testShaderBuild(paintStroke_vert,paintStroke_frag);
|
||||||
|
testShaderBuild(polyvox_vert, polyvox_frag);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
_context->swapBuffers(this);
|
_context->swapBuffers(this);
|
||||||
glFinish();
|
|
||||||
|
|
||||||
fps.increment();
|
|
||||||
if (fps.elapsed() >= 2.0f) {
|
|
||||||
qDebug() << "FPS: " << fps.rate();
|
|
||||||
fps.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
||||||
|
@ -352,7 +262,6 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char * LOG_FILTER_RULES = R"V0G0N(
|
const char * LOG_FILTER_RULES = R"V0G0N(
|
||||||
hifi.gpu=true
|
hifi.gpu=true
|
||||||
)V0G0N";
|
)V0G0N";
|
||||||
|
|
Loading…
Reference in a new issue