mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-10 11:41:59 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into toulouse
This commit is contained in:
commit
53642763c9
17 changed files with 158 additions and 127 deletions
|
@ -75,7 +75,7 @@ public:
|
|||
void each(std::function<void(AvatarMixerSlave& slave)> functor);
|
||||
|
||||
#ifdef DEBUG_EVENT_QUEUE
|
||||
void AvatarMixerSlavePool::queueStats(QJsonObject& stats);
|
||||
void queueStats(QJsonObject& stats);
|
||||
#endif
|
||||
|
||||
void setNumThreads(int numThreads);
|
||||
|
|
|
@ -27,11 +27,15 @@ Rectangle {
|
|||
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
readonly property real treeScale: 32768; // ~20 miles.. This is the number of meters of the 0.0 to 1.0 voxel universe
|
||||
readonly property real halfTreeScale: treeScale / 2;
|
||||
|
||||
// This controls the LOD. Larger number will make smaller voxels visible at greater distance.
|
||||
readonly property real defaultOctreeSizeScale: treeScale * 400.0
|
||||
// This controls the LOD. Larger number will make smaller objects visible at greater distance.
|
||||
readonly property real defaultMaxVisibilityDistance: 400.0
|
||||
readonly property real unitElementMaxExtent: Math.sqrt(3.0) * 0.5
|
||||
|
||||
function visibilityDistanceToLODAngleDeg(visibilityDistance) {
|
||||
var lodHalfAngle = Math.atan(unitElementMaxExtent / visibilityDistance);
|
||||
var lodAngle = lodHalfAngle * 2.0;
|
||||
return lodAngle * 180.0 / Math.PI;
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.margins: 10
|
||||
|
@ -71,7 +75,7 @@ Rectangle {
|
|||
id: adjustCheckbox
|
||||
boxSize: 20
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
onCheckedChanged: LODManager.setAutomaticLODAdjust(!checked);
|
||||
onCheckedChanged: LODManager.setAutomaticLODAdjust(!adjustCheckbox.checked);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,10 +93,10 @@ Rectangle {
|
|||
anchors.right: parent.right
|
||||
minimumValue: 5
|
||||
maximumValue: 2000
|
||||
value: LODManager.getOctreeSizeScale() / treeScale
|
||||
value: defaultMaxVisibilityDistance
|
||||
tickmarksEnabled: false
|
||||
onValueChanged: {
|
||||
LODManager.setOctreeSizeScale(value * treeScale);
|
||||
LODManager.lodAngleDeg = visibilityDistanceToLODAngleDeg(slider.value);
|
||||
whatYouCanSeeLabel.text = LODManager.getLODFeedbackText()
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +110,7 @@ Rectangle {
|
|||
colorScheme: root.colorScheme
|
||||
height: 30
|
||||
onClicked: {
|
||||
slider.value = defaultOctreeSizeScale/treeScale
|
||||
slider.value = defaultMaxVisibilityDistance
|
||||
adjustCheckbox.checked = false
|
||||
LODManager.setAutomaticLODAdjust(adjustCheckbox.checked);
|
||||
}
|
||||
|
|
|
@ -6817,8 +6817,8 @@ void Application::updateRenderArgs(float deltaTime) {
|
|||
_viewFrustum.setProjection(adjustedProjection);
|
||||
_viewFrustum.calculate();
|
||||
}
|
||||
appRenderArgs._renderArgs = RenderArgs(_graphicsEngine.getGPUContext(), lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(), lodManager->getLODAngleHalfTan(), RenderArgs::DEFAULT_RENDER_MODE,
|
||||
appRenderArgs._renderArgs = RenderArgs(_graphicsEngine.getGPUContext(), lodManager->getVisibilityDistance(),
|
||||
lodManager->getBoundaryLevelAdjust(), lodManager->getLODHalfAngleTan(), RenderArgs::DEFAULT_RENDER_MODE,
|
||||
RenderArgs::MONO, RenderArgs::DEFERRED, RenderArgs::RENDER_DEBUG_NONE);
|
||||
appRenderArgs._renderArgs._scene = getMain3DScene();
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "LODManager.h"
|
||||
|
||||
#include <SettingHandle.h>
|
||||
#include <OctreeUtils.h>
|
||||
#include <Util.h>
|
||||
#include <shared/GlobalAppProperties.h>
|
||||
|
||||
|
@ -93,8 +92,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Previous values for output
|
||||
float oldOctreeSizeScale = getOctreeSizeScale();
|
||||
// Previous value for output
|
||||
float oldLODAngle = getLODAngleDeg();
|
||||
|
||||
// Target fps is slightly overshooted by 5hz
|
||||
|
@ -165,7 +163,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
|||
// And now add the output of the controller to the LODAngle where we will guarantee it is in the proper range
|
||||
setLODAngleDeg(oldLODAngle + output);
|
||||
|
||||
if (oldOctreeSizeScale != _octreeSizeScale) {
|
||||
if (oldLODAngle != getLODAngleDeg()) {
|
||||
auto lodToolsDialog = DependencyManager::get<DialogsManager>()->getLodToolsDialog();
|
||||
if (lodToolsDialog) {
|
||||
lodToolsDialog->reloadSliders();
|
||||
|
@ -173,21 +171,32 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
|||
}
|
||||
}
|
||||
|
||||
float LODManager::getLODAngleHalfTan() const {
|
||||
return getPerspectiveAccuracyAngleTan(_octreeSizeScale, _boundaryLevelAdjust);
|
||||
float LODManager::getLODHalfAngleTan() const {
|
||||
return tan(_lodHalfAngle);
|
||||
}
|
||||
float LODManager::getLODAngle() const {
|
||||
return 2.0f * atanf(getLODAngleHalfTan());
|
||||
return 2.0f * _lodHalfAngle;
|
||||
}
|
||||
float LODManager::getLODAngleDeg() const {
|
||||
return glm::degrees(getLODAngle());
|
||||
}
|
||||
|
||||
float LODManager::getVisibilityDistance() const {
|
||||
float systemDistance = getVisibilityDistanceFromHalfAngle(_lodHalfAngle);
|
||||
// Maintain behavior with deprecated _boundaryLevelAdjust property
|
||||
return systemDistance * powf(2.0f, _boundaryLevelAdjust);
|
||||
}
|
||||
|
||||
void LODManager::setVisibilityDistance(float distance) {
|
||||
// Maintain behavior with deprecated _boundaryLevelAdjust property
|
||||
float userDistance = distance / powf(2.0f, _boundaryLevelAdjust);
|
||||
_lodHalfAngle = getHalfAngleFromVisibilityDistance(userDistance);
|
||||
}
|
||||
|
||||
void LODManager::setLODAngleDeg(float lodAngle) {
|
||||
auto newSolidAngle = std::max(0.5f, std::min(lodAngle, 90.f));
|
||||
auto halTan = glm::tan(glm::radians(newSolidAngle * 0.5f));
|
||||
auto octreeSizeScale = TREE_SCALE * OCTREE_TO_MESH_RATIO / halTan;
|
||||
setOctreeSizeScale(octreeSizeScale);
|
||||
auto newLODAngleDeg = std::max(0.001f, std::min(lodAngle, 90.f));
|
||||
auto newLODHalfAngle = glm::radians(newLODAngleDeg * 0.5f);
|
||||
_lodHalfAngle = newLODHalfAngle;
|
||||
}
|
||||
|
||||
void LODManager::setSmoothScale(float t) {
|
||||
|
@ -267,7 +276,11 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
|
|||
};
|
||||
|
||||
void LODManager::setOctreeSizeScale(float sizeScale) {
|
||||
_octreeSizeScale = sizeScale;
|
||||
setVisibilityDistance(sizeScale / TREE_SCALE);
|
||||
}
|
||||
|
||||
float LODManager::getOctreeSizeScale() const {
|
||||
return getVisibilityDistance() * TREE_SCALE;
|
||||
}
|
||||
|
||||
void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
|
||||
|
@ -293,12 +306,14 @@ QString LODManager::getLODFeedbackText() {
|
|||
} break;
|
||||
}
|
||||
// distance feedback
|
||||
float octreeSizeScale = getOctreeSizeScale();
|
||||
float relativeToDefault = octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE;
|
||||
float visibilityDistance = getVisibilityDistance();
|
||||
float relativeToDefault = visibilityDistance / DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT;
|
||||
int relativeToTwentyTwenty = 20 / relativeToDefault;
|
||||
|
||||
QString result;
|
||||
if (relativeToDefault > 1.01f) {
|
||||
if (relativeToTwentyTwenty < 1) {
|
||||
result = QString("%2 times further than average vision%3").arg(relativeToDefault, 0, 'f', 3).arg(granularityFeedback);
|
||||
} else if (relativeToDefault > 1.01f) {
|
||||
result = QString("20:%1 or %2 times further than average vision%3").arg(relativeToTwentyTwenty).arg(relativeToDefault, 0, 'f', 2).arg(granularityFeedback);
|
||||
} else if (relativeToDefault > 0.99f) {
|
||||
result = QString("20:20 or the default distance for average vision%1").arg(granularityFeedback);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <DependencyManager.h>
|
||||
#include <NumericalConstants.h>
|
||||
#include <OctreeConstants.h>
|
||||
#include <OctreeUtils.h>
|
||||
#include <PIDController.h>
|
||||
#include <SimpleMovingAverage.h>
|
||||
#include <render/Args.h>
|
||||
|
@ -138,24 +139,28 @@ public:
|
|||
/**jsdoc
|
||||
* @function LODManager.setOctreeSizeScale
|
||||
* @param {number} sizeScale
|
||||
* @deprecated This function is deprecated and will be removed. Use the {@link LODManager.lodAngleDeg} property instead.
|
||||
*/
|
||||
Q_INVOKABLE void setOctreeSizeScale(float sizeScale);
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getOctreeSizeScale
|
||||
* @returns {number}
|
||||
* @deprecated This function is deprecated and will be removed. Use the {@link LODManager.lodAngleDeg} property instead.
|
||||
*/
|
||||
Q_INVOKABLE float getOctreeSizeScale() const { return _octreeSizeScale; }
|
||||
Q_INVOKABLE float getOctreeSizeScale() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.setBoundaryLevelAdjust
|
||||
* @param {number} boundaryLevelAdjust
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE void setBoundaryLevelAdjust(int boundaryLevelAdjust);
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getBoundaryLevelAdjust
|
||||
* @returns {number}
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
|
||||
|
||||
|
@ -196,8 +201,10 @@ public:
|
|||
|
||||
float getLODAngleDeg() const;
|
||||
void setLODAngleDeg(float lodAngle);
|
||||
float getLODAngleHalfTan() const;
|
||||
float getLODHalfAngleTan() const;
|
||||
float getLODAngle() const;
|
||||
float getVisibilityDistance() const;
|
||||
void setVisibilityDistance(float distance);
|
||||
|
||||
float getPidKp() const;
|
||||
float getPidKi() const;
|
||||
|
@ -254,7 +261,7 @@ private:
|
|||
float _desktopTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS };
|
||||
float _hmdTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS };
|
||||
|
||||
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
||||
float _lodHalfAngle = getHalfAngleFromVisibilityDistance(DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT);
|
||||
int _boundaryLevelAdjust = 0;
|
||||
|
||||
glm::vec4 _pidCoefs{ 1.0f, 0.0f, 0.0f, 1.0f }; // Kp, Ki, Kd, Kv
|
||||
|
|
|
@ -64,7 +64,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
|
|||
_lodSize->setTickPosition(QSlider::TicksBelow);
|
||||
_lodSize->setFixedWidth(SLIDER_WIDTH);
|
||||
_lodSize->setPageStep(PAGE_STEP_LOD_SIZE);
|
||||
int sliderValue = lodManager->getOctreeSizeScale() / TREE_SCALE;
|
||||
int sliderValue = lodManager->getVisibilityDistance();
|
||||
_lodSize->setValue(sliderValue);
|
||||
form->addRow("Level of Detail:", _lodSize);
|
||||
connect(_lodSize,SIGNAL(valueChanged(int)),this,SLOT(sizeScaleValueChanged(int)));
|
||||
|
@ -81,7 +81,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
|
|||
|
||||
void LodToolsDialog::reloadSliders() {
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
_lodSize->setValue(lodManager->getOctreeSizeScale() / TREE_SCALE);
|
||||
_lodSize->setValue(lodManager->getVisibilityDistance());
|
||||
_feedback->setText(lodManager->getLODFeedbackText());
|
||||
}
|
||||
|
||||
|
@ -93,15 +93,14 @@ void LodToolsDialog::updateAutomaticLODAdjust() {
|
|||
|
||||
void LodToolsDialog::sizeScaleValueChanged(int value) {
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
float realValue = value * TREE_SCALE;
|
||||
lodManager->setOctreeSizeScale(realValue);
|
||||
lodManager->setVisibilityDistance(value);
|
||||
|
||||
_feedback->setText(lodManager->getLODFeedbackText());
|
||||
}
|
||||
|
||||
void LodToolsDialog::resetClicked(bool checked) {
|
||||
|
||||
int sliderValue = DEFAULT_OCTREE_SIZE_SCALE / TREE_SCALE;
|
||||
int sliderValue = DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT;
|
||||
_lodSize->setValue(sliderValue);
|
||||
_manualLODAdjust->setChecked(false);
|
||||
|
||||
|
@ -124,8 +123,8 @@ void LodToolsDialog::closeEvent(QCloseEvent* event) {
|
|||
lodManager->setAutomaticLODAdjust(true);
|
||||
|
||||
// if the user adjusted the LOD above "normal" then always revert back to default
|
||||
if (lodManager->getOctreeSizeScale() > DEFAULT_OCTREE_SIZE_SCALE) {
|
||||
lodManager->setOctreeSizeScale(DEFAULT_OCTREE_SIZE_SCALE);
|
||||
if (lodManager->getVisibilityDistance() > DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT) {
|
||||
lodManager->setVisibilityDistance(DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -213,6 +213,12 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std::
|
|||
}
|
||||
}
|
||||
|
||||
float AnimInverseKinematics::getInterpolationAlpha(float timer) {
|
||||
float alpha = (JOINT_CHAIN_INTERP_TIME - timer) / JOINT_CHAIN_INTERP_TIME;
|
||||
alpha = 1.0f - powf(2.0f, -10.0f * alpha);
|
||||
return alpha;
|
||||
}
|
||||
|
||||
void AnimInverseKinematics::solve(const AnimContext& context, const std::vector<IKTarget>& targets, float dt, JointChainInfoVec& jointChainInfoVec) {
|
||||
// compute absolute poses that correspond to relative target poses
|
||||
AnimPoseVec absolutePoses;
|
||||
|
@ -227,6 +233,8 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector<
|
|||
accumulator.clearAndClean();
|
||||
}
|
||||
|
||||
std::map<int, int> targetToChainMap;
|
||||
|
||||
float maxError = 0.0f;
|
||||
int numLoops = 0;
|
||||
const int MAX_IK_LOOPS = 16;
|
||||
|
@ -248,17 +256,13 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector<
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// on last iteration, interpolate jointChains, if necessary
|
||||
if (numLoops == MAX_IK_LOOPS) {
|
||||
for (size_t i = 0; i < _prevJointChainInfoVec.size(); i++) {
|
||||
targetToChainMap.insert(std::pair<int, int>(_prevJointChainInfoVec[i].target.getIndex(), (int)i));
|
||||
if (_prevJointChainInfoVec[i].timer > 0.0f) {
|
||||
|
||||
float alpha = (JOINT_CHAIN_INTERP_TIME - _prevJointChainInfoVec[i].timer) / JOINT_CHAIN_INTERP_TIME;
|
||||
|
||||
// ease in expo
|
||||
alpha = 1.0f - powf(2.0f, -10.0f * alpha);
|
||||
|
||||
float alpha = getInterpolationAlpha(_prevJointChainInfoVec[i].timer);
|
||||
size_t chainSize = std::min(_prevJointChainInfoVec[i].jointInfoVec.size(), jointChainInfoVec[i].jointInfoVec.size());
|
||||
|
||||
if (jointChainInfoVec[i].target.getType() != IKTarget::Type::Unknown) {
|
||||
|
@ -336,22 +340,47 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector<
|
|||
for (auto& target: targets) {
|
||||
int tipIndex = target.getIndex();
|
||||
int parentIndex = (tipIndex >= 0) ? _skeleton->getParentIndex(tipIndex) : -1;
|
||||
|
||||
int chainIndex = targetToChainMap[tipIndex];
|
||||
bool needsInterpolation = _prevJointChainInfoVec[chainIndex].timer > 0.0f;
|
||||
float alpha = needsInterpolation ? getInterpolationAlpha(_prevJointChainInfoVec[chainIndex].timer) : 0.0f;
|
||||
// update rotationOnly targets that don't lie on the ik chain of other ik targets.
|
||||
if (parentIndex != -1 && !_rotationAccumulators[tipIndex].isDirty() && target.getType() == IKTarget::Type::RotationOnly) {
|
||||
const glm::quat& targetRotation = target.getRotation();
|
||||
// compute tip's new parent-relative rotation
|
||||
// Q = Qp * q --> q' = Qp^ * Q
|
||||
glm::quat newRelativeRotation = glm::inverse(absolutePoses[parentIndex].rot()) * targetRotation;
|
||||
RotationConstraint* constraint = getConstraint(tipIndex);
|
||||
if (constraint) {
|
||||
constraint->apply(newRelativeRotation);
|
||||
// TODO: ATM the final rotation target just fails but we need to provide
|
||||
// feedback to the IK system so that it can adjust the bones up the skeleton
|
||||
// to help this rotation target get met.
|
||||
if (parentIndex != -1 && !_rotationAccumulators[tipIndex].isDirty() &&
|
||||
(target.getType() == IKTarget::Type::RotationOnly || target.getType() == IKTarget::Type::Unknown)) {
|
||||
if (target.getType() == IKTarget::Type::RotationOnly) {
|
||||
const glm::quat& targetRotation = target.getRotation();
|
||||
// compute tip's new parent-relative rotation
|
||||
// Q = Qp * q --> q' = Qp^ * Q
|
||||
glm::quat newRelativeRotation = glm::inverse(absolutePoses[parentIndex].rot()) * targetRotation;
|
||||
RotationConstraint* constraint = getConstraint(tipIndex);
|
||||
if (constraint) {
|
||||
constraint->apply(newRelativeRotation);
|
||||
// TODO: ATM the final rotation target just fails but we need to provide
|
||||
// feedback to the IK system so that it can adjust the bones up the skeleton
|
||||
// to help this rotation target get met.
|
||||
}
|
||||
if (needsInterpolation) {
|
||||
_relativePoses[tipIndex].rot() = safeMix(_relativePoses[tipIndex].rot(), newRelativeRotation, alpha);
|
||||
} else {
|
||||
_relativePoses[tipIndex].rot() = newRelativeRotation;
|
||||
}
|
||||
// Add last known rotations to interpolate from
|
||||
if (_rotationOnlyIKRotations.find(tipIndex) == _rotationOnlyIKRotations.end()) {
|
||||
_rotationOnlyIKRotations.insert(std::pair<int, glm::quat>(tipIndex, _relativePoses[tipIndex].rot()));
|
||||
} else {
|
||||
_rotationOnlyIKRotations[tipIndex] = _relativePoses[tipIndex].rot();
|
||||
}
|
||||
absolutePoses[tipIndex].rot() = targetRotation;
|
||||
} else {
|
||||
bool rotationSnapshotExist = _rotationOnlyIKRotations.find(tipIndex) != _rotationOnlyIKRotations.end();
|
||||
if (needsInterpolation) {
|
||||
if (rotationSnapshotExist) {
|
||||
glm::quat lastKnownRotation = _rotationOnlyIKRotations[tipIndex];
|
||||
_relativePoses[tipIndex].rot() = safeMix(_relativePoses[tipIndex].rot(), lastKnownRotation, (1 - alpha));
|
||||
}
|
||||
} else if (rotationSnapshotExist) {
|
||||
_rotationOnlyIKRotations.erase(tipIndex);
|
||||
}
|
||||
}
|
||||
_relativePoses[tipIndex].rot() = newRelativeRotation;
|
||||
absolutePoses[tipIndex].rot() = targetRotation;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -928,6 +957,10 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
|||
(jointChainInfoVec[i].target.getType() != _prevJointChainInfoVec[i].target.getType() ||
|
||||
jointChainInfoVec[i].target.getPoleVectorEnabled() != _prevJointChainInfoVec[i].target.getPoleVectorEnabled())) {
|
||||
_prevJointChainInfoVec[i].timer = JOINT_CHAIN_INTERP_TIME;
|
||||
// Clear the rotations when the target is known
|
||||
if (jointChainInfoVec[i].target.getType() != IKTarget::Type::Unknown) {
|
||||
_rotationOnlyIKRotations.erase(jointChainInfoVec[i].target.getIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,6 +148,7 @@ protected:
|
|||
void clearConstraints();
|
||||
void initConstraints();
|
||||
void initLimitCenterPoses();
|
||||
float getInterpolationAlpha(float timer);
|
||||
|
||||
// no copies
|
||||
AnimInverseKinematics(const AnimInverseKinematics&) = delete;
|
||||
|
@ -181,6 +182,7 @@ protected:
|
|||
AnimPoseVec _defaultRelativePoses; // poses of the relaxed state
|
||||
AnimPoseVec _relativePoses; // current relative poses
|
||||
AnimPoseVec _limitCenterPoses; // relative
|
||||
std::map<int, glm::quat> _rotationOnlyIKRotations;
|
||||
|
||||
std::map<int, AnimPose> _secondaryTargetsInRigFrame;
|
||||
|
||||
|
|
|
@ -334,12 +334,17 @@ void Socket::checkForReadyReadBackup() {
|
|||
qCDebug(networking) << "Socket::checkForReadyReadyBackup() last sequence number"
|
||||
<< (uint32_t) _lastReceivedSequenceNumber << "from" << _lastPacketSockAddr << "-"
|
||||
<< _lastPacketSizeRead << "bytes";
|
||||
|
||||
#ifdef DEBUG_EVENT_QUEUE
|
||||
qCDebug(networking) << "NodeList event queue size:" << ::hifi::qt::getEventQueueSize(thread());
|
||||
#endif
|
||||
|
||||
// drop all of the pending datagrams on the floor
|
||||
int droppedCount = 0;
|
||||
while (_udpSocket.hasPendingDatagrams()) {
|
||||
_udpSocket.readDatagram(nullptr, 0);
|
||||
++droppedCount;
|
||||
}
|
||||
qCDebug(networking) << "Flushed" << droppedCount << "Packets";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,9 @@ const int TREE_SCALE = 32768; // ~20 miles.. This is the number of meters of the
|
|||
const int HALF_TREE_SCALE = TREE_SCALE / 2;
|
||||
|
||||
// This controls the LOD. Larger number will make smaller voxels visible at greater distance.
|
||||
const float MAX_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT = 400.0f; // max distance where a 1x1x1 cube is visible for 20:20 vision
|
||||
const float DEFAULT_OCTREE_SIZE_SCALE = TREE_SCALE * MAX_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT;
|
||||
const float DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT = 400.0f; // max distance where a 1x1x1 cube is visible for 20:20 vision
|
||||
const float UNIT_ELEMENT_MAX_EXTENT = sqrtf(3.0f) / 2.0f; // A unit cube tilted on its edge will have its edge jutting out sqrt(3)/2 units from the center
|
||||
const float DEFAULT_OCTREE_SIZE_SCALE = TREE_SCALE * DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT;
|
||||
|
||||
// Since entities like models live inside of octree cells, and they themselves can have very small mesh parts,
|
||||
// we want to have some constant that controls have big a mesh part must be to render even if the octree cell itself
|
||||
|
|
|
@ -18,64 +18,31 @@
|
|||
#include <AABox.h>
|
||||
#include <AACube.h>
|
||||
|
||||
float calculateRenderAccuracy(const glm::vec3& position,
|
||||
const AABox& bounds,
|
||||
float octreeSizeScale,
|
||||
int boundaryLevelAdjust) {
|
||||
float largestDimension = bounds.getLargestDimension();
|
||||
|
||||
const float maxScale = (float)TREE_SCALE;
|
||||
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / OCTREE_TO_MESH_RATIO;
|
||||
|
||||
static std::once_flag once;
|
||||
static QMap<float, float> shouldRenderTable;
|
||||
std::call_once(once, [&] {
|
||||
float SMALLEST_SCALE_IN_TABLE = 0.001f; // 1mm is plenty small
|
||||
float scale = maxScale;
|
||||
float factor = 1.0f;
|
||||
|
||||
while (scale > SMALLEST_SCALE_IN_TABLE) {
|
||||
scale /= 2.0f;
|
||||
factor /= 2.0f;
|
||||
shouldRenderTable[scale] = factor;
|
||||
}
|
||||
});
|
||||
|
||||
float closestScale = maxScale;
|
||||
float visibleDistanceAtClosestScale = visibleDistanceAtMaxScale;
|
||||
QMap<float, float>::const_iterator lowerBound = shouldRenderTable.lowerBound(largestDimension);
|
||||
if (lowerBound != shouldRenderTable.constEnd()) {
|
||||
closestScale = lowerBound.key();
|
||||
visibleDistanceAtClosestScale = visibleDistanceAtMaxScale * lowerBound.value();
|
||||
}
|
||||
|
||||
if (closestScale < largestDimension) {
|
||||
visibleDistanceAtClosestScale *= 2.0f;
|
||||
}
|
||||
|
||||
// FIXME - for now, it's either visible or not visible. We want to adjust this to eventually return
|
||||
// a floating point for objects that have small angular size to indicate that they may be rendered
|
||||
// with lower preciscion
|
||||
float distanceToCamera = glm::length(bounds.calcCenter() - position);
|
||||
return (distanceToCamera <= visibleDistanceAtClosestScale) ? 1.0f : 0.0f;
|
||||
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float visibilityDistance) {
|
||||
return visibilityDistance / powf(2.0f, renderLevel);
|
||||
}
|
||||
|
||||
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale) {
|
||||
return voxelSizeScale / powf(2.0f, renderLevel);
|
||||
float getPerspectiveAccuracyHalfAngleTan(float visibilityDistance, int boundaryLevelAdjust) {
|
||||
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, visibilityDistance);
|
||||
return UNIT_ELEMENT_MAX_EXTENT / visibleDistanceAtMaxScale;
|
||||
}
|
||||
|
||||
float getPerspectiveAccuracyAngleTan(float octreeSizeScale, int boundaryLevelAdjust) {
|
||||
const float maxScale = (float)TREE_SCALE;
|
||||
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / OCTREE_TO_MESH_RATIO;
|
||||
return (maxScale / visibleDistanceAtMaxScale);
|
||||
float getPerspectiveAccuracyHalfAngle(float visibilityDistance, int boundaryLevelAdjust) {
|
||||
return atan(getPerspectiveAccuracyHalfAngleTan(visibilityDistance, boundaryLevelAdjust));
|
||||
}
|
||||
|
||||
float getPerspectiveAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust) {
|
||||
return atan(getPerspectiveAccuracyAngleTan(octreeSizeScale, boundaryLevelAdjust));
|
||||
float getVisibilityDistanceFromHalfAngle(float halfAngle) {
|
||||
float halfAngleTan = tan(halfAngle);
|
||||
return UNIT_ELEMENT_MAX_EXTENT / halfAngleTan;
|
||||
}
|
||||
|
||||
float getOrthographicAccuracySize(float octreeSizeScale, int boundaryLevelAdjust) {
|
||||
float getHalfAngleFromVisibilityDistance(float visibilityDistance) {
|
||||
float halfAngleTan = UNIT_ELEMENT_MAX_EXTENT / visibilityDistance;
|
||||
return atan(halfAngleTan);
|
||||
}
|
||||
|
||||
float getOrthographicAccuracySize(float visibilityDistance, int boundaryLevelAdjust) {
|
||||
// Smallest visible element is 1cm
|
||||
const float smallestSize = 0.01f;
|
||||
return (smallestSize * MAX_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT) / boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale);
|
||||
return (smallestSize * DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT) / boundaryDistanceForRenderLevel(boundaryLevelAdjust, visibilityDistance);
|
||||
}
|
||||
|
|
|
@ -20,18 +20,13 @@ class AABox;
|
|||
class AACube;
|
||||
class QJsonDocument;
|
||||
|
||||
/// renderAccuracy represents a floating point "visibility" of an object based on it's view from the camera. At a simple
|
||||
/// level it returns 0.0f for things that are so small for the current settings that they could not be visible.
|
||||
float calculateRenderAccuracy(const glm::vec3& position,
|
||||
const AABox& bounds,
|
||||
float octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE,
|
||||
int boundaryLevelAdjust = 0);
|
||||
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float visibilityDistance);
|
||||
|
||||
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale);
|
||||
|
||||
float getPerspectiveAccuracyAngleTan(float octreeSizeScale, int boundaryLevelAdjust);
|
||||
float getPerspectiveAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust);
|
||||
float getOrthographicAccuracySize(float octreeSizeScale, int boundaryLevelAdjust);
|
||||
float getPerspectiveAccuracyHalfAngleTan(float visibilityDistance, int boundaryLevelAdjust);
|
||||
float getPerspectiveAccuracyHalfAngle(float visibilityDistance, int boundaryLevelAdjust);
|
||||
float getVisibilityDistanceFromHalfAngle(float halfAngle);
|
||||
float getHalfAngleFromVisibilityDistance(float visibilityDistance);
|
||||
float getOrthographicAccuracySize(float visibilityDistance, int boundaryLevelAdjust);
|
||||
|
||||
// MIN_ELEMENT_ANGULAR_DIAMETER = angular diameter of 1x1x1m cube at 400m = sqrt(3) / 400 = 0.0043301 radians ~= 0.25 degrees
|
||||
const float MIN_ELEMENT_ANGULAR_DIAMETER = 0.0043301f; // radians
|
||||
|
|
|
@ -120,7 +120,7 @@ void DrawSceneOctree::run(const RenderContextPointer& renderContext, const ItemS
|
|||
|
||||
// Draw the LOD Reticle
|
||||
{
|
||||
float angle = glm::degrees(getPerspectiveAccuracyAngle(args->_sizeScale, args->_boundaryLevelAdjust));
|
||||
float angle = glm::degrees(getPerspectiveAccuracyHalfAngle(args->_sizeScale, args->_boundaryLevelAdjust));
|
||||
Transform crosshairModel;
|
||||
crosshairModel.setTranslation(glm::vec3(0.0, 0.0, -1000.0));
|
||||
crosshairModel.setScale(1000.0f * tanf(glm::radians(angle))); // Scaling at the actual tan of the lod angle => Multiplied by TWO
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#ifdef WIN32
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX)
|
||||
// Enable event queue debugging
|
||||
#define DEBUG_EVENT_QUEUE
|
||||
#endif // WIN32
|
||||
#endif
|
||||
|
||||
namespace hifi { namespace qt {
|
||||
void addBlockingForbiddenThread(const QString& name, QThread* thread = nullptr);
|
||||
|
|
|
@ -80,7 +80,7 @@ Item {
|
|||
valueVar: LODManager["lodAngleDeg"]
|
||||
valueVarSetter: (function (v) { LODManager["lodAngleDeg"] = v })
|
||||
max: 90.0
|
||||
min: 0.5
|
||||
min: 0.01
|
||||
integral: false
|
||||
|
||||
anchors.left: parent.left
|
||||
|
@ -239,6 +239,7 @@ Item {
|
|||
object: LODManager
|
||||
valueScale: 1.0
|
||||
valueUnit: "deg"
|
||||
valueNumDigits: 2
|
||||
plots: [
|
||||
{
|
||||
prop: "lodAngleDeg",
|
||||
|
|
|
@ -533,7 +533,7 @@ function maybeUpdateOutputDeviceMutedOverlay() {
|
|||
var oldAutomaticLODAdjust;
|
||||
var oldLODAngleDeg;
|
||||
var SIMPLIFIED_UI_AUTO_LOD_ADJUST = false;
|
||||
var SIMPLIFIED_UI_LOD_ANGLE_DEG = 0.5;
|
||||
var SIMPLIFIED_UI_LOD_ANGLE_DEG = 0.248;
|
||||
function modifyLODSettings() {
|
||||
oldAutomaticLODAdjust = LODManager.automaticLODAdjust;
|
||||
oldLODAngleDeg = LODManager.lodAngleDeg;
|
||||
|
|
|
@ -30,6 +30,8 @@ source_group("UI Files" FILES ${QT_UI_FILES})
|
|||
# have qt5 wrap them and generate the appropriate header files
|
||||
qt5_wrap_ui(QT_UI_HEADERS "${QT_UI_FILES}")
|
||||
|
||||
setup_memory_debugger()
|
||||
|
||||
# add them to the nitpick source files
|
||||
set(NITPICK_SRCS ${NITPICK_SRCS} "${QT_UI_HEADERS}" "${QT_RESOURCES}")
|
||||
|
||||
|
|
Loading…
Reference in a new issue