mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 13:12:52 +02:00
213 lines
7.8 KiB
C++
213 lines
7.8 KiB
C++
//
|
|
// VisionSqueeze.cpp
|
|
// interface/src
|
|
//
|
|
// Created by Seth Alves on 2019-3-13.
|
|
// Copyright 2019 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include "VisionSqueeze.h"
|
|
|
|
#include <glm/gtx/matrix_decompose.hpp>
|
|
#include <glm/gtc/epsilon.hpp>
|
|
|
|
#include <display-plugins/hmd/HmdDisplayPlugin.h>
|
|
|
|
#include "Application.h"
|
|
|
|
VisionSqueeze::VisionSqueeze() :
|
|
_visionSqueezeEnabled(_visionSqueezeEnabledSetting.get()),
|
|
_visionSqueezeRatioX(_visionSqueezeRatioXSetting.get()),
|
|
_visionSqueezeRatioY(_visionSqueezeRatioYSetting.get()),
|
|
_visionSqueezeUnSqueezeDelay(_visionSqueezeUnSqueezeDelaySetting.get()),
|
|
_visionSqueezeUnSqueezeSpeed(_visionSqueezeUnSqueezeSpeedSetting.get()),
|
|
_visionSqueezeTransition(_visionSqueezeTransitionSetting.get()),
|
|
_visionSqueezePerEye(_visionSqueezePerEyeSetting.get()),
|
|
_visionSqueezeGroundPlaneY(_visionSqueezeGroundPlaneYSetting.get()),
|
|
_visionSqueezeSpotlightSize(_visionSqueezeSpotlightSizeSetting.get()),
|
|
_visionSqueezeTurningXFactor(_visionSqueezeTurningXFactorSetting.get()),
|
|
_visionSqueezeTurningYFactor(_visionSqueezeTurningYFactorSetting.get()) {
|
|
}
|
|
|
|
void VisionSqueeze::setVisionSqueezeEnabled(bool value) {
|
|
if (value != _visionSqueezeEnabled) {
|
|
_visionSqueezeEnabled = value;
|
|
_visionSqueezeEnabledSetting.set(_visionSqueezeEnabled);
|
|
}
|
|
}
|
|
|
|
void VisionSqueeze::setVisionSqueezeRatioX(float value) {
|
|
if (value != _visionSqueezeRatioX) {
|
|
_visionSqueezeRatioX = value;
|
|
_visionSqueezeRatioXSetting.set(_visionSqueezeRatioX);
|
|
}
|
|
}
|
|
|
|
void VisionSqueeze::setVisionSqueezeRatioY(float value) {
|
|
if (value != _visionSqueezeRatioY) {
|
|
_visionSqueezeRatioY = value;
|
|
_visionSqueezeRatioYSetting.set(_visionSqueezeRatioY);
|
|
}
|
|
}
|
|
|
|
void VisionSqueeze::setVisionSqueezeUnSqueezeDelay(float value) {
|
|
if (value != _visionSqueezeUnSqueezeDelay) {
|
|
_visionSqueezeUnSqueezeDelay = value;
|
|
_visionSqueezeUnSqueezeDelaySetting.set(_visionSqueezeUnSqueezeDelay);
|
|
}
|
|
}
|
|
|
|
void VisionSqueeze::setVisionSqueezeUnSqueezeSpeed(float value) {
|
|
if (value != _visionSqueezeUnSqueezeSpeed) {
|
|
_visionSqueezeUnSqueezeSpeed = value;
|
|
_visionSqueezeUnSqueezeSpeedSetting.set(_visionSqueezeUnSqueezeSpeed);
|
|
}
|
|
}
|
|
|
|
void VisionSqueeze::setVisionSqueezeTransition(float value) {
|
|
if (value != _visionSqueezeTransition) {
|
|
_visionSqueezeTransition = value;
|
|
_visionSqueezeTransitionSetting.set(_visionSqueezeTransition);
|
|
}
|
|
}
|
|
|
|
void VisionSqueeze::setVisionSqueezePerEye(int value) {
|
|
if (value != _visionSqueezePerEye) {
|
|
_visionSqueezePerEye = value;
|
|
_visionSqueezePerEyeSetting.set(_visionSqueezePerEye);
|
|
}
|
|
}
|
|
|
|
void VisionSqueeze::setVisionSqueezeGroundPlaneY(float value) {
|
|
if (value != _visionSqueezeGroundPlaneY) {
|
|
_visionSqueezeGroundPlaneY = value;
|
|
_visionSqueezeGroundPlaneYSetting.set(_visionSqueezeGroundPlaneY);
|
|
}
|
|
}
|
|
|
|
void VisionSqueeze::setVisionSqueezeSpotlightSize(float value) {
|
|
if (value != _visionSqueezeSpotlightSize) {
|
|
_visionSqueezeSpotlightSize = value;
|
|
_visionSqueezeSpotlightSizeSetting.set(_visionSqueezeSpotlightSize);
|
|
}
|
|
}
|
|
|
|
void VisionSqueeze::setVisionSqueezeTurningXFactor(float value) {
|
|
if (value != _visionSqueezeTurningXFactor) {
|
|
_visionSqueezeTurningXFactor = value;
|
|
_visionSqueezeTurningXFactorSetting.set(_visionSqueezeTurningXFactor);
|
|
}
|
|
}
|
|
|
|
void VisionSqueeze::setVisionSqueezeTurningYFactor(float value) {
|
|
if (value != _visionSqueezeTurningYFactor) {
|
|
_visionSqueezeTurningYFactor = value;
|
|
_visionSqueezeTurningYFactorSetting.set(_visionSqueezeTurningYFactor);
|
|
}
|
|
}
|
|
|
|
void VisionSqueeze::updateVisionSqueeze(const glm::mat4& sensorToWorldMatrix, float deltaTime) {
|
|
|
|
const float SENSOR_TO_WORLD_TRANS_EPSILON = 0.0001f;
|
|
const float SENSOR_TO_WORLD_TRANS_Y_EPSILON = 0.01f;
|
|
const float SENSOR_TO_WORLD_TRANS_ITS_A_TELEPORT_SQUARED = 2.0f;
|
|
const float SENSOR_TO_WORLD_ROT_EPSILON = 0.000005f;
|
|
const float SENSOR_TO_WORLD_ROT_ITS_A_SNAP_TURN = 0.99f;
|
|
const float VISION_SQUEEZE_TP_LOCKOUT = 0.1f; // seconds
|
|
|
|
glm::vec3 scale;
|
|
glm::quat rotation;
|
|
glm::vec3 translation;
|
|
glm::vec3 skew;
|
|
glm::vec4 perspective;
|
|
glm::decompose(sensorToWorldMatrix, scale, rotation, translation, skew, perspective);
|
|
|
|
if (!_visionSqueezeEnabled) {
|
|
_squeezeVision = false;
|
|
_squeezeVisionTurning = false;
|
|
} else if (_visionSqueezeLockout > 0.0f) {
|
|
_visionSqueezeLockout -= deltaTime;
|
|
} else {
|
|
_squeezeVision = false;
|
|
_squeezeVisionTurning = false;
|
|
glm::vec3 absTransDelta = glm::abs(translation - _prevTranslation);
|
|
float rotDot = fabsf(glm::dot(rotation, _prevRotation));
|
|
|
|
// if the avatar has just teleported or snap-turned, briefly disable triggering of vision-squeeze
|
|
if (glm::length2(translation - _prevTranslation) > SENSOR_TO_WORLD_TRANS_ITS_A_TELEPORT_SQUARED ||
|
|
rotDot < SENSOR_TO_WORLD_ROT_ITS_A_SNAP_TURN) {
|
|
_visionSqueezeLockout = VISION_SQUEEZE_TP_LOCKOUT;
|
|
_squeezeVision = true;
|
|
_squeezeVisionTurning = true;
|
|
} else if (rotDot < 1.0f - SENSOR_TO_WORLD_ROT_EPSILON) {
|
|
_squeezeVision = true;
|
|
_squeezeVisionTurning = true;
|
|
} else if (absTransDelta.x > SENSOR_TO_WORLD_TRANS_EPSILON ||
|
|
absTransDelta.y > SENSOR_TO_WORLD_TRANS_Y_EPSILON ||
|
|
absTransDelta.z > SENSOR_TO_WORLD_TRANS_EPSILON) {
|
|
_squeezeVision = true;
|
|
_squeezeVisionTurning = false;
|
|
}
|
|
}
|
|
|
|
_prevTranslation = translation;
|
|
_prevRotation = rotation;
|
|
|
|
static quint64 lastSqueezeTime = 0;
|
|
quint64 now = usecTimestampNow();
|
|
static float visionSqueezeX = 0.0f; // 0.0 -- unobstructed, 1.0 -- fully blocked
|
|
static float visionSqueezeY = 0.0f; // 0.0 -- unobstructed, 1.0 -- fully blocked
|
|
|
|
if (_squeezeVision) {
|
|
float ratioX = getVisionSqueezeRatioX();
|
|
float ratioY = getVisionSqueezeRatioY();
|
|
|
|
if (ratioX >= 0.0f) {
|
|
if (_squeezeVisionTurning) {
|
|
ratioX += (1.0f - ratioX) * getVisionSqueezeTurningXFactor();
|
|
}
|
|
float newVisionSqueezeX = ratioX;
|
|
if (newVisionSqueezeX >= visionSqueezeX) {
|
|
lastSqueezeTime = now;
|
|
visionSqueezeX = newVisionSqueezeX;
|
|
}
|
|
} else {
|
|
visionSqueezeX = -1.0f;
|
|
}
|
|
|
|
if (ratioY >= 0.0f) {
|
|
float newVisionSqueezeY = ratioY;
|
|
if (newVisionSqueezeY >= visionSqueezeY) {
|
|
lastSqueezeTime = now;
|
|
visionSqueezeY = newVisionSqueezeY;
|
|
}
|
|
} else {
|
|
visionSqueezeY = -1.0f;
|
|
}
|
|
}
|
|
|
|
float unsqueezeAmount = deltaTime * getVisionSqueezeUnSqueezeSpeed();
|
|
if (now - lastSqueezeTime > getVisionSqueezeUnSqueezeDelay() * USECS_PER_SECOND) {
|
|
visionSqueezeX -= unsqueezeAmount;
|
|
if (visionSqueezeX < 0.0f) {
|
|
visionSqueezeX = -1.0f;
|
|
}
|
|
visionSqueezeY -= unsqueezeAmount;
|
|
if (visionSqueezeY < 0.0f) {
|
|
visionSqueezeY = -1.0f;
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<HmdDisplayPlugin> hmdDisplayPlugin =
|
|
std::dynamic_pointer_cast<HmdDisplayPlugin>(qApp->getActiveDisplayPlugin());
|
|
if (hmdDisplayPlugin) {
|
|
hmdDisplayPlugin->updateVisionSqueezeParameters(visionSqueezeX, visionSqueezeY,
|
|
getVisionSqueezeTransition(),
|
|
getVisionSqueezePerEye(),
|
|
getVisionSqueezeGroundPlaneY(),
|
|
getVisionSqueezeSpotlightSize());
|
|
}
|
|
}
|