mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 23:33:26 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
08c48bf6a7
8 changed files with 130 additions and 23 deletions
|
@ -139,22 +139,22 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
|
|||
double start = usecTimestampNow();
|
||||
double sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000.0;
|
||||
|
||||
if (sinceLastTime <= std::max(_setupNewVoxelsForDrawingLastElapsed,SIXTY_FPS_IN_MILLISECONDS)) {
|
||||
if (sinceLastTime <= std::max(_setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) {
|
||||
return; // bail early, it hasn't been long enough since the last time we ran
|
||||
}
|
||||
|
||||
double sinceLastViewCulling = (start - _lastViewCulling) / 1000.0;
|
||||
|
||||
// If the view frustum has changed, since last time, then remove nodes that are out of view
|
||||
if ((sinceLastViewCulling >= VIEW_CULLING_RATE_IN_MILLISECONDS) && hasViewChanged()) {
|
||||
if ((sinceLastViewCulling >= std::max(_lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) && hasViewChanged()) {
|
||||
_lastViewCulling = start;
|
||||
removeOutOfView();
|
||||
double endViewCulling = usecTimestampNow();
|
||||
_lastViewCullingElapsed = (endViewCulling - start) / 1000.0;
|
||||
}
|
||||
|
||||
if (_tree->isDirty()) {
|
||||
PerformanceWarning warn(_renderWarningsOn, "calling... newTreeToArrays()");
|
||||
_callsToTreesToArrays++;
|
||||
|
||||
if (_alwaysRenderFullVBO) {
|
||||
_voxelsInWriteArrays = 0; // reset our VBO
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
|
|||
copyWrittenDataToReadArrays();
|
||||
|
||||
double end = usecTimestampNow();
|
||||
double elapsedmsec = (end - start)/1000.0;
|
||||
double elapsedmsec = (end - start) / 1000.0;
|
||||
_setupNewVoxelsForDrawingLastFinished = end;
|
||||
_setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ void VoxelSystem::init() {
|
|||
_callsToTreesToArrays = 0;
|
||||
_setupNewVoxelsForDrawingLastFinished = 0;
|
||||
_setupNewVoxelsForDrawingLastElapsed = 0;
|
||||
_lastViewCulling = 0;
|
||||
_lastViewCullingElapsed = _lastViewCulling = 0;
|
||||
|
||||
// When we change voxels representations in the arrays, we'll update this
|
||||
_voxelsDirty = false;
|
||||
|
@ -583,17 +583,71 @@ void VoxelSystem::falseColorizeDistanceFromView(ViewFrustum* viewFrustum) {
|
|||
setupNewVoxelsForDrawing();
|
||||
}
|
||||
|
||||
// combines the removeOutOfView args into a single class
|
||||
class removeOutOfViewArgs {
|
||||
public:
|
||||
VoxelSystem* thisVoxelSystem;
|
||||
VoxelNodeBag dontRecurseBag;
|
||||
unsigned long nodesScanned;
|
||||
unsigned long nodesRemoved;
|
||||
unsigned long nodesInside;
|
||||
unsigned long nodesIntersect;
|
||||
unsigned long nodesOutside;
|
||||
|
||||
removeOutOfViewArgs(VoxelSystem* voxelSystem) :
|
||||
thisVoxelSystem(voxelSystem),
|
||||
dontRecurseBag(),
|
||||
nodesScanned(0),
|
||||
nodesRemoved(0),
|
||||
nodesInside(0),
|
||||
nodesIntersect(0),
|
||||
nodesOutside(0)
|
||||
{ }
|
||||
};
|
||||
|
||||
// "Remove" voxels from the tree that are not in view. We don't actually delete them,
|
||||
// we remove them from the tree and place them into a holding area for later deletion
|
||||
bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) {
|
||||
VoxelSystem* thisVoxelSystem = (VoxelSystem*) extraData;
|
||||
_nodeCount++;
|
||||
removeOutOfViewArgs* args = (removeOutOfViewArgs*)extraData;
|
||||
|
||||
// If our node was previously added to the don't recurse bag, then return false to
|
||||
// stop the further recursion. This means that the whole node and it's children are
|
||||
// known to be in view, so don't recurse them
|
||||
if (args->dontRecurseBag.contains(node)) {
|
||||
args->dontRecurseBag.remove(node);
|
||||
return false; // stop recursion
|
||||
}
|
||||
|
||||
VoxelSystem* thisVoxelSystem = args->thisVoxelSystem;
|
||||
args->nodesScanned++;
|
||||
// Need to operate on our child nodes, so we can remove them
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
VoxelNode* childNode = node->getChildAtIndex(i);
|
||||
if (childNode && !childNode->isInView(*thisVoxelSystem->_viewFrustum)) {
|
||||
node->removeChildAtIndex(i);
|
||||
thisVoxelSystem->_removedVoxels.insert(childNode);
|
||||
if (childNode) {
|
||||
ViewFrustum::location inFrustum = childNode->inFrustum(*thisVoxelSystem->_viewFrustum);
|
||||
switch (inFrustum) {
|
||||
case ViewFrustum::OUTSIDE: {
|
||||
args->nodesOutside++;
|
||||
args->nodesRemoved++;
|
||||
node->removeChildAtIndex(i);
|
||||
thisVoxelSystem->_removedVoxels.insert(childNode);
|
||||
// by removing the child, it will not get recursed!
|
||||
} break;
|
||||
case ViewFrustum::INSIDE: {
|
||||
// if the child node is fully INSIDE the view, then there's no need to recurse it
|
||||
// because we know all it's children will also be in the view, so we want to
|
||||
// tell the caller to NOT recurse this child
|
||||
args->nodesInside++;
|
||||
args->dontRecurseBag.insert(childNode);
|
||||
} break;
|
||||
case ViewFrustum::INTERSECT: {
|
||||
// if the child node INTERSECTs the view, then we don't want to remove it because
|
||||
// it is at least partially in view. But we DO want to recurse the children because
|
||||
// some of them may not be in view... nothing specifically to do, just keep iterating
|
||||
// the children
|
||||
args->nodesIntersect++;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true; // keep going!
|
||||
|
@ -609,7 +663,14 @@ bool VoxelSystem::hasViewChanged() {
|
|||
}
|
||||
|
||||
void VoxelSystem::removeOutOfView() {
|
||||
PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()"); // would like to include removedCount, _nodeCount, _removedVoxels.count()
|
||||
_nodeCount = 0;
|
||||
_tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)this);
|
||||
PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()");
|
||||
removeOutOfViewArgs args(this);
|
||||
_tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args);
|
||||
|
||||
if (_renderWarningsOn) {
|
||||
printLog("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld bag.count()=%d \n",
|
||||
args.nodesScanned, args.nodesRemoved, args.nodesInside,
|
||||
args.nodesIntersect, args.nodesOutside, args.dontRecurseBag.count()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ private:
|
|||
double _setupNewVoxelsForDrawingLastElapsed;
|
||||
double _setupNewVoxelsForDrawingLastFinished;
|
||||
double _lastViewCulling;
|
||||
double _lastViewCullingElapsed;
|
||||
|
||||
GLuint _vboVerticesID;
|
||||
GLuint _vboNormalsID;
|
||||
|
|
|
@ -158,12 +158,12 @@ const char* ViewFrustum::debugPlaneName (int plane) const {
|
|||
}
|
||||
|
||||
|
||||
int ViewFrustum::pointInFrustum(const glm::vec3& point) const {
|
||||
ViewFrustum::location ViewFrustum::pointInFrustum(const glm::vec3& point) const {
|
||||
|
||||
//printf("ViewFrustum::pointInFrustum() point=%f,%f,%f\n",point.x,point.y,point.z);
|
||||
//dump();
|
||||
|
||||
int result = INSIDE;
|
||||
ViewFrustum::location result = INSIDE;
|
||||
for(int i=0; i < 6; i++) {
|
||||
float distance = _planes[i].distance(point);
|
||||
|
||||
|
@ -176,8 +176,8 @@ int ViewFrustum::pointInFrustum(const glm::vec3& point) const {
|
|||
return(result);
|
||||
}
|
||||
|
||||
int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) const {
|
||||
int result = INSIDE;
|
||||
ViewFrustum::location ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) const {
|
||||
ViewFrustum::location result = INSIDE;
|
||||
float distance;
|
||||
for(int i=0; i < 6; i++) {
|
||||
distance = _planes[i].distance(center);
|
||||
|
@ -190,11 +190,11 @@ int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) const {
|
|||
}
|
||||
|
||||
|
||||
int ViewFrustum::boxInFrustum(const AABox& box) const {
|
||||
ViewFrustum::location ViewFrustum::boxInFrustum(const AABox& box) const {
|
||||
|
||||
//printf("ViewFrustum::boxInFrustum() box.corner=%f,%f,%f x=%f\n",
|
||||
// box.getCorner().x,box.getCorner().y,box.getCorner().z,box.getSize().x);
|
||||
int result = INSIDE;
|
||||
ViewFrustum::location result = INSIDE;
|
||||
for(int i=0; i < 6; i++) {
|
||||
|
||||
//printf("plane[%d] -- point(%f,%f,%f) normal(%f,%f,%f) d=%f \n",i,
|
||||
|
|
|
@ -94,9 +94,9 @@ public:
|
|||
|
||||
typedef enum {OUTSIDE, INTERSECT, INSIDE} location;
|
||||
|
||||
int pointInFrustum(const glm::vec3& point) const;
|
||||
int sphereInFrustum(const glm::vec3& center, float radius) const;
|
||||
int boxInFrustum(const AABox& box) const;
|
||||
ViewFrustum::location pointInFrustum(const glm::vec3& point) const;
|
||||
ViewFrustum::location sphereInFrustum(const glm::vec3& center, float radius) const;
|
||||
ViewFrustum::location boxInFrustum(const AABox& box) const;
|
||||
|
||||
// some frustum comparisons
|
||||
bool matches(const ViewFrustum& compareTo) const;
|
||||
|
|
|
@ -259,6 +259,12 @@ bool VoxelNode::isInView(const ViewFrustum& viewFrustum) const {
|
|||
return inView;
|
||||
}
|
||||
|
||||
ViewFrustum::location VoxelNode::inFrustum(const ViewFrustum& viewFrustum) const {
|
||||
AABox box = _box; // use temporary box so we can scale it
|
||||
box.scale(TREE_SCALE);
|
||||
return viewFrustum.boxInFrustum(box);
|
||||
}
|
||||
|
||||
float VoxelNode::distanceToCamera(const ViewFrustum& viewFrustum) const {
|
||||
glm::vec3 center = _box.getCenter() * (float)TREE_SCALE;
|
||||
float distanceToVoxelCenter = sqrtf(powf(viewFrustum.getPosition().x - center.x, 2) +
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
|
||||
bool isColored() const { return (_trueColor[3]==1); };
|
||||
bool isInView(const ViewFrustum& viewFrustum) const;
|
||||
ViewFrustum::location inFrustum(const ViewFrustum& viewFrustum) const;
|
||||
float distanceToCamera(const ViewFrustum& viewFrustum) const;
|
||||
bool isLeaf() const;
|
||||
void printDebugDetails(const char* label) const;
|
||||
|
|
|
@ -82,3 +82,39 @@ VoxelNode* VoxelNodeBag::extract() {
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool VoxelNodeBag::contains(VoxelNode* node) {
|
||||
for (int i = 0; i < _elementsInUse; i++) {
|
||||
// just compare the pointers... that's good enough
|
||||
if (_bagElements[i] == node) {
|
||||
return true; // exit early!!
|
||||
}
|
||||
// if we're past where it should be, then it's not here!
|
||||
if (_bagElements[i] > node) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// if we made it through the entire bag, it's not here!
|
||||
return false;
|
||||
}
|
||||
|
||||
void VoxelNodeBag::remove(VoxelNode* node) {
|
||||
int foundAt = -1;
|
||||
for (int i = 0; i < _elementsInUse; i++) {
|
||||
// just compare the pointers... that's good enough
|
||||
if (_bagElements[i] == node) {
|
||||
foundAt = i;
|
||||
break;
|
||||
}
|
||||
// if we're past where it should be, then it's not here!
|
||||
if (_bagElements[i] > node) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if we found it, then we need to remove it....
|
||||
if (foundAt != -1) {
|
||||
memmove(&_bagElements[foundAt], &_bagElements[foundAt + 1], (_elementsInUse - foundAt) * sizeof(VoxelNode*));
|
||||
_elementsInUse--;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ public:
|
|||
|
||||
void insert(VoxelNode* node); // put a node into the bag
|
||||
VoxelNode* extract(); // pull a node out of the bag (could come in any order)
|
||||
bool contains(VoxelNode* node); // is this node in the bag?
|
||||
void remove(VoxelNode* node); // remove a specific item from the bag
|
||||
|
||||
bool isEmpty() const { return (_elementsInUse == 0); };
|
||||
int count() const { return _elementsInUse; };
|
||||
|
|
Loading…
Reference in a new issue