mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 09:24:00 +02:00
improvements to subtle moves for view frustum and voxel serving
This commit is contained in:
parent
0188d55ad3
commit
b4c88a85f8
9 changed files with 133 additions and 21 deletions
|
@ -1700,7 +1700,7 @@ bool VoxelSystem::isViewChanging() {
|
|||
bool result = false; // assume the best
|
||||
|
||||
// If our viewFrustum has changed since our _lastKnownViewFrustum
|
||||
if (!_lastKnownViewFrustum.matches(_viewFrustum)) {
|
||||
if (!_lastKnownViewFrustum.isVerySimilar(_viewFrustum)) {
|
||||
result = true;
|
||||
_lastKnownViewFrustum = *_viewFrustum; // save last known
|
||||
}
|
||||
|
@ -1716,7 +1716,7 @@ bool VoxelSystem::hasViewChanged() {
|
|||
}
|
||||
|
||||
// If our viewFrustum has changed since our _lastKnownViewFrustum
|
||||
if (!_lastStableViewFrustum.matches(_viewFrustum)) {
|
||||
if (!_lastStableViewFrustum.isVerySimilar(_viewFrustum)) {
|
||||
result = true;
|
||||
_lastStableViewFrustum = *_viewFrustum; // save last stable
|
||||
}
|
||||
|
@ -1867,7 +1867,7 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!forceFullFrustum && _culledOnce && args.lastViewFrustum.matches(args.thisViewFrustum)) {
|
||||
if (!forceFullFrustum && _culledOnce && args.lastViewFrustum.isVerySimilar(args.thisViewFrustum)) {
|
||||
//printf("view frustum hasn't changed BAIL!!!\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ bool VoxelNodeData::updateCurrentViewFrustum() {
|
|||
newestViewFrustum.setEyeOffsetPosition(getCameraEyeOffsetPosition());
|
||||
|
||||
// if there has been a change, then recalculate
|
||||
if (!newestViewFrustum.matches(_currentViewFrustum)) {
|
||||
if (!newestViewFrustum.isVerySimilar(_currentViewFrustum)) {
|
||||
_currentViewFrustum = newestViewFrustum;
|
||||
_currentViewFrustum.calculate();
|
||||
currentViewFrustumChanged = true;
|
||||
|
@ -109,7 +109,7 @@ void VoxelNodeData::setViewSent(bool viewSent) {
|
|||
|
||||
|
||||
void VoxelNodeData::updateLastKnownViewFrustum() {
|
||||
bool frustumChanges = !_lastKnownViewFrustum.matches(_currentViewFrustum);
|
||||
bool frustumChanges = !_lastKnownViewFrustum.isVerySimilar(_currentViewFrustum);
|
||||
|
||||
if (frustumChanges) {
|
||||
// save our currentViewFrustum into our lastKnownViewFrustum
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
@ -296,17 +298,17 @@ ViewFrustum::location ViewFrustum::boxInFrustum(const AABox& box) const {
|
|||
return regularResult;
|
||||
}
|
||||
|
||||
bool testMatches(glm::quat lhs, glm::quat rhs) {
|
||||
return (fabs(lhs.x - rhs.x) <= EPSILON && fabs(lhs.y - rhs.y) <= EPSILON && fabs(lhs.z - rhs.z) <= EPSILON
|
||||
&& fabs(lhs.w - rhs.w) <= EPSILON);
|
||||
bool testMatches(glm::quat lhs, glm::quat rhs, float epsilon = EPSILON) {
|
||||
return (fabs(lhs.x - rhs.x) <= epsilon && fabs(lhs.y - rhs.y) <= epsilon && fabs(lhs.z - rhs.z) <= epsilon
|
||||
&& fabs(lhs.w - rhs.w) <= epsilon);
|
||||
}
|
||||
|
||||
bool testMatches(glm::vec3 lhs, glm::vec3 rhs) {
|
||||
return (fabs(lhs.x - rhs.x) <= EPSILON && fabs(lhs.y - rhs.y) <= EPSILON && fabs(lhs.z - rhs.z) <= EPSILON);
|
||||
bool testMatches(glm::vec3 lhs, glm::vec3 rhs, float epsilon = EPSILON) {
|
||||
return (fabs(lhs.x - rhs.x) <= epsilon && fabs(lhs.y - rhs.y) <= epsilon && fabs(lhs.z - rhs.z) <= epsilon);
|
||||
}
|
||||
|
||||
bool testMatches(float lhs, float rhs) {
|
||||
return (fabs(lhs - rhs) <= EPSILON);
|
||||
bool testMatches(float lhs, float rhs, float epsilon = EPSILON) {
|
||||
return (fabs(lhs - rhs) <= epsilon);
|
||||
}
|
||||
|
||||
bool ViewFrustum::matches(const ViewFrustum& compareTo, bool debug) const {
|
||||
|
@ -369,6 +371,93 @@ bool ViewFrustum::matches(const ViewFrustum& compareTo, bool debug) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
bool isNaN(float f) {
|
||||
return f != f;
|
||||
}
|
||||
|
||||
bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const {
|
||||
|
||||
// Compute distance between the two positions
|
||||
const float POSITION_SIMILAR_ENOUGH = 5.0f; // 5 meters
|
||||
float positionDistance = glm::distance(_position, compareTo._position);
|
||||
|
||||
const float EYEOFFSET_POSITION_SIMILAR_ENOUGH = 0.15f; // 0.15 meters
|
||||
float eyeOffsetpositionDistance = glm::distance(_eyeOffsetPosition, compareTo._eyeOffsetPosition);
|
||||
|
||||
// Compute the angular distance between the two orientations
|
||||
const float ORIENTATION_SIMILAR_ENOUGH = 10.0f; // 10 degrees in any direction
|
||||
glm::quat dQOrientation = _orientation * glm::inverse(compareTo._orientation);
|
||||
float angleOrientation = compareTo._orientation == _orientation ? 0.0f : glm::angle(dQOrientation);
|
||||
if (isNaN(angleOrientation)) {
|
||||
angleOrientation = 0.0f;
|
||||
}
|
||||
|
||||
glm::quat dQEyeOffsetOrientation = _eyeOffsetOrientation * glm::inverse(compareTo._eyeOffsetOrientation);
|
||||
float angleEyeOffsetOrientation = compareTo._eyeOffsetOrientation == _eyeOffsetOrientation
|
||||
? 0.0f : glm::angle(dQEyeOffsetOrientation);
|
||||
if (isNaN(angleEyeOffsetOrientation)) {
|
||||
angleOrientation = 0.0f;
|
||||
}
|
||||
|
||||
bool result =
|
||||
testMatches(0, positionDistance, POSITION_SIMILAR_ENOUGH) &&
|
||||
testMatches(0, angleOrientation, ORIENTATION_SIMILAR_ENOUGH) &&
|
||||
testMatches(compareTo._fieldOfView, _fieldOfView) &&
|
||||
testMatches(compareTo._aspectRatio, _aspectRatio) &&
|
||||
testMatches(compareTo._nearClip, _nearClip) &&
|
||||
testMatches(compareTo._farClip, _farClip) &&
|
||||
testMatches(compareTo._focalLength, _focalLength) &&
|
||||
testMatches(0, eyeOffsetpositionDistance, EYEOFFSET_POSITION_SIMILAR_ENOUGH) &&
|
||||
testMatches(0, angleEyeOffsetOrientation, ORIENTATION_SIMILAR_ENOUGH);
|
||||
|
||||
|
||||
if (!result && debug) {
|
||||
qDebug("ViewFrustum::isVerySimilar()... result=%s\n", debug::valueOf(result));
|
||||
qDebug("%s -- compareTo._position=%f,%f,%f _position=%f,%f,%f\n",
|
||||
(testMatches(compareTo._position,_position, POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||
compareTo._position.x, compareTo._position.y, compareTo._position.z,
|
||||
_position.x, _position.y, _position.z );
|
||||
|
||||
qDebug("%s -- positionDistance=%f\n",
|
||||
(testMatches(0,positionDistance, POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||
positionDistance);
|
||||
|
||||
qDebug("%s -- angleOrientation=%f\n",
|
||||
(testMatches(0, angleOrientation, ORIENTATION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||
angleOrientation);
|
||||
|
||||
qDebug("%s -- compareTo._fieldOfView=%f _fieldOfView=%f\n",
|
||||
(testMatches(compareTo._fieldOfView, _fieldOfView) ? "MATCHES " : "NO MATCH"),
|
||||
compareTo._fieldOfView, _fieldOfView);
|
||||
qDebug("%s -- compareTo._aspectRatio=%f _aspectRatio=%f\n",
|
||||
(testMatches(compareTo._aspectRatio, _aspectRatio) ? "MATCHES " : "NO MATCH"),
|
||||
compareTo._aspectRatio, _aspectRatio);
|
||||
qDebug("%s -- compareTo._nearClip=%f _nearClip=%f\n",
|
||||
(testMatches(compareTo._nearClip, _nearClip) ? "MATCHES " : "NO MATCH"),
|
||||
compareTo._nearClip, _nearClip);
|
||||
qDebug("%s -- compareTo._farClip=%f _farClip=%f\n",
|
||||
(testMatches(compareTo._farClip, _farClip) ? "MATCHES " : "NO MATCH"),
|
||||
compareTo._farClip, _farClip);
|
||||
qDebug("%s -- compareTo._focalLength=%f _focalLength=%f\n",
|
||||
(testMatches(compareTo._focalLength, _focalLength) ? "MATCHES " : "NO MATCH"),
|
||||
compareTo._focalLength, _focalLength);
|
||||
|
||||
qDebug("%s -- compareTo._eyeOffsetPosition=%f,%f,%f _eyeOffsetPosition=%f,%f,%f\n",
|
||||
(testMatches(compareTo._eyeOffsetPosition, _eyeOffsetPosition, POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||
compareTo._eyeOffsetPosition.x, compareTo._eyeOffsetPosition.y, compareTo._eyeOffsetPosition.z,
|
||||
_eyeOffsetPosition.x, _eyeOffsetPosition.y, _eyeOffsetPosition.z);
|
||||
|
||||
qDebug("%s -- eyeOffsetpositionDistance=%f\n",
|
||||
(testMatches(0,eyeOffsetpositionDistance, EYEOFFSET_POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||
eyeOffsetpositionDistance);
|
||||
|
||||
qDebug("%s -- angleEyeOffsetOrientation=%f\n",
|
||||
(testMatches(0, angleEyeOffsetOrientation, ORIENTATION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||
angleEyeOffsetOrientation);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ViewFrustum::computePickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const {
|
||||
origin = _nearTopLeft + x*(_nearTopRight - _nearTopLeft) + y*(_nearBottomLeft - _nearTopLeft);
|
||||
direction = glm::normalize(origin - (_position + _orientation * _eyeOffsetPosition));
|
||||
|
|
|
@ -85,6 +85,9 @@ public:
|
|||
bool matches(const ViewFrustum& compareTo, bool debug = false) const;
|
||||
bool matches(const ViewFrustum* compareTo, bool debug = false) const { return matches(*compareTo, debug); }
|
||||
|
||||
bool isVerySimilar(const ViewFrustum& compareTo, bool debug = false) const;
|
||||
bool isVerySimilar(const ViewFrustum* compareTo, bool debug = false) const { return isVerySimilar(*compareTo, debug); }
|
||||
|
||||
void computePickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const;
|
||||
|
||||
void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& near, float& far,
|
||||
|
|
|
@ -54,4 +54,9 @@ const uint64_t CLIENT_TO_SERVER_VOXEL_SEND_INTERVAL_USECS = 1000 * 5; // 1 packe
|
|||
|
||||
const float VIEW_FRUSTUM_FOV_OVERSEND = 60.0f;
|
||||
|
||||
// These are guards to prevent our voxel tree recursive routines from spinning out of control
|
||||
const int UNREASONABLY_DEEP_RECURSION = 20; // use this for something that you want to be shallow, but not spin out
|
||||
const int DANGEROUSLY_DEEP_RECURSION = 200; // use this for something that needs to go deeper
|
||||
|
||||
|
||||
#endif
|
|
@ -1021,14 +1021,18 @@ VoxelNode* VoxelNode::addChildAtIndex(int childIndex) {
|
|||
}
|
||||
|
||||
// handles staging or deletion of all deep children
|
||||
void VoxelNode::safeDeepDeleteChildAtIndex(int childIndex) {
|
||||
void VoxelNode::safeDeepDeleteChildAtIndex(int childIndex, int recursionCount) {
|
||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||
qDebug() << "VoxelNode::safeDeepDeleteChildAtIndex() reached DANGEROUSLY_DEEP_RECURSION, bailing!\n";
|
||||
return;
|
||||
}
|
||||
VoxelNode* childToDelete = getChildAtIndex(childIndex);
|
||||
if (childToDelete) {
|
||||
// If the child is not a leaf, then call ourselves recursively on all the children
|
||||
if (!childToDelete->isLeaf()) {
|
||||
// delete all it's children
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
childToDelete->safeDeepDeleteChildAtIndex(i);
|
||||
childToDelete->safeDeepDeleteChildAtIndex(i,recursionCount+1);
|
||||
}
|
||||
}
|
||||
deleteChildAtIndex(childIndex);
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
void deleteChildAtIndex(int childIndex);
|
||||
VoxelNode* removeChildAtIndex(int childIndex);
|
||||
VoxelNode* addChildAtIndex(int childIndex);
|
||||
void safeDeepDeleteChildAtIndex(int childIndex); // handles deletion of all descendents
|
||||
void safeDeepDeleteChildAtIndex(int childIndex, int recursionCount = 0); // handles deletion of all descendents
|
||||
|
||||
void setColorFromAverageOfChildren();
|
||||
void setRandomColor(int minimumBrightness);
|
||||
|
|
|
@ -78,13 +78,18 @@ void VoxelTree::recurseTreeWithOperation(RecurseVoxelTreeOperation operation, vo
|
|||
}
|
||||
|
||||
// Recurses voxel node with an operation function
|
||||
void VoxelTree::recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData) {
|
||||
void VoxelTree::recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData,
|
||||
int recursionCount) {
|
||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||
qDebug() << "VoxelTree::recurseNodeWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (operation(node, extraData)) {
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
VoxelNode* child = node->getChildAtIndex(i);
|
||||
if (child) {
|
||||
recurseNodeWithOperation(child, operation, extraData);
|
||||
recurseNodeWithOperation(child, operation, extraData, recursionCount+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +105,13 @@ void VoxelTree::recurseTreeWithOperationDistanceSorted(RecurseVoxelTreeOperation
|
|||
|
||||
// Recurses voxel node with an operation function
|
||||
void VoxelTree::recurseNodeWithOperationDistanceSorted(VoxelNode* node, RecurseVoxelTreeOperation operation,
|
||||
const glm::vec3& point, void* extraData) {
|
||||
const glm::vec3& point, void* extraData, int recursionCount) {
|
||||
|
||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||
qDebug() << "VoxelTree::recurseNodeWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (operation(node, extraData)) {
|
||||
// determine the distance sorted order of our children
|
||||
VoxelNode* sortedChildren[NUMBER_OF_CHILDREN];
|
||||
|
@ -641,7 +652,6 @@ void VoxelTree::reaverageVoxelColors(VoxelNode* startNode) {
|
|||
} else {
|
||||
recursionCount++;
|
||||
}
|
||||
const int UNREASONABLY_DEEP_RECURSION = 20;
|
||||
if (recursionCount > UNREASONABLY_DEEP_RECURSION) {
|
||||
qDebug("VoxelTree::reaverageVoxelColors()... bailing out of UNREASONABLY_DEEP_RECURSION\n");
|
||||
recursionCount--;
|
||||
|
|
|
@ -190,10 +190,11 @@ public:
|
|||
|
||||
bool getShouldReaverage() const { return _shouldReaverage; }
|
||||
|
||||
void recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData);
|
||||
void recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation,
|
||||
void* extraData, int recursionCount = 0);
|
||||
|
||||
void recurseNodeWithOperationDistanceSorted(VoxelNode* node, RecurseVoxelTreeOperation operation,
|
||||
const glm::vec3& point, void* extraData);
|
||||
const glm::vec3& point, void* extraData, int recursionCount = 0);
|
||||
|
||||
void nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmount, VoxelEditPacketSender& voxelEditSender);
|
||||
|
||||
|
|
Loading…
Reference in a new issue