mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-22 21:06:27 +02:00
Merge branch 'master' into 20855
This commit is contained in:
commit
f85b7696b3
40 changed files with 417 additions and 180 deletions
|
@ -369,14 +369,6 @@ void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) {
|
||||||
reverbTime = _zoneReverbSettings[i].reverbTime;
|
reverbTime = _zoneReverbSettings[i].reverbTime;
|
||||||
wetLevel = _zoneReverbSettings[i].wetLevel;
|
wetLevel = _zoneReverbSettings[i].wetLevel;
|
||||||
|
|
||||||
// Modulate wet level with distance to wall
|
|
||||||
float MIN_ATTENUATION_DISTANCE = 2.0f;
|
|
||||||
float MAX_ATTENUATION = -12; // dB
|
|
||||||
glm::vec3 distanceToWalls = (box.getDimensions() / 2.0f) - glm::abs(streamPosition - box.calcCenter());
|
|
||||||
float distanceToClosestWall = glm::min(distanceToWalls.x, distanceToWalls.z);
|
|
||||||
if (distanceToClosestWall < MIN_ATTENUATION_DISTANCE) {
|
|
||||||
wetLevel += MAX_ATTENUATION * (1.0f - distanceToClosestWall / MIN_ATTENUATION_DISTANCE);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
cmake/externals/openvr/CMakeLists.txt
vendored
4
cmake/externals/openvr/CMakeLists.txt
vendored
|
@ -7,8 +7,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||||
|
|
||||||
ExternalProject_Add(
|
ExternalProject_Add(
|
||||||
${EXTERNAL_NAME}
|
${EXTERNAL_NAME}
|
||||||
URL https://github.com/ValveSoftware/openvr/archive/v0.9.15.zip
|
URL https://github.com/ValveSoftware/openvr/archive/v0.9.19.zip
|
||||||
URL_MD5 0ff8560b49b6da1150fcc47360e8ceca
|
URL_MD5 843f9dde488584d8af1f3ecf2252b4e0
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND ""
|
BUILD_COMMAND ""
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
|
|
|
@ -308,7 +308,7 @@
|
||||||
"name": "reverb",
|
"name": "reverb",
|
||||||
"type": "table",
|
"type": "table",
|
||||||
"label": "Reverb Settings",
|
"label": "Reverb Settings",
|
||||||
"help": "In this table you can set reverb levels for audio zones. For a medium-sized (e.g., 100 square meter) meeting room, try a decay time of around 1.5 seconds and a wet level of -10 db. For an airplane hangar or cathedral, try a decay time of 4 seconds and a wet level of -5 db.",
|
"help": "In this table you can set reverb levels for audio zones. For a medium-sized (e.g., 100 square meter) meeting room, try a decay time of around 1.5 seconds and a wet/dry mix of 25%. For an airplane hangar or cathedral, try a decay time of 4 seconds and a wet/dry mix of 50%.",
|
||||||
"numbered": true,
|
"numbered": true,
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
|
@ -325,9 +325,9 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "wet_level",
|
"name": "wet_level",
|
||||||
"label": "Wet Level",
|
"label": "Wet/Dry Mix",
|
||||||
"can_set": true,
|
"can_set": true,
|
||||||
"placeholder": "(in db)"
|
"placeholder": "(in percent)"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -461,6 +461,37 @@
|
||||||
|
|
||||||
var elPreviewCameraButton = document.getElementById("preview-camera-button");
|
var elPreviewCameraButton = document.getElementById("preview-camera-button");
|
||||||
|
|
||||||
|
var urlUpdaters = document.getElementsByClassName("update-url-version");
|
||||||
|
var PARAM_REGEXP = /(?:\?)(\S+)/; // Check if this has any parameters.
|
||||||
|
var TIMESTAMP_REGEXP = /(&?HFTime=\d+)/;
|
||||||
|
|
||||||
|
var refreshEvent = function(event){
|
||||||
|
var urlElement = event.target.parentElement.getElementsByClassName("url")[0];
|
||||||
|
var content = urlElement.value;
|
||||||
|
var date = new Date();
|
||||||
|
var timeStamp = date.getTime();
|
||||||
|
|
||||||
|
if(content.length > 0){
|
||||||
|
if(PARAM_REGEXP.test(content)){
|
||||||
|
// Has params, so lets remove existing definition and append again.
|
||||||
|
content = content.replace(TIMESTAMP_REGEXP,"") + "&";
|
||||||
|
}else{
|
||||||
|
content += "?";
|
||||||
|
}
|
||||||
|
content = content.replace("?&","?");
|
||||||
|
urlElement.value = content + "HFTime=" + timeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
var evt = document.createEvent("HTMLEvents");
|
||||||
|
evt.initEvent("change", true, true );
|
||||||
|
urlElement.dispatchEvent(evt);
|
||||||
|
};
|
||||||
|
|
||||||
|
for(var index = 0; index < urlUpdaters.length; index++){
|
||||||
|
var urlUpdater = urlUpdaters[index];
|
||||||
|
urlUpdater.addEventListener("click", refreshEvent);
|
||||||
|
}
|
||||||
|
|
||||||
if (window.EventBridge !== undefined) {
|
if (window.EventBridge !== undefined) {
|
||||||
var properties;
|
var properties;
|
||||||
EventBridge.scriptEventReceived.connect(function(data) {
|
EventBridge.scriptEventReceived.connect(function(data) {
|
||||||
|
@ -1195,6 +1226,7 @@
|
||||||
<div class="label">Ambient URL</div>
|
<div class="label">Ambient URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input type="text" id="property-zone-key-ambient-url" class="url">
|
<input type="text" id="property-zone-key-ambient-url" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1272,6 +1304,7 @@
|
||||||
<div class="label">Skybox URL</div>
|
<div class="label">Skybox URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input type="text" id="property-zone-skybox-url" class="url">
|
<input type="text" id="property-zone-skybox-url" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1283,6 +1316,7 @@
|
||||||
<div class="label">Source URL</div>
|
<div class="label">Source URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input type="text" id="property-web-source-url" class="url">
|
<input type="text" id="property-web-source-url" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1296,12 +1330,14 @@
|
||||||
<div class="label">Href - Hifi://address</div>
|
<div class="label">Href - Hifi://address</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input id="property-hyperlink-href" class="url">
|
<input id="property-hyperlink-href" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="hyperlink-section property">
|
<div class="hyperlink-section property">
|
||||||
<div class="label">Description</div>
|
<div class="label">Description</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input id="property-hyperlink-description" class="url">
|
<input id="property-hyperlink-description" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1385,16 +1421,19 @@
|
||||||
<div class="label">X-axis Texture URL</div>
|
<div class="label">X-axis Texture URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input type="text" id="property-x-texture-url" class="url">
|
<input type="text" id="property-x-texture-url" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="label">Y-axis Texture URL</div>
|
<div class="label">Y-axis Texture URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input type="text" id="property-y-texture-url" class="url">
|
<input type="text" id="property-y-texture-url" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="label">Z-axis Texture URL</div>
|
<div class="label">Z-axis Texture URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input type="text" id="property-z-texture-url" class="url">
|
<input type="text" id="property-z-texture-url" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1576,6 +1615,7 @@
|
||||||
<div class="label">Collision Sound URL</div>
|
<div class="label">Collision Sound URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input id="property-collision-sound-url" class="url">
|
<input id="property-collision-sound-url" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1593,6 +1633,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input id="property-script-url" class="url">
|
<input id="property-script-url" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1605,6 +1646,7 @@
|
||||||
<div class="label">Model URL</div>
|
<div class="label">Model URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input type="text" id="property-model-url" class="url">
|
<input type="text" id="property-model-url" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1623,12 +1665,14 @@
|
||||||
<div class="label">Compound Shape URL</div>
|
<div class="label">Compound Shape URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input type="text" id="property-compound-shape-url" class="url">
|
<input type="text" id="property-compound-shape-url" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="model-section property">
|
<div class="model-section property">
|
||||||
<div class="label">Animation URL</div>
|
<div class="label">Animation URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input type="text" id="property-model-animation-url" class="url">
|
<input type="text" id="property-model-animation-url" class="url">
|
||||||
|
<div class="update-url-version"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="model-section property">
|
<div class="model-section property">
|
||||||
|
|
|
@ -134,8 +134,18 @@ textarea {
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.update-url-version{
|
||||||
|
width:17px;
|
||||||
|
height:17px;
|
||||||
|
float:right;
|
||||||
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAQAAACRZI9xAAABAUlEQVQoz33RvyvEARjH8SdlUX6UbhFJfgwmE3aTxWEiitxqN/gH7IxCKTcymLiJFIOJsihiUKcrCYnuXoZv+F45n2d4lvfz6fPpCSFs6BO1JllvLmXk5F37dC0vJ5NGmlBxoFp7Rn6RDpRRtG5KtynrijhLoBBGQcllKkFWAXsyCbKEFxeGqmJmFZFLkE639vX+12hCSVft0nUR8RbLcRN/aSHGIqL2tVYPconL32qLtaiL88Rl0qtXc+pTDv1OPGMlidtgS8Wp2RR05FEFM98/GlRQ9mTHvB7jVt2rKGPAT9xh2z6qfnToHV1SjZpN23Tl051di1oco9W/pdttaBRfEhFXOZV7vEsAAAAASUVORK5CYII=);
|
||||||
|
padding:0 !important;
|
||||||
|
margin:0 2px 0 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
input.url {
|
input.url {
|
||||||
width: 100%;
|
width:85%;
|
||||||
|
padding-right: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.coord {
|
input.coord {
|
||||||
|
|
|
@ -1415,7 +1415,7 @@ void Application::paintGL() {
|
||||||
_lastFramesPerSecondUpdate = now;
|
_lastFramesPerSecondUpdate = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE_EX(__FUNCTION__, 0xff0000ff, (uint64_t)_frameCount);
|
||||||
PerformanceTimer perfTimer("paintGL");
|
PerformanceTimer perfTimer("paintGL");
|
||||||
|
|
||||||
if (nullptr == _displayPlugin) {
|
if (nullptr == _displayPlugin) {
|
||||||
|
@ -2554,11 +2554,12 @@ void Application::idle(uint64_t now) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
|
|
||||||
// We're going to execute idle processing, so restart the last idle timer
|
// We're going to execute idle processing, so restart the last idle timer
|
||||||
_lastTimeUpdated.start();
|
_lastTimeUpdated.start();
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
|
||||||
static uint64_t lastIdleStart{ now };
|
static uint64_t lastIdleStart{ now };
|
||||||
uint64_t idleStartToStartDuration = now - lastIdleStart;
|
uint64_t idleStartToStartDuration = now - lastIdleStart;
|
||||||
if (idleStartToStartDuration != 0) {
|
if (idleStartToStartDuration != 0) {
|
||||||
|
@ -3146,6 +3147,9 @@ void Application::updateDialogs(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::update(float deltaTime) {
|
void Application::update(float deltaTime) {
|
||||||
|
|
||||||
|
PROFILE_RANGE_EX(__FUNCTION__, 0xffff0000, (uint64_t)_frameCount + 1);
|
||||||
|
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::update()");
|
PerformanceWarning warn(showWarnings, "Application::update()");
|
||||||
|
|
||||||
|
@ -3246,9 +3250,13 @@ void Application::update(float deltaTime) {
|
||||||
QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>();
|
QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>();
|
||||||
|
|
||||||
if (_physicsEnabled) {
|
if (_physicsEnabled) {
|
||||||
|
PROFILE_RANGE_EX("Physics", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
|
|
||||||
PerformanceTimer perfTimer("physics");
|
PerformanceTimer perfTimer("physics");
|
||||||
|
|
||||||
{
|
{
|
||||||
|
PROFILE_RANGE_EX("UpdateStats", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
|
|
||||||
PerformanceTimer perfTimer("updateStates)");
|
PerformanceTimer perfTimer("updateStates)");
|
||||||
static VectorOfMotionStates motionStates;
|
static VectorOfMotionStates motionStates;
|
||||||
_entitySimulation.getObjectsToRemoveFromPhysics(motionStates);
|
_entitySimulation.getObjectsToRemoveFromPhysics(motionStates);
|
||||||
|
@ -3281,12 +3289,14 @@ void Application::update(float deltaTime) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
PROFILE_RANGE_EX("StepSimulation", 0xffff8000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
PerformanceTimer perfTimer("stepSimulation");
|
PerformanceTimer perfTimer("stepSimulation");
|
||||||
getEntities()->getTree()->withWriteLock([&] {
|
getEntities()->getTree()->withWriteLock([&] {
|
||||||
_physicsEngine->stepSimulation();
|
_physicsEngine->stepSimulation();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
PROFILE_RANGE_EX("HarvestChanges", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
PerformanceTimer perfTimer("havestChanges");
|
PerformanceTimer perfTimer("havestChanges");
|
||||||
if (_physicsEngine->hasOutgoingChanges()) {
|
if (_physicsEngine->hasOutgoingChanges()) {
|
||||||
getEntities()->getTree()->withWriteLock([&] {
|
getEntities()->getTree()->withWriteLock([&] {
|
||||||
|
@ -3321,17 +3331,24 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
qApp->setAvatarSimrateSample(1.0f / deltaTime);
|
qApp->setAvatarSimrateSample(1.0f / deltaTime);
|
||||||
|
|
||||||
avatarManager->updateOtherAvatars(deltaTime);
|
{
|
||||||
|
PROFILE_RANGE_EX("OtherAvatars", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
|
avatarManager->updateOtherAvatars(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
qApp->updateMyAvatarLookAtPosition();
|
qApp->updateMyAvatarLookAtPosition();
|
||||||
|
|
||||||
// update sensorToWorldMatrix for camera and hand controllers
|
// update sensorToWorldMatrix for camera and hand controllers
|
||||||
myAvatar->updateSensorToWorldMatrix();
|
myAvatar->updateSensorToWorldMatrix();
|
||||||
|
|
||||||
avatarManager->updateMyAvatar(deltaTime);
|
{
|
||||||
|
PROFILE_RANGE_EX("MyAvatar", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
|
avatarManager->updateMyAvatar(deltaTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
PROFILE_RANGE_EX("Overlays", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
PerformanceTimer perfTimer("overlays");
|
PerformanceTimer perfTimer("overlays");
|
||||||
_overlays.update(deltaTime);
|
_overlays.update(deltaTime);
|
||||||
}
|
}
|
||||||
|
@ -3351,6 +3368,7 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
// Update my voxel servers with my current voxel query...
|
// Update my voxel servers with my current voxel query...
|
||||||
{
|
{
|
||||||
|
PROFILE_RANGE_EX("QueryOctree", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
PerformanceTimer perfTimer("queryOctree");
|
PerformanceTimer perfTimer("queryOctree");
|
||||||
quint64 sinceLastQuery = now - _lastQueriedTime;
|
quint64 sinceLastQuery = now - _lastQueriedTime;
|
||||||
const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND;
|
const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND;
|
||||||
|
@ -4677,13 +4695,18 @@ qreal Application::getDevicePixelRatio() {
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayPlugin* Application::getActiveDisplayPlugin() {
|
DisplayPlugin* Application::getActiveDisplayPlugin() {
|
||||||
std::unique_lock<std::recursive_mutex> lock(_displayPluginLock);
|
DisplayPlugin* result = nullptr;
|
||||||
if (nullptr == _displayPlugin && QThread::currentThread() == thread()) {
|
if (QThread::currentThread() == thread()) {
|
||||||
updateDisplayMode();
|
if (nullptr == _displayPlugin) {
|
||||||
Q_ASSERT(_displayPlugin);
|
updateDisplayMode();
|
||||||
|
Q_ASSERT(_displayPlugin);
|
||||||
|
}
|
||||||
|
result = _displayPlugin.get();
|
||||||
|
} else {
|
||||||
|
std::unique_lock<std::mutex> lock(_displayPluginLock);
|
||||||
|
result = _displayPlugin.get();
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
return _displayPlugin.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DisplayPlugin* Application::getActiveDisplayPlugin() const {
|
const DisplayPlugin* Application::getActiveDisplayPlugin() const {
|
||||||
|
@ -4801,20 +4824,26 @@ void Application::updateDisplayMode() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_displayPlugin) {
|
|
||||||
_displayPlugin->deactivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
|
||||||
// FIXME probably excessive and useless context switching
|
// Make the switch atomic from the perspective of other threads
|
||||||
_offscreenContext->makeCurrent();
|
{
|
||||||
newDisplayPlugin->activate();
|
std::unique_lock<std::mutex> lock(_displayPluginLock);
|
||||||
_offscreenContext->makeCurrent();
|
|
||||||
offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));
|
if (_displayPlugin) {
|
||||||
_offscreenContext->makeCurrent();
|
_displayPlugin->deactivate();
|
||||||
getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
|
}
|
||||||
_displayPlugin = newDisplayPlugin;
|
|
||||||
|
// FIXME probably excessive and useless context switching
|
||||||
|
_offscreenContext->makeCurrent();
|
||||||
|
newDisplayPlugin->activate();
|
||||||
|
_offscreenContext->makeCurrent();
|
||||||
|
offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));
|
||||||
|
_offscreenContext->makeCurrent();
|
||||||
|
getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
|
||||||
|
_displayPlugin = newDisplayPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
emit activeDisplayPluginChanged();
|
emit activeDisplayPluginChanged();
|
||||||
|
|
||||||
|
|
|
@ -383,7 +383,7 @@ private:
|
||||||
|
|
||||||
OffscreenGLCanvas* _offscreenContext { nullptr };
|
OffscreenGLCanvas* _offscreenContext { nullptr };
|
||||||
DisplayPluginPointer _displayPlugin;
|
DisplayPluginPointer _displayPlugin;
|
||||||
std::recursive_mutex _displayPluginLock;
|
std::mutex _displayPluginLock;
|
||||||
InputPluginList _activeInputPlugins;
|
InputPluginList _activeInputPlugins;
|
||||||
|
|
||||||
bool _activatingDisplayPlugin { false };
|
bool _activatingDisplayPlugin { false };
|
||||||
|
|
|
@ -187,7 +187,7 @@ void Avatar::simulate(float deltaTime) {
|
||||||
|
|
||||||
// simple frustum check
|
// simple frustum check
|
||||||
float boundingRadius = getBoundingRadius();
|
float boundingRadius = getBoundingRadius();
|
||||||
bool inView = qApp->getViewFrustum()->sphereIntersectsFrustum(getPosition(), boundingRadius);
|
bool inView = qApp->getDisplayViewFrustum()->sphereIntersectsFrustum(getPosition(), boundingRadius);
|
||||||
|
|
||||||
if (_shouldAnimate && !_shouldSkipRender && inView) {
|
if (_shouldAnimate && !_shouldSkipRender && inView) {
|
||||||
{
|
{
|
||||||
|
|
|
@ -231,6 +231,13 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
||||||
|
|
||||||
_leftEyePosition = _rightEyePosition = getPosition();
|
_leftEyePosition = _rightEyePosition = getPosition();
|
||||||
_eyePosition = calculateAverageEyePosition();
|
_eyePosition = calculateAverageEyePosition();
|
||||||
|
|
||||||
|
if (!billboard && _owningAvatar) {
|
||||||
|
auto skeletonModel = static_cast<Avatar*>(_owningAvatar)->getSkeletonModel();
|
||||||
|
if (skeletonModel) {
|
||||||
|
skeletonModel->getEyePositions(_leftEyePosition, _rightEyePosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::calculateMouthShapes() {
|
void Head::calculateMouthShapes() {
|
||||||
|
|
|
@ -897,7 +897,9 @@ void MyAvatar::updateLookAtTargetAvatar() {
|
||||||
// Scale by proportional differences between avatar and human.
|
// Scale by proportional differences between avatar and human.
|
||||||
float humanEyeSeparationInModelSpace = glm::length(humanLeftEye - humanRightEye) * ipdScale;
|
float humanEyeSeparationInModelSpace = glm::length(humanLeftEye - humanRightEye) * ipdScale;
|
||||||
float avatarEyeSeparation = glm::length(avatarLeftEye - avatarRightEye);
|
float avatarEyeSeparation = glm::length(avatarLeftEye - avatarRightEye);
|
||||||
gazeOffset = gazeOffset * humanEyeSeparationInModelSpace / avatarEyeSeparation;
|
if (avatarEyeSeparation > 0.0f) {
|
||||||
|
gazeOffset = gazeOffset * humanEyeSeparationInModelSpace / avatarEyeSeparation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// And now we can finally add that offset to the camera.
|
// And now we can finally add that offset to the camera.
|
||||||
|
|
|
@ -611,7 +611,7 @@ AnimNode::Pointer AnimNodeLoader::load(const QByteArray& contents, const QUrl& j
|
||||||
return loadNode(rootVal.toObject(), jsonUrl);
|
return loadNode(rootVal.toObject(), jsonUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimNodeLoader::onRequestDone(const QByteArray& data) {
|
void AnimNodeLoader::onRequestDone(const QByteArray data) {
|
||||||
auto node = load(data, _url);
|
auto node = load(data, _url);
|
||||||
if (node) {
|
if (node) {
|
||||||
emit success(node);
|
emit success(node);
|
||||||
|
|
|
@ -36,7 +36,7 @@ protected:
|
||||||
static AnimNode::Pointer load(const QByteArray& contents, const QUrl& jsonUrl);
|
static AnimNode::Pointer load(const QByteArray& contents, const QUrl& jsonUrl);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onRequestDone(const QByteArray& data);
|
void onRequestDone(const QByteArray data);
|
||||||
void onRequestError(QNetworkReply::NetworkError error);
|
void onRequestError(QNetworkReply::NetworkError error);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <GeometryUtil.h>
|
#include <GeometryUtil.h>
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
#include <DebugDraw.h>
|
#include <DebugDraw.h>
|
||||||
|
#include <shared/NsightHelpers.h>
|
||||||
|
|
||||||
#include "AnimationLogging.h"
|
#include "AnimationLogging.h"
|
||||||
#include "AnimClip.h"
|
#include "AnimClip.h"
|
||||||
|
@ -852,6 +853,8 @@ void Rig::updateAnimationStateHandlers() { // called on avatar update thread (wh
|
||||||
|
|
||||||
void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) {
|
void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) {
|
||||||
|
|
||||||
|
PROFILE_RANGE_EX(__FUNCTION__, 0xffff00ff, 0);
|
||||||
|
|
||||||
setModelOffset(rootTransform);
|
setModelOffset(rootTransform);
|
||||||
|
|
||||||
if (_animNode) {
|
if (_animNode) {
|
||||||
|
|
|
@ -565,10 +565,10 @@ void AudioClient::updateReverbOptions() {
|
||||||
_zoneReverbOptions.setReverbTime(_receivedAudioStream.getRevebTime());
|
_zoneReverbOptions.setReverbTime(_receivedAudioStream.getRevebTime());
|
||||||
reverbChanged = true;
|
reverbChanged = true;
|
||||||
}
|
}
|
||||||
//if (_zoneReverbOptions.getWetLevel() != _receivedAudioStream.getWetLevel()) {
|
if (_zoneReverbOptions.getWetDryMix() != _receivedAudioStream.getWetLevel()) {
|
||||||
// _zoneReverbOptions.setWetLevel(_receivedAudioStream.getWetLevel());
|
_zoneReverbOptions.setWetDryMix(_receivedAudioStream.getWetLevel());
|
||||||
// reverbChanged = true;
|
reverbChanged = true;
|
||||||
//}
|
}
|
||||||
|
|
||||||
if (_reverbOptions != &_zoneReverbOptions) {
|
if (_reverbOptions != &_zoneReverbOptions) {
|
||||||
_reverbOptions = &_zoneReverbOptions;
|
_reverbOptions = &_zoneReverbOptions;
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include <gl/GLWidget.h>
|
#include <gl/GLWidget.h>
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
|
#include <shared/NsightHelpers.h>
|
||||||
#include <plugins/PluginContainer.h>
|
#include <plugins/PluginContainer.h>
|
||||||
#include <gl/Config.h>
|
#include <gl/Config.h>
|
||||||
#include <gl/GLEscrow.h>
|
#include <gl/GLEscrow.h>
|
||||||
|
@ -404,7 +404,11 @@ void OpenGLDisplayPlugin::submitOverlayTexture(const gpu::TexturePointer& overla
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::updateTextures() {
|
void OpenGLDisplayPlugin::updateTextures() {
|
||||||
// FIXME intrduce a GPU wait instead of a CPU/GPU sync point?
|
// FIXME intrduce a GPU wait instead of a CPU/GPU sync point?
|
||||||
|
#if THREADED_PRESENT
|
||||||
if (_sceneTextureEscrow.fetchSignaledAndRelease(_currentSceneTexture)) {
|
if (_sceneTextureEscrow.fetchSignaledAndRelease(_currentSceneTexture)) {
|
||||||
|
#else
|
||||||
|
if (_sceneTextureEscrow.fetchAndReleaseWithGpuWait(_currentSceneTexture)) {
|
||||||
|
#endif
|
||||||
updateFrameData();
|
updateFrameData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,6 +531,9 @@ void OpenGLDisplayPlugin::internalPresent() {
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::present() {
|
void OpenGLDisplayPlugin::present() {
|
||||||
incrementPresentCount();
|
incrementPresentCount();
|
||||||
|
|
||||||
|
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)presentCount())
|
||||||
|
|
||||||
updateTextures();
|
updateTextures();
|
||||||
if (_currentSceneTexture) {
|
if (_currentSceneTexture) {
|
||||||
// Write all layers to a local framebuffer
|
// Write all layers to a local framebuffer
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
#include <SimpleMovingAverage.h>
|
#include <SimpleMovingAverage.h>
|
||||||
#include <gl/OglplusHelpers.h>
|
#include <gl/OglplusHelpers.h>
|
||||||
#include <gl/GLEscrow.h>
|
|
||||||
|
|
||||||
#define THREADED_PRESENT 1
|
#define THREADED_PRESENT 1
|
||||||
|
#include <gl/GLEscrow.h>
|
||||||
|
|
||||||
class OpenGLDisplayPlugin : public DisplayPlugin {
|
class OpenGLDisplayPlugin : public DisplayPlugin {
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <gpu/GLBackend.h>
|
#include <gpu/GLBackend.h>
|
||||||
#include <CursorManager.h>
|
#include <CursorManager.h>
|
||||||
#include <gl/GLWidget.h>
|
#include <gl/GLWidget.h>
|
||||||
|
#include <shared/NsightHelpers.h>
|
||||||
|
|
||||||
#include "../Logging.h"
|
#include "../Logging.h"
|
||||||
#include "../CompositorHelper.h"
|
#include "../CompositorHelper.h"
|
||||||
|
@ -106,6 +107,9 @@ void HmdDisplayPlugin::compositePointer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HmdDisplayPlugin::internalPresent() {
|
void HmdDisplayPlugin::internalPresent() {
|
||||||
|
|
||||||
|
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)presentCount())
|
||||||
|
|
||||||
// Composite together the scene, overlay and mouse cursor
|
// Composite together the scene, overlay and mouse cursor
|
||||||
hmdPresent();
|
hmdPresent();
|
||||||
|
|
||||||
|
@ -149,6 +153,8 @@ void HmdDisplayPlugin::internalPresent() {
|
||||||
});
|
});
|
||||||
swapBuffers();
|
swapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HmdDisplayPlugin::setEyeRenderPose(uint32_t frameIndex, Eye eye, const glm::mat4& pose) {
|
void HmdDisplayPlugin::setEyeRenderPose(uint32_t frameIndex, Eye eye, const glm::mat4& pose) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual void hmdPresent() = 0;
|
virtual void hmdPresent() = 0;
|
||||||
virtual bool isHmdMounted() const = 0;
|
virtual bool isHmdMounted() const = 0;
|
||||||
|
virtual void postPreview() {};
|
||||||
|
|
||||||
void internalActivate() override;
|
void internalActivate() override;
|
||||||
void compositeOverlay() override;
|
void compositeOverlay() override;
|
||||||
|
|
|
@ -113,14 +113,18 @@ QVariantMap RenderableModelEntityItem::parseTexturesToMap(QString textures) {
|
||||||
return _originalTexturesMap;
|
return _originalTexturesMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString jsonTextures = "{\"" + textures.replace(":\"", "\":\"").replace(",\n", ",\"") + "}";
|
// Legacy: a ,\n-delimited list of filename:"texturepath"
|
||||||
|
if (*textures.cbegin() != '{') {
|
||||||
|
textures = "{\"" + textures.replace(":\"", "\":\"").replace(",\n", ",\"") + "}";
|
||||||
|
}
|
||||||
|
|
||||||
QJsonParseError error;
|
QJsonParseError error;
|
||||||
QJsonDocument texturesAsJson = QJsonDocument::fromJson(jsonTextures.toUtf8(), &error);
|
QJsonDocument texturesJson = QJsonDocument::fromJson(textures.toUtf8(), &error);
|
||||||
if (error.error != QJsonParseError::NoError) {
|
if (error.error != QJsonParseError::NoError) {
|
||||||
qCWarning(entitiesrenderer) << "Could not evaluate textures property value:" << _textures;
|
qCWarning(entitiesrenderer) << "Could not evaluate textures property value:" << _textures;
|
||||||
|
return _originalTexturesMap;
|
||||||
}
|
}
|
||||||
QJsonObject texturesAsJsonObject = texturesAsJson.object();
|
return texturesJson.object().toVariantMap();
|
||||||
return texturesAsJsonObject.toVariantMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableModelEntityItem::remapTextures() {
|
void RenderableModelEntityItem::remapTextures() {
|
||||||
|
|
|
@ -101,12 +101,15 @@ void EntitySimulation::expireMortalEntities(const quint64& now) {
|
||||||
prepareEntityForDelete(entity);
|
prepareEntityForDelete(entity);
|
||||||
} else {
|
} else {
|
||||||
if (expiry < _nextExpiry) {
|
if (expiry < _nextExpiry) {
|
||||||
// remeber the smallest _nextExpiry so we know when to start the next search
|
// remember the smallest _nextExpiry so we know when to start the next search
|
||||||
_nextExpiry = expiry;
|
_nextExpiry = expiry;
|
||||||
}
|
}
|
||||||
++itemItr;
|
++itemItr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_mortalEntities.size() < 1) {
|
||||||
|
_nextExpiry = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -293,7 +293,7 @@ void NetworkGeometry::requestModel(const QUrl& url) {
|
||||||
connect(_resource, &Resource::failed, this, &NetworkGeometry::modelRequestError);
|
connect(_resource, &Resource::failed, this, &NetworkGeometry::modelRequestError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkGeometry::mappingRequestDone(const QByteArray& data) {
|
void NetworkGeometry::mappingRequestDone(const QByteArray data) {
|
||||||
assert(_state == RequestMappingState);
|
assert(_state == RequestMappingState);
|
||||||
|
|
||||||
// parse the mapping file
|
// parse the mapping file
|
||||||
|
@ -325,7 +325,7 @@ void NetworkGeometry::mappingRequestError(QNetworkReply::NetworkError error) {
|
||||||
emit onFailure(*this, MappingRequestError);
|
emit onFailure(*this, MappingRequestError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkGeometry::modelRequestDone(const QByteArray& data) {
|
void NetworkGeometry::modelRequestDone(const QByteArray data) {
|
||||||
assert(_state == RequestModelState);
|
assert(_state == RequestModelState);
|
||||||
|
|
||||||
_state = ParsingModelState;
|
_state = ParsingModelState;
|
||||||
|
|
|
@ -113,10 +113,10 @@ public slots:
|
||||||
void textureLoaded(const QWeakPointer<NetworkTexture>& networkTexture);
|
void textureLoaded(const QWeakPointer<NetworkTexture>& networkTexture);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void mappingRequestDone(const QByteArray& data);
|
void mappingRequestDone(const QByteArray data);
|
||||||
void mappingRequestError(QNetworkReply::NetworkError error);
|
void mappingRequestError(QNetworkReply::NetworkError error);
|
||||||
|
|
||||||
void modelRequestDone(const QByteArray& data);
|
void modelRequestDone(const QByteArray data);
|
||||||
void modelRequestError(QNetworkReply::NetworkError error);
|
void modelRequestError(QNetworkReply::NetworkError error);
|
||||||
|
|
||||||
void modelParseSuccess(FBXGeometry* geometry);
|
void modelParseSuccess(FBXGeometry* geometry);
|
||||||
|
|
|
@ -320,13 +320,12 @@ void ImageReader::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QMetaObject::invokeMethod(texture.data(), "setImage",
|
QMetaObject::invokeMethod(texture.data(), "setImage",
|
||||||
Q_ARG(const QImage&, image),
|
|
||||||
Q_ARG(void*, theTexture),
|
Q_ARG(void*, theTexture),
|
||||||
Q_ARG(int, originalWidth), Q_ARG(int, originalHeight));
|
Q_ARG(int, originalWidth), Q_ARG(int, originalHeight));
|
||||||
QThread::currentThread()->setPriority(originalPriority);
|
QThread::currentThread()->setPriority(originalPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkTexture::setImage(const QImage& image, void* voidTexture, int originalWidth,
|
void NetworkTexture::setImage(void* voidTexture, int originalWidth,
|
||||||
int originalHeight) {
|
int originalHeight) {
|
||||||
_originalWidth = originalWidth;
|
_originalWidth = originalWidth;
|
||||||
_originalHeight = originalHeight;
|
_originalHeight = originalHeight;
|
||||||
|
|
|
@ -136,7 +136,7 @@ protected:
|
||||||
|
|
||||||
Q_INVOKABLE void loadContent(const QByteArray& content);
|
Q_INVOKABLE void loadContent(const QByteArray& content);
|
||||||
// FIXME: This void* should be a gpu::Texture* but i cannot get it to work for now, moving on...
|
// FIXME: This void* should be a gpu::Texture* but i cannot get it to work for now, moving on...
|
||||||
Q_INVOKABLE void setImage(const QImage& image, void* texture, int originalWidth, int originalHeight);
|
Q_INVOKABLE void setImage(void* texture, int originalWidth, int originalHeight);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -423,12 +423,12 @@ void Resource::handleReplyFinished() {
|
||||||
|
|
||||||
auto result = _request->getResult();
|
auto result = _request->getResult();
|
||||||
if (result == ResourceRequest::Success) {
|
if (result == ResourceRequest::Success) {
|
||||||
_data = _request->getData();
|
|
||||||
auto extraInfo = _url == _activeUrl ? "" : QString(", %1").arg(_activeUrl.toDisplayString());
|
auto extraInfo = _url == _activeUrl ? "" : QString(", %1").arg(_activeUrl.toDisplayString());
|
||||||
qCDebug(networking).noquote() << QString("Request finished for %1%2").arg(_url.toDisplayString(), extraInfo);
|
qCDebug(networking).noquote() << QString("Request finished for %1%2").arg(_url.toDisplayString(), extraInfo);
|
||||||
|
|
||||||
emit loaded(_data);
|
auto data = _request->getData();
|
||||||
downloadFinished(_data);
|
emit loaded(data);
|
||||||
|
downloadFinished(data);
|
||||||
} else {
|
} else {
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case ResourceRequest::Result::Timeout: {
|
case ResourceRequest::Result::Timeout: {
|
||||||
|
|
|
@ -194,12 +194,11 @@ public:
|
||||||
Q_INVOKABLE void allReferencesCleared();
|
Q_INVOKABLE void allReferencesCleared();
|
||||||
|
|
||||||
const QUrl& getURL() const { return _url; }
|
const QUrl& getURL() const { return _url; }
|
||||||
const QByteArray& getData() const { return _data; }
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/// Fired when the resource has been downloaded.
|
/// Fired when the resource has been downloaded.
|
||||||
/// This can be used instead of downloadFinished to access data before it is processed.
|
/// This can be used instead of downloadFinished to access data before it is processed.
|
||||||
void loaded(const QByteArray& request);
|
void loaded(const QByteArray request);
|
||||||
|
|
||||||
/// Fired when the resource has finished loading.
|
/// Fired when the resource has finished loading.
|
||||||
void finished(bool success);
|
void finished(bool success);
|
||||||
|
@ -235,7 +234,6 @@ protected:
|
||||||
QHash<QPointer<QObject>, float> _loadPriorities;
|
QHash<QPointer<QObject>, float> _loadPriorities;
|
||||||
QWeakPointer<Resource> _self;
|
QWeakPointer<Resource> _self;
|
||||||
QPointer<ResourceCache> _cache;
|
QPointer<ResourceCache> _cache;
|
||||||
QByteArray _data;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleDownloadProgress(uint64_t bytesReceived, uint64_t bytesTotal);
|
void handleDownloadProgress(uint64_t bytesReceived, uint64_t bytesTotal);
|
||||||
|
|
|
@ -57,16 +57,18 @@ void PhysicalEntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicalEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
|
void PhysicalEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
|
||||||
EntitySimulation::removeEntityInternal(entity);
|
if (entity->isSimulated()) {
|
||||||
QMutexLocker lock(&_mutex);
|
EntitySimulation::removeEntityInternal(entity);
|
||||||
_entitiesToAddToPhysics.remove(entity);
|
QMutexLocker lock(&_mutex);
|
||||||
|
_entitiesToAddToPhysics.remove(entity);
|
||||||
|
|
||||||
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
|
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
|
||||||
if (motionState) {
|
if (motionState) {
|
||||||
_outgoingChanges.remove(motionState);
|
_outgoingChanges.remove(motionState);
|
||||||
_entitiesToRemoveFromPhysics.insert(entity);
|
_entitiesToRemoveFromPhysics.insert(entity);
|
||||||
} else {
|
} else {
|
||||||
_entitiesToDelete.insert(entity);
|
_entitiesToDelete.insert(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +177,7 @@ void PhysicalEntitySimulation::getObjectsToRemoveFromPhysics(VectorOfMotionState
|
||||||
_entitiesToRelease.insert(entity);
|
_entitiesToRelease.insert(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity->isSimulated() && entity->isDead()) {
|
if (entity->isDead()) {
|
||||||
_entitiesToDelete.insert(entity);
|
_entitiesToDelete.insert(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,7 +192,7 @@ void PhysicalEntitySimulation::deleteObjectsRemovedFromPhysics() {
|
||||||
entity->setPhysicsInfo(nullptr);
|
entity->setPhysicsInfo(nullptr);
|
||||||
delete motionState;
|
delete motionState;
|
||||||
|
|
||||||
if (entity->isSimulated() && entity->isDead()) {
|
if (entity->isDead()) {
|
||||||
_entitiesToDelete.insert(entity);
|
_entitiesToDelete.insert(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,7 @@ void FetchSpatialTree::run(const SceneContextPointer& sceneContext, const Render
|
||||||
void CullSpatialSelection::configure(const Config& config) {
|
void CullSpatialSelection::configure(const Config& config) {
|
||||||
_justFrozeFrustum = _justFrozeFrustum || (config.freezeFrustum && !_freezeFrustum);
|
_justFrozeFrustum = _justFrozeFrustum || (config.freezeFrustum && !_freezeFrustum);
|
||||||
_freezeFrustum = config.freezeFrustum;
|
_freezeFrustum = config.freezeFrustum;
|
||||||
|
_skipCulling = config.skipCulling;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CullSpatialSelection::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
|
void CullSpatialSelection::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
|
||||||
|
@ -191,60 +192,112 @@ void CullSpatialSelection::run(const SceneContextPointer& sceneContext, const Re
|
||||||
// visibility cull if partially selected ( octree cell contianing it was partial)
|
// visibility cull if partially selected ( octree cell contianing it was partial)
|
||||||
// distance cull if was a subcell item ( octree cell is way bigger than the item bound itself, so now need to test per item)
|
// distance cull if was a subcell item ( octree cell is way bigger than the item bound itself, so now need to test per item)
|
||||||
|
|
||||||
// inside & fit items: easy, just filter
|
if (_skipCulling) {
|
||||||
{
|
// inside & fit items: filter only, culling is disabled
|
||||||
PerformanceTimer perfTimer("insideFitItems");
|
{
|
||||||
for (auto id : inSelection.insideItems) {
|
PerformanceTimer perfTimer("insideFitItems");
|
||||||
auto& item = scene->getItem(id);
|
for (auto id : inSelection.insideItems) {
|
||||||
if (_filter.test(item.getKey())) {
|
auto& item = scene->getItem(id);
|
||||||
ItemBound itemBound(id, item.getBound());
|
if (_filter.test(item.getKey())) {
|
||||||
outItems.emplace_back(itemBound);
|
ItemBound itemBound(id, item.getBound());
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// inside & subcell items: filter & distance cull
|
|
||||||
{
|
|
||||||
PerformanceTimer perfTimer("insideSmallItems");
|
|
||||||
for (auto id : inSelection.insideSubcellItems) {
|
|
||||||
auto& item = scene->getItem(id);
|
|
||||||
if (_filter.test(item.getKey())) {
|
|
||||||
ItemBound itemBound(id, item.getBound());
|
|
||||||
if (test.solidAngleTest(itemBound.bound)) {
|
|
||||||
outItems.emplace_back(itemBound);
|
outItems.emplace_back(itemBound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// partial & fit items: filter & frustum cull
|
// inside & subcell items: filter only, culling is disabled
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("partialFitItems");
|
PerformanceTimer perfTimer("insideSmallItems");
|
||||||
for (auto id : inSelection.partialItems) {
|
for (auto id : inSelection.insideSubcellItems) {
|
||||||
auto& item = scene->getItem(id);
|
auto& item = scene->getItem(id);
|
||||||
if (_filter.test(item.getKey())) {
|
if (_filter.test(item.getKey())) {
|
||||||
ItemBound itemBound(id, item.getBound());
|
ItemBound itemBound(id, item.getBound());
|
||||||
if (test.frustumTest(itemBound.bound)) {
|
|
||||||
outItems.emplace_back(itemBound);
|
outItems.emplace_back(itemBound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// partial & subcell items:: filter & frutum cull & solidangle cull
|
// partial & fit items: filter only, culling is disabled
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("partialSmallItems");
|
PerformanceTimer perfTimer("partialFitItems");
|
||||||
for (auto id : inSelection.partialSubcellItems) {
|
for (auto id : inSelection.partialItems) {
|
||||||
auto& item = scene->getItem(id);
|
auto& item = scene->getItem(id);
|
||||||
if (_filter.test(item.getKey())) {
|
if (_filter.test(item.getKey())) {
|
||||||
ItemBound itemBound(id, item.getBound());
|
ItemBound itemBound(id, item.getBound());
|
||||||
if (test.frustumTest(itemBound.bound)) {
|
outItems.emplace_back(itemBound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// partial & subcell items: filter only, culling is disabled
|
||||||
|
{
|
||||||
|
PerformanceTimer perfTimer("partialSmallItems");
|
||||||
|
for (auto id : inSelection.partialSubcellItems) {
|
||||||
|
auto& item = scene->getItem(id);
|
||||||
|
if (_filter.test(item.getKey())) {
|
||||||
|
ItemBound itemBound(id, item.getBound());
|
||||||
|
outItems.emplace_back(itemBound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// inside & fit items: easy, just filter
|
||||||
|
{
|
||||||
|
PerformanceTimer perfTimer("insideFitItems");
|
||||||
|
for (auto id : inSelection.insideItems) {
|
||||||
|
auto& item = scene->getItem(id);
|
||||||
|
if (_filter.test(item.getKey())) {
|
||||||
|
ItemBound itemBound(id, item.getBound());
|
||||||
|
outItems.emplace_back(itemBound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// inside & subcell items: filter & distance cull
|
||||||
|
{
|
||||||
|
PerformanceTimer perfTimer("insideSmallItems");
|
||||||
|
for (auto id : inSelection.insideSubcellItems) {
|
||||||
|
auto& item = scene->getItem(id);
|
||||||
|
if (_filter.test(item.getKey())) {
|
||||||
|
ItemBound itemBound(id, item.getBound());
|
||||||
if (test.solidAngleTest(itemBound.bound)) {
|
if (test.solidAngleTest(itemBound.bound)) {
|
||||||
outItems.emplace_back(itemBound);
|
outItems.emplace_back(itemBound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// partial & fit items: filter & frustum cull
|
||||||
|
{
|
||||||
|
PerformanceTimer perfTimer("partialFitItems");
|
||||||
|
for (auto id : inSelection.partialItems) {
|
||||||
|
auto& item = scene->getItem(id);
|
||||||
|
if (_filter.test(item.getKey())) {
|
||||||
|
ItemBound itemBound(id, item.getBound());
|
||||||
|
if (test.frustumTest(itemBound.bound)) {
|
||||||
|
outItems.emplace_back(itemBound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// partial & subcell items:: filter & frutum cull & solidangle cull
|
||||||
|
{
|
||||||
|
PerformanceTimer perfTimer("partialSmallItems");
|
||||||
|
for (auto id : inSelection.partialSubcellItems) {
|
||||||
|
auto& item = scene->getItem(id);
|
||||||
|
if (_filter.test(item.getKey())) {
|
||||||
|
ItemBound itemBound(id, item.getBound());
|
||||||
|
if (test.frustumTest(itemBound.bound)) {
|
||||||
|
if (test.solidAngleTest(itemBound.bound)) {
|
||||||
|
outItems.emplace_back(itemBound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
details._rendered += (int)outItems.size();
|
details._rendered += (int)outItems.size();
|
||||||
|
|
|
@ -70,14 +70,16 @@ namespace render {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(int numItems READ getNumItems)
|
Q_PROPERTY(int numItems READ getNumItems)
|
||||||
Q_PROPERTY(bool freezeFrustum MEMBER freezeFrustum WRITE setFreezeFrustum)
|
Q_PROPERTY(bool freezeFrustum MEMBER freezeFrustum WRITE setFreezeFrustum)
|
||||||
|
Q_PROPERTY(bool skipCulling MEMBER skipCulling WRITE setSkipCulling)
|
||||||
public:
|
public:
|
||||||
int numItems{ 0 };
|
int numItems{ 0 };
|
||||||
int getNumItems() { return numItems; }
|
int getNumItems() { return numItems; }
|
||||||
|
|
||||||
bool freezeFrustum{ false };
|
bool freezeFrustum{ false };
|
||||||
|
bool skipCulling{ false };
|
||||||
public slots:
|
public slots:
|
||||||
void setFreezeFrustum(bool enabled) { freezeFrustum = enabled; emit dirty(); }
|
void setFreezeFrustum(bool enabled) { freezeFrustum = enabled; emit dirty(); }
|
||||||
|
void setSkipCulling(bool enabled) { skipCulling = enabled; emit dirty(); }
|
||||||
signals:
|
signals:
|
||||||
void dirty();
|
void dirty();
|
||||||
};
|
};
|
||||||
|
@ -85,6 +87,7 @@ namespace render {
|
||||||
class CullSpatialSelection {
|
class CullSpatialSelection {
|
||||||
bool _freezeFrustum{ false }; // initialized by Config
|
bool _freezeFrustum{ false }; // initialized by Config
|
||||||
bool _justFrozeFrustum{ false };
|
bool _justFrozeFrustum{ false };
|
||||||
|
bool _skipCulling{ false };
|
||||||
ViewFrustum _frozenFrutstum;
|
ViewFrustum _frozenFrutstum;
|
||||||
public:
|
public:
|
||||||
using Config = CullSpatialSelectionConfig;
|
using Config = CullSpatialSelectionConfig;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "NsightHelpers.h"
|
#include "NsightHelpers.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
#if defined(NSIGHT_FOUND)
|
#if defined(NSIGHT_FOUND)
|
||||||
#include "nvToolsExt.h"
|
#include "nvToolsExt.h"
|
||||||
|
|
||||||
|
@ -15,8 +16,28 @@ ProfileRange::ProfileRange(const char *name) {
|
||||||
nvtxRangePush(name);
|
nvtxRangePush(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProfileRange::ProfileRange(const char *name, uint32_t argbColor, uint64_t payload) {
|
||||||
|
|
||||||
|
nvtxEventAttributes_t eventAttrib = {0};
|
||||||
|
eventAttrib.version = NVTX_VERSION;
|
||||||
|
eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
|
||||||
|
eventAttrib.colorType = NVTX_COLOR_ARGB;
|
||||||
|
eventAttrib.color = argbColor;
|
||||||
|
eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
|
||||||
|
eventAttrib.message.ascii = name;
|
||||||
|
eventAttrib.payload.llValue = payload;
|
||||||
|
eventAttrib.payloadType = NVTX_PAYLOAD_TYPE_UNSIGNED_INT64;
|
||||||
|
|
||||||
|
nvtxRangePushEx(&eventAttrib);
|
||||||
|
}
|
||||||
|
|
||||||
ProfileRange::~ProfileRange() {
|
ProfileRange::~ProfileRange() {
|
||||||
nvtxRangePop();
|
nvtxRangePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
ProfileRange::ProfileRange(const char *name) {}
|
||||||
|
ProfileRange::ProfileRange(const char *name, uint32_t argbColor, uint64_t payload) {}
|
||||||
|
ProfileRange::~ProfileRange() {}
|
||||||
#endif
|
#endif
|
||||||
|
#endif // _WIN32
|
||||||
|
|
|
@ -9,16 +9,21 @@
|
||||||
#ifndef hifi_gl_NsightHelpers_h
|
#ifndef hifi_gl_NsightHelpers_h
|
||||||
#define hifi_gl_NsightHelpers_h
|
#define hifi_gl_NsightHelpers_h
|
||||||
|
|
||||||
#if defined(NSIGHT_FOUND)
|
#ifdef _WIN32
|
||||||
class ProfileRange {
|
#include <stdint.h>
|
||||||
public:
|
|
||||||
ProfileRange(const char *name);
|
class ProfileRange {
|
||||||
~ProfileRange();
|
public:
|
||||||
};
|
ProfileRange(const char *name);
|
||||||
|
ProfileRange(const char *name, uint32_t argbColor, uint64_t payload);
|
||||||
|
~ProfileRange();
|
||||||
|
};
|
||||||
|
|
||||||
#define PROFILE_RANGE(name) ProfileRange profileRangeThis(name);
|
#define PROFILE_RANGE(name) ProfileRange profileRangeThis(name);
|
||||||
|
#define PROFILE_RANGE_EX(name, argbColor, payload) ProfileRange profileRangeThis(name, argbColor, payload);
|
||||||
#else
|
#else
|
||||||
#define PROFILE_RANGE(name)
|
#define PROFILE_RANGE(name)
|
||||||
|
#define PROFILE_RANGE_EX(name, argbColor, payload)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif
|
|
||||||
|
|
|
@ -31,19 +31,18 @@ static const char* const URL_PROPERTY = "source";
|
||||||
// Method called by Qt scripts to create a new web window in the overlay
|
// Method called by Qt scripts to create a new web window in the overlay
|
||||||
QScriptValue QmlWebWindowClass::constructor(QScriptContext* context, QScriptEngine* engine) {
|
QScriptValue QmlWebWindowClass::constructor(QScriptContext* context, QScriptEngine* engine) {
|
||||||
return QmlWindowClass::internalConstructor("QmlWebWindow.qml", context, engine,
|
return QmlWindowClass::internalConstructor("QmlWebWindow.qml", context, engine,
|
||||||
[&](QObject* object) { return new QmlWebWindowClass(object); });
|
[&](QObject* object) { return new QmlWebWindowClass(object); });
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlWebWindowClass::QmlWebWindowClass(QObject* qmlWindow) : QmlWindowClass(qmlWindow) {
|
QmlWebWindowClass::QmlWebWindowClass(QObject* qmlWindow) : QmlWindowClass(qmlWindow) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME remove.
|
|
||||||
void QmlWebWindowClass::handleNavigation(const QString& url) {
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QmlWebWindowClass::getURL() const {
|
QString QmlWebWindowClass::getURL() const {
|
||||||
QVariant result = DependencyManager::get<OffscreenUi>()->returnFromUiThread([&]()->QVariant {
|
QVariant result = DependencyManager::get<OffscreenUi>()->returnFromUiThread([&]()->QVariant {
|
||||||
|
if (_qmlWindow.isNull()) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
return _qmlWindow->property(URL_PROPERTY);
|
return _qmlWindow->property(URL_PROPERTY);
|
||||||
});
|
});
|
||||||
return result.toString();
|
return result.toString();
|
||||||
|
@ -54,6 +53,8 @@ extern QString fixupHifiUrl(const QString& urlString);
|
||||||
|
|
||||||
void QmlWebWindowClass::setURL(const QString& urlString) {
|
void QmlWebWindowClass::setURL(const QString& urlString) {
|
||||||
DependencyManager::get<OffscreenUi>()->executeOnUiThread([=] {
|
DependencyManager::get<OffscreenUi>()->executeOnUiThread([=] {
|
||||||
_qmlWindow->setProperty(URL_PROPERTY, fixupHifiUrl(urlString));
|
if (!_qmlWindow.isNull()) {
|
||||||
|
_qmlWindow->setProperty(URL_PROPERTY, fixupHifiUrl(urlString));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,6 @@ public slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void urlChanged();
|
void urlChanged();
|
||||||
|
|
||||||
private slots:
|
|
||||||
void handleNavigation(const QString& url);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -214,7 +214,7 @@ QmlWindowClass::QmlWindowClass(QObject* qmlWindow)
|
||||||
{
|
{
|
||||||
qDebug() << "Created window with ID " << _windowId;
|
qDebug() << "Created window with ID " << _windowId;
|
||||||
Q_ASSERT(_qmlWindow);
|
Q_ASSERT(_qmlWindow);
|
||||||
Q_ASSERT(dynamic_cast<const QQuickItem*>(_qmlWindow));
|
Q_ASSERT(dynamic_cast<const QQuickItem*>(_qmlWindow.data()));
|
||||||
// Forward messages received from QML on to the script
|
// Forward messages received from QML on to the script
|
||||||
connect(_qmlWindow, SIGNAL(sendToScript(QVariant)), this, SIGNAL(fromQml(const QVariant&)), Qt::QueuedConnection);
|
connect(_qmlWindow, SIGNAL(sendToScript(QVariant)), this, SIGNAL(fromQml(const QVariant&)), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ QQuickItem* QmlWindowClass::asQuickItem() const {
|
||||||
if (_toolWindow) {
|
if (_toolWindow) {
|
||||||
return DependencyManager::get<OffscreenUi>()->getToolWindow();
|
return DependencyManager::get<OffscreenUi>()->getToolWindow();
|
||||||
}
|
}
|
||||||
return dynamic_cast<QQuickItem*>(_qmlWindow);
|
return _qmlWindow.isNull() ? nullptr : dynamic_cast<QQuickItem*>(_qmlWindow.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlWindowClass::setVisible(bool visible) {
|
void QmlWindowClass::setVisible(bool visible) {
|
||||||
|
@ -260,32 +260,34 @@ void QmlWindowClass::setVisible(bool visible) {
|
||||||
|
|
||||||
bool QmlWindowClass::isVisible() const {
|
bool QmlWindowClass::isVisible() const {
|
||||||
// The tool window itself has special logic based on whether any tabs are enabled
|
// The tool window itself has special logic based on whether any tabs are enabled
|
||||||
if (_toolWindow) {
|
return DependencyManager::get<OffscreenUi>()->returnFromUiThread([&] {
|
||||||
auto targetTab = dynamic_cast<QQuickItem*>(_qmlWindow);
|
if (_qmlWindow.isNull()) {
|
||||||
return DependencyManager::get<OffscreenUi>()->returnFromUiThread([&] {
|
return QVariant::fromValue(false);
|
||||||
return QVariant::fromValue(targetTab->isEnabled());
|
}
|
||||||
}).toBool();
|
if (_toolWindow) {
|
||||||
} else {
|
return QVariant::fromValue(dynamic_cast<QQuickItem*>(_qmlWindow.data())->isEnabled());
|
||||||
QQuickItem* targetWindow = asQuickItem();
|
} else {
|
||||||
return DependencyManager::get<OffscreenUi>()->returnFromUiThread([&] {
|
return QVariant::fromValue(asQuickItem()->isVisible());
|
||||||
return QVariant::fromValue(targetWindow->isVisible());
|
}
|
||||||
}).toBool();
|
}).toBool();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 QmlWindowClass::getPosition() const {
|
glm::vec2 QmlWindowClass::getPosition() const {
|
||||||
QQuickItem* targetWindow = asQuickItem();
|
|
||||||
QVariant result = DependencyManager::get<OffscreenUi>()->returnFromUiThread([&]()->QVariant {
|
QVariant result = DependencyManager::get<OffscreenUi>()->returnFromUiThread([&]()->QVariant {
|
||||||
return targetWindow->position();
|
if (_qmlWindow.isNull()) {
|
||||||
|
return QVariant(QPointF(0, 0));
|
||||||
|
}
|
||||||
|
return asQuickItem()->position();
|
||||||
});
|
});
|
||||||
return toGlm(result.toPointF());
|
return toGlm(result.toPointF());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QmlWindowClass::setPosition(const glm::vec2& position) {
|
void QmlWindowClass::setPosition(const glm::vec2& position) {
|
||||||
QQuickItem* targetWindow = asQuickItem();
|
|
||||||
DependencyManager::get<OffscreenUi>()->executeOnUiThread([=] {
|
DependencyManager::get<OffscreenUi>()->executeOnUiThread([=] {
|
||||||
targetWindow->setPosition(QPointF(position.x, position.y));
|
if (!_qmlWindow.isNull()) {
|
||||||
|
asQuickItem()->setPosition(QPointF(position.x, position.y));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,17 +301,21 @@ glm::vec2 toGlm(const QSizeF& size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 QmlWindowClass::getSize() const {
|
glm::vec2 QmlWindowClass::getSize() const {
|
||||||
QQuickItem* targetWindow = asQuickItem();
|
|
||||||
QVariant result = DependencyManager::get<OffscreenUi>()->returnFromUiThread([&]()->QVariant {
|
QVariant result = DependencyManager::get<OffscreenUi>()->returnFromUiThread([&]()->QVariant {
|
||||||
|
if (_qmlWindow.isNull()) {
|
||||||
|
return QVariant(QSizeF(0, 0));
|
||||||
|
}
|
||||||
|
QQuickItem* targetWindow = asQuickItem();
|
||||||
return QSizeF(targetWindow->width(), targetWindow->height());
|
return QSizeF(targetWindow->width(), targetWindow->height());
|
||||||
});
|
});
|
||||||
return toGlm(result.toSizeF());
|
return toGlm(result.toSizeF());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlWindowClass::setSize(const glm::vec2& size) {
|
void QmlWindowClass::setSize(const glm::vec2& size) {
|
||||||
QQuickItem* targetWindow = asQuickItem();
|
|
||||||
DependencyManager::get<OffscreenUi>()->executeOnUiThread([=] {
|
DependencyManager::get<OffscreenUi>()->executeOnUiThread([=] {
|
||||||
targetWindow->setSize(QSizeF(size.x, size.y));
|
if (!_qmlWindow.isNull()) {
|
||||||
|
asQuickItem()->setSize(QSizeF(size.x, size.y));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,9 +324,10 @@ void QmlWindowClass::setSize(int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlWindowClass::setTitle(const QString& title) {
|
void QmlWindowClass::setTitle(const QString& title) {
|
||||||
QQuickItem* targetWindow = asQuickItem();
|
|
||||||
DependencyManager::get<OffscreenUi>()->executeOnUiThread([=] {
|
DependencyManager::get<OffscreenUi>()->executeOnUiThread([=] {
|
||||||
targetWindow->setProperty(TITLE_PROPERTY, title);
|
if (!_qmlWindow.isNull()) {
|
||||||
|
asQuickItem()->setProperty(TITLE_PROPERTY, title);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +352,12 @@ void QmlWindowClass::hasClosed() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlWindowClass::raise() {
|
void QmlWindowClass::raise() {
|
||||||
QMetaObject::invokeMethod(asQuickItem(), "raise", Qt::QueuedConnection);
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
offscreenUi->executeOnUiThread([=] {
|
||||||
|
if (!_qmlWindow.isNull()) {
|
||||||
|
QMetaObject::invokeMethod(asQuickItem(), "raise", Qt::DirectConnection);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "QmlWindowClass.moc"
|
#include "QmlWindowClass.moc"
|
||||||
|
|
|
@ -10,11 +10,13 @@
|
||||||
#define hifi_ui_QmlWindowClass_h
|
#define hifi_ui_QmlWindowClass_h
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <GLMHelpers.h>
|
#include <QtCore/QPointer>
|
||||||
#include <QtScript/QScriptValue>
|
#include <QtScript/QScriptValue>
|
||||||
#include <QtQuick/QQuickItem>
|
#include <QtQuick/QQuickItem>
|
||||||
#include <QtWebChannel/QWebChannelAbstractTransport>
|
#include <QtWebChannel/QWebChannelAbstractTransport>
|
||||||
|
|
||||||
|
#include <GLMHelpers.h>
|
||||||
|
|
||||||
class QScriptEngine;
|
class QScriptEngine;
|
||||||
class QScriptContext;
|
class QScriptContext;
|
||||||
class QmlWindowClass;
|
class QmlWindowClass;
|
||||||
|
@ -38,14 +40,13 @@ private:
|
||||||
const QmlWindowClass* _webWindow { nullptr };
|
const QmlWindowClass* _webWindow { nullptr };
|
||||||
QWebSocket *_socket { nullptr };
|
QWebSocket *_socket { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME refactor this class to be a QQuickItem derived type and eliminate the needless wrapping
|
// FIXME refactor this class to be a QQuickItem derived type and eliminate the needless wrapping
|
||||||
class QmlWindowClass : public QObject {
|
class QmlWindowClass : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QObject* eventBridge READ getEventBridge CONSTANT)
|
Q_PROPERTY(QObject* eventBridge READ getEventBridge CONSTANT)
|
||||||
Q_PROPERTY(int windowId READ getWindowId CONSTANT)
|
Q_PROPERTY(int windowId READ getWindowId CONSTANT)
|
||||||
Q_PROPERTY(glm::vec2 position READ getPosition WRITE setPosition)
|
Q_PROPERTY(glm::vec2 position READ getPosition WRITE setPosition NOTIFY positionChanged)
|
||||||
Q_PROPERTY(glm::vec2 size READ getSize WRITE setSize)
|
Q_PROPERTY(glm::vec2 size READ getSize WRITE setSize NOTIFY sizeChanged)
|
||||||
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibilityChanged)
|
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibilityChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -64,11 +65,8 @@ public slots:
|
||||||
glm::vec2 getSize() const;
|
glm::vec2 getSize() const;
|
||||||
void setSize(const glm::vec2& size);
|
void setSize(const glm::vec2& size);
|
||||||
void setSize(int width, int height);
|
void setSize(int width, int height);
|
||||||
|
|
||||||
void setTitle(const QString& title);
|
void setTitle(const QString& title);
|
||||||
|
|
||||||
|
|
||||||
// Ugh.... do not want to do
|
|
||||||
Q_INVOKABLE void raise();
|
Q_INVOKABLE void raise();
|
||||||
Q_INVOKABLE void close();
|
Q_INVOKABLE void close();
|
||||||
Q_INVOKABLE int getWindowId() const { return _windowId; };
|
Q_INVOKABLE int getWindowId() const { return _windowId; };
|
||||||
|
@ -79,6 +77,8 @@ public slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void visibilityChanged(bool visible); // Tool window
|
void visibilityChanged(bool visible); // Tool window
|
||||||
|
void positionChanged();
|
||||||
|
void sizeChanged();
|
||||||
void moved(glm::vec2 position);
|
void moved(glm::vec2 position);
|
||||||
void resized(QSizeF size);
|
void resized(QSizeF size);
|
||||||
void closed();
|
void closed();
|
||||||
|
@ -104,7 +104,7 @@ protected:
|
||||||
// for tool window panes in QML
|
// for tool window panes in QML
|
||||||
bool _toolWindow { false };
|
bool _toolWindow { false };
|
||||||
const int _windowId;
|
const int _windowId;
|
||||||
QObject* _qmlWindow;
|
QPointer<QObject> _qmlWindow;
|
||||||
QString _source;
|
QString _source;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
#include "OculusDisplayPlugin.h"
|
#include "OculusDisplayPlugin.h"
|
||||||
|
#include <shared/NsightHelpers.h>
|
||||||
#include "OculusHelpers.h"
|
#include "OculusHelpers.h"
|
||||||
|
|
||||||
const QString OculusDisplayPlugin::NAME("Oculus Rift");
|
const QString OculusDisplayPlugin::NAME("Oculus Rift");
|
||||||
|
@ -54,6 +55,9 @@ void OculusDisplayPlugin::updateFrameData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OculusDisplayPlugin::hmdPresent() {
|
void OculusDisplayPlugin::hmdPresent() {
|
||||||
|
|
||||||
|
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)_currentRenderFrameIndex)
|
||||||
|
|
||||||
if (!_currentSceneTexture) {
|
if (!_currentSceneTexture) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <plugins/PluginContainer.h>
|
#include <plugins/PluginContainer.h>
|
||||||
#include <ViewFrustum.h>
|
#include <ViewFrustum.h>
|
||||||
|
#include <shared/NsightHelpers.h>
|
||||||
#include "OpenVrHelpers.h"
|
#include "OpenVrHelpers.h"
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(displayplugins)
|
Q_DECLARE_LOGGING_CATEGORY(displayplugins)
|
||||||
|
@ -69,6 +69,9 @@ void OpenVrDisplayPlugin::internalActivate() {
|
||||||
_compositor = vr::VRCompositor();
|
_compositor = vr::VRCompositor();
|
||||||
Q_ASSERT(_compositor);
|
Q_ASSERT(_compositor);
|
||||||
|
|
||||||
|
// enable async time warp
|
||||||
|
// _compositor->ForceInterleavedReprojectionOn(true);
|
||||||
|
|
||||||
// set up default sensor space such that the UI overlay will align with the front of the room.
|
// set up default sensor space such that the UI overlay will align with the front of the room.
|
||||||
auto chaperone = vr::VRChaperone();
|
auto chaperone = vr::VRChaperone();
|
||||||
if (chaperone) {
|
if (chaperone) {
|
||||||
|
@ -119,14 +122,11 @@ void OpenVrDisplayPlugin::updateHeadPose(uint32_t frameIndex) {
|
||||||
float vsyncToPhotons = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SecondsFromVsyncToPhotons_Float);
|
float vsyncToPhotons = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SecondsFromVsyncToPhotons_Float);
|
||||||
|
|
||||||
#if THREADED_PRESENT
|
#if THREADED_PRESENT
|
||||||
// TODO: this seems awfuly long, 44ms total, but it produced the best results.
|
// 3 frames of prediction + vsyncToPhotons = 44ms total
|
||||||
const float NUM_PREDICTION_FRAMES = 3.0f;
|
const float NUM_PREDICTION_FRAMES = 3.0f;
|
||||||
float predictedSecondsFromNow = NUM_PREDICTION_FRAMES * frameDuration + vsyncToPhotons;
|
float predictedSecondsFromNow = NUM_PREDICTION_FRAMES * frameDuration + vsyncToPhotons;
|
||||||
#else
|
#else
|
||||||
uint64_t frameCounter;
|
float predictedSecondsFromNow = frameDuration + vsyncToPhotons;
|
||||||
float timeSinceLastVsync;
|
|
||||||
_system->GetTimeSinceLastVsync(&timeSinceLastVsync, &frameCounter);
|
|
||||||
float predictedSecondsFromNow = 3.0f * frameDuration - timeSinceLastVsync + vsyncToPhotons;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vr::TrackedDevicePose_t predictedTrackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
vr::TrackedDevicePose_t predictedTrackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
||||||
|
@ -144,6 +144,9 @@ void OpenVrDisplayPlugin::updateHeadPose(uint32_t frameIndex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenVrDisplayPlugin::hmdPresent() {
|
void OpenVrDisplayPlugin::hmdPresent() {
|
||||||
|
|
||||||
|
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)_currentRenderFrameIndex)
|
||||||
|
|
||||||
// Flip y-axis since GL UV coords are backwards.
|
// Flip y-axis since GL UV coords are backwards.
|
||||||
static vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 };
|
static vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 };
|
||||||
static vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 1 };
|
static vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 1 };
|
||||||
|
@ -152,6 +155,10 @@ void OpenVrDisplayPlugin::hmdPresent() {
|
||||||
|
|
||||||
_compositor->Submit(vr::Eye_Left, &texture, &leftBounds);
|
_compositor->Submit(vr::Eye_Left, &texture, &leftBounds);
|
||||||
_compositor->Submit(vr::Eye_Right, &texture, &rightBounds);
|
_compositor->Submit(vr::Eye_Right, &texture, &rightBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenVrDisplayPlugin::postPreview() {
|
||||||
|
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)_currentRenderFrameIndex)
|
||||||
|
|
||||||
vr::TrackedDevicePose_t currentTrackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
vr::TrackedDevicePose_t currentTrackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
||||||
_compositor->WaitGetPoses(currentTrackedDevicePose, vr::k_unMaxTrackedDeviceCount, nullptr, 0);
|
_compositor->WaitGetPoses(currentTrackedDevicePose, vr::k_unMaxTrackedDeviceCount, nullptr, 0);
|
||||||
|
|
|
@ -35,6 +35,7 @@ protected:
|
||||||
|
|
||||||
void hmdPresent() override;
|
void hmdPresent() override;
|
||||||
bool isHmdMounted() const override;
|
bool isHmdMounted() const override;
|
||||||
|
void postPreview() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vr::IVRSystem* _system { nullptr };
|
vr::IVRSystem* _system { nullptr };
|
||||||
|
|
|
@ -51,7 +51,7 @@ vr::IVRSystem* acquireOpenVrSystem() {
|
||||||
if (!activeHmd) {
|
if (!activeHmd) {
|
||||||
qCDebug(displayplugins) << "openvr: No vr::IVRSystem instance active, building";
|
qCDebug(displayplugins) << "openvr: No vr::IVRSystem instance active, building";
|
||||||
vr::EVRInitError eError = vr::VRInitError_None;
|
vr::EVRInitError eError = vr::VRInitError_None;
|
||||||
activeHmd = vr::VR_Init(&eError);
|
activeHmd = vr::VR_Init(&eError, vr::VRApplication_Scene);
|
||||||
qCDebug(displayplugins) << "openvr display: HMD is " << activeHmd << " error is " << eError;
|
qCDebug(displayplugins) << "openvr display: HMD is " << activeHmd << " error is " << eError;
|
||||||
}
|
}
|
||||||
if (activeHmd) {
|
if (activeHmd) {
|
||||||
|
|
|
@ -44,6 +44,14 @@ ready = function() {
|
||||||
var domainServer = remote.getGlobal('domainServer');
|
var domainServer = remote.getGlobal('domainServer');
|
||||||
var acMonitor = remote.getGlobal('acMonitor');
|
var acMonitor = remote.getGlobal('acMonitor');
|
||||||
|
|
||||||
|
var pendingLines = {
|
||||||
|
'ds': new Array(),
|
||||||
|
'ac': new Array()
|
||||||
|
};
|
||||||
|
|
||||||
|
var UPDATE_INTERVAL = 16; // Update log at ~60 fps
|
||||||
|
var interval = setInterval(flushPendingLines, UPDATE_INTERVAL);
|
||||||
|
|
||||||
var logWatchers = {
|
var logWatchers = {
|
||||||
'ds': {
|
'ds': {
|
||||||
},
|
},
|
||||||
|
@ -83,7 +91,7 @@ ready = function() {
|
||||||
var logTail = new Tail(cleanFilePath, '\n', { start: start, interval: 500 });
|
var logTail = new Tail(cleanFilePath, '\n', { start: start, interval: 500 });
|
||||||
|
|
||||||
logTail.on('line', function(msg) {
|
logTail.on('line', function(msg) {
|
||||||
appendLogMessage(msg, stream);
|
pendingLines[stream].push(msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
logTail.on('error', function(error) {
|
logTail.on('error', function(error) {
|
||||||
|
@ -107,6 +115,7 @@ ready = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onbeforeunload = function(e) {
|
window.onbeforeunload = function(e) {
|
||||||
|
clearInterval(interval);
|
||||||
domainServer.removeListener('logs-updated', updateLogFiles);
|
domainServer.removeListener('logs-updated', updateLogFiles);
|
||||||
acMonitor.removeListener('logs-updated', updateLogFiles);
|
acMonitor.removeListener('logs-updated', updateLogFiles);
|
||||||
};
|
};
|
||||||
|
@ -164,14 +173,23 @@ ready = function() {
|
||||||
return !filter || message.toLowerCase().indexOf(filter) >= 0;
|
return !filter || message.toLowerCase().indexOf(filter) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendLogMessage(msg, name) {
|
function appendLogMessages(name) {
|
||||||
|
var array = pendingLines[name];
|
||||||
|
if (array.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (array.length > maxLogLines) {
|
||||||
|
array = array.slice(-maxLogLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(name, array.length);
|
||||||
|
|
||||||
var id = name == "ds" ? "domain-server" : "assignment-client";
|
var id = name == "ds" ? "domain-server" : "assignment-client";
|
||||||
var $pidLog = $('#' + id);
|
var $pidLog = $('#' + id);
|
||||||
|
|
||||||
var size = ++tabStates[id].size;
|
var size = tabStates[id].size + array.length;
|
||||||
if (size > maxLogLines) {
|
if (size > maxLogLines) {
|
||||||
$pidLog.find('div.log-line:first').remove();
|
$pidLog.find('div.log-line:lt(' + (size - maxLogLines) + ')').remove();
|
||||||
removed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var wasAtBottom = false;
|
var wasAtBottom = false;
|
||||||
|
@ -179,17 +197,25 @@ ready = function() {
|
||||||
wasAtBottom = $pidLog[0].scrollTop >= ($pidLog[0].scrollHeight - $pidLog.height());
|
wasAtBottom = $pidLog[0].scrollTop >= ($pidLog[0].scrollHeight - $pidLog.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
var $logLine = $('<div class="log-line">').text(msg);
|
for (line in array) {
|
||||||
if (!shouldDisplayLogMessage(msg)) {
|
var $logLine = $('<div class="log-line">').text(array[line]);
|
||||||
$logLine.hide();
|
if (!shouldDisplayLogMessage(array[line])) {
|
||||||
|
$logLine.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$pidLog.append($logLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
$pidLog.append($logLine);
|
delete pendingLines[name];
|
||||||
|
pendingLines[name] = new Array();
|
||||||
|
|
||||||
if (wasAtBottom) {
|
if (wasAtBottom) {
|
||||||
$pidLog.scrollTop($pidLog[0].scrollHeight);
|
$pidLog.scrollTop($pidLog[0].scrollHeight);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
function flushPendingLines() {
|
||||||
|
appendLogMessages('ds');
|
||||||
|
appendLogMessages('ac');
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle filtering of table rows on input change
|
// handle filtering of table rows on input change
|
||||||
|
|
Loading…
Reference in a new issue