overte-JulianGro/interface/src/VisionSqueeze.cpp

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());
}
}