From 1284f9d09aaa9c42613404a23a55a0b1ade3fbfe Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 19 Jun 2013 13:45:13 -0700 Subject: [PATCH] naming cleanup and some optimizations --- interface/src/VoxelSystem.cpp | 20 ++++---- libraries/voxels/src/AABox.cpp | 11 ++++ libraries/voxels/src/AABox.h | 1 + libraries/voxels/src/ViewFrustum.cpp | 75 +++++++++++++--------------- libraries/voxels/src/ViewFrustum.h | 9 ++-- libraries/voxels/src/VoxelTree.cpp | 23 +++++---- 6 files changed, 74 insertions(+), 65 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 4a81d3ec2d..25ed13b338 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -1202,19 +1202,19 @@ bool VoxelSystem::falseColorizeOccludedOperation(VoxelNode* node, void* extraDat AABox voxelBox = node->getAABox(); voxelBox.scale(TREE_SCALE); - VoxelProjectedPolygon* voxelShadow = new VoxelProjectedPolygon(args->viewFrustum->getProjectedShadow(voxelBox)); + VoxelProjectedPolygon* voxelPolygon = new VoxelProjectedPolygon(args->viewFrustum->getProjectedPolygon(voxelBox)); // If we're not all in view, then ignore it, and just return. But keep searching... - if (!voxelShadow->getAllInView()) { + if (!voxelPolygon->getAllInView()) { args->nonLeavesOutOfView++; - delete voxelShadow; + delete voxelPolygon; return true; } - CoverageMap::StorageResult result = args->map->checkMap(voxelShadow, false); + CoverageMap::StorageResult result = args->map->checkMap(voxelPolygon, false); if (result == CoverageMap::OCCLUDED) { args->nonLeavesOccluded++; - delete voxelShadow; + delete voxelPolygon; FalseColorizeSubTreeOperationArgs subArgs; subArgs.color[0] = 0; @@ -1230,7 +1230,7 @@ bool VoxelSystem::falseColorizeOccludedOperation(VoxelNode* node, void* extraDat return false; } - delete voxelShadow; + delete voxelPolygon; return true; // keep looking... } @@ -1239,16 +1239,16 @@ bool VoxelSystem::falseColorizeOccludedOperation(VoxelNode* node, void* extraDat AABox voxelBox = node->getAABox(); voxelBox.scale(TREE_SCALE); - VoxelProjectedPolygon* voxelShadow = new VoxelProjectedPolygon(args->viewFrustum->getProjectedShadow(voxelBox)); + VoxelProjectedPolygon* voxelPolygon = new VoxelProjectedPolygon(args->viewFrustum->getProjectedPolygon(voxelBox)); // If we're not all in view, then ignore it, and just return. But keep searching... - if (!voxelShadow->getAllInView()) { + if (!voxelPolygon->getAllInView()) { args->outOfView++; - delete voxelShadow; + delete voxelPolygon; return true; } - CoverageMap::StorageResult result = args->map->checkMap(voxelShadow, true); + CoverageMap::StorageResult result = args->map->checkMap(voxelPolygon, true); if (result == CoverageMap::OCCLUDED) { node->setFalseColor(255, 0, 0); args->occludedVoxels++; diff --git a/libraries/voxels/src/AABox.cpp b/libraries/voxels/src/AABox.cpp index d4b7e1383c..36e65561c3 100644 --- a/libraries/voxels/src/AABox.cpp +++ b/libraries/voxels/src/AABox.cpp @@ -105,6 +105,17 @@ bool AABox::contains(const glm::vec3& point) const { isWithin(point.z, _corner.z, _size.z); } +bool AABox::contains(const AABox& otherBox) const { + for (int v = BOTTOM_LEFT_NEAR; v < TOP_LEFT_FAR; v++) { + glm::vec3 vertex = otherBox.getVertex((BoxVertex)v); + if (!contains(vertex)) { + return false; + } + } + return true; +} + + // determines whether a value is within the expanded extents static bool isWithinExpanded(float value, float corner, float size, float expansion) { return value >= corner - expansion && value <= corner + size + expansion; diff --git a/libraries/voxels/src/AABox.h b/libraries/voxels/src/AABox.h index d295f24aea..735799cd05 100644 --- a/libraries/voxels/src/AABox.h +++ b/libraries/voxels/src/AABox.h @@ -63,6 +63,7 @@ public: glm::vec3 getVertex(BoxVertex vertex) const; bool contains(const glm::vec3& point) const; + bool contains(const AABox& otherBox) const; bool expandedContains(const glm::vec3& point, float expansion) const; bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const; bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index f231688c77..4ded457d44 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -123,6 +123,10 @@ void ViewFrustum::calculate() { // Our ModelViewProjection : multiplication of our 3 matrices (note: model is identity, so we can drop it) _ourModelViewProjectionMatrix = projection * view; // Remember, matrix multiplication is the other way around + + // Set up our keyhole bounding box... + glm::vec3 corner = _position - _keyholeRadius; + _keyholeBoundingBox = AABox(corner,(_keyholeRadius * 2.0f)); } //enum { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE }; @@ -138,14 +142,14 @@ const char* ViewFrustum::debugPlaneName (int plane) const { return "Unknown"; } -ViewFrustum::location ViewFrustum::pointInSphere(const glm::vec3& point, const glm::vec3& center, float radius ) const { +ViewFrustum::location ViewFrustum::pointInKeyhole(const glm::vec3& point) const { ViewFrustum::location result = INTERSECT; - float distance = glm::distance(point, center); - if (distance > radius) { + float distance = glm::distance(point, _position); + if (distance > _keyholeRadius) { result = OUTSIDE; - } else if (distance < radius) { + } else if (distance < _keyholeRadius) { result = INSIDE; } @@ -155,15 +159,13 @@ ViewFrustum::location ViewFrustum::pointInSphere(const glm::vec3& point, const g // To determine if two spheres intersect, simply calculate the distance between the centers of the two spheres. // If the distance is greater than the sum of the two sphere radii, they don’t intersect. Otherwise they intersect. // If the distance plus the radius of sphere A is less than the radius of sphere B then, sphere A is inside of sphere B -ViewFrustum::location ViewFrustum::sphereInSphere(const glm::vec3& centerA, float radiusA, - const glm::vec3& centerB, float radiusB ) const { - +ViewFrustum::location ViewFrustum::sphereInKeyhole(const glm::vec3& center, float radius) const { ViewFrustum::location result = INTERSECT; - float distanceFromAtoB = glm::distance(centerA, centerB); - if (distanceFromAtoB > (radiusA + radiusB)) { + float distance = glm::distance(center, _position); + if (distance > (radius + _keyholeRadius)) { result = OUTSIDE; - } else if ((distanceFromAtoB + radiusA) < radiusB) { + } else if ((distance + radius) < _keyholeRadius) { result = INSIDE; } @@ -174,9 +176,16 @@ ViewFrustum::location ViewFrustum::sphereInSphere(const glm::vec3& centerA, floa // A box is inside a sphere if all of its corners are inside the sphere // A box intersects a sphere if any of its edges (as rays) interesect the sphere // A box is outside a sphere if none of its edges (as rays) interesect the sphere -ViewFrustum::location ViewFrustum::boxInSphere(const AABox& box, const glm::vec3& center, float radius) const { +ViewFrustum::location ViewFrustum::boxInKeyhole(const AABox& box) const { + + // First check to see if the box is in the bounding box for the sphere, if it's not, then we can short circuit + // this and not check with sphere penetration which is more expensive + if (!_keyholeBoundingBox.contains(box)) { + return OUTSIDE; + } + glm::vec3 penetration; - bool intersects = box.findSpherePenetration(center, radius, penetration); + bool intersects = box.findSpherePenetration(_position, _keyholeRadius, penetration); ViewFrustum::location result = OUTSIDE; @@ -185,32 +194,18 @@ ViewFrustum::location ViewFrustum::boxInSphere(const AABox& box, const glm::vec3 result = INTERSECT; // test all the corners, if they are all inside the sphere, the entire box is in the sphere - glm::vec3 testPoint = box.getCorner(); - glm::vec3 size = box.getSize(); - if (pointInSphere(testPoint, center, radius)) { - testPoint = box.getCorner() + glm::vec3(size.x, 0.0f, 0.0f); - if (pointInSphere(testPoint, center, radius)) { - testPoint = box.getCorner() + glm::vec3(0.0f, 0.0f, size.z); - if (pointInSphere(testPoint, center, radius)) { - testPoint = box.getCorner() + glm::vec3(size.x, 0.0f, size.z); - if (pointInSphere(testPoint, center, radius)) { - testPoint = box.getCorner() + glm::vec3(0.0f, size.y, 0.0f); - if (pointInSphere(testPoint, center, radius)) { - testPoint = box.getCorner() + glm::vec3(size.x, size.y, 0.0f); - if (pointInSphere(testPoint, center, radius)) { - testPoint = box.getCorner() + glm::vec3(0.0f, size.y, size.z); - if (pointInSphere(testPoint, center, radius)) { - testPoint = box.getCorner() + glm::vec3(size.x, size.y, size.z); - if (pointInSphere(testPoint, center, radius)) { - result = INSIDE; - } - } - } - } - } - } + bool allPointsInside = true; // assume the best + for (int v = BOTTOM_LEFT_NEAR; v < TOP_LEFT_FAR; v++) { + glm::vec3 vertex = box.getVertex((BoxVertex)v); + if (!pointInKeyhole(vertex)) { + allPointsInside = false; + break; } } + + if (allPointsInside) { + result = INSIDE; + } } return result; @@ -222,7 +217,7 @@ ViewFrustum::location ViewFrustum::pointInFrustum(const glm::vec3& point) const // If we have a keyholeRadius, check that first, since it's cheaper if (_keyholeRadius >= 0.0f) { - keyholeResult = pointInSphere(point, _position, _keyholeRadius); + keyholeResult = pointInKeyhole(point); } if (keyholeResult == INSIDE) { return keyholeResult; @@ -245,7 +240,7 @@ ViewFrustum::location ViewFrustum::sphereInFrustum(const glm::vec3& center, floa // If we have a keyholeRadius, check that first, since it's cheaper if (_keyholeRadius >= 0.0f) { - keyholeResult = sphereInSphere(center, radius, _position, _keyholeRadius); + keyholeResult = sphereInKeyhole(center, radius); } if (keyholeResult == INSIDE) { return keyholeResult; @@ -272,7 +267,7 @@ ViewFrustum::location ViewFrustum::boxInFrustum(const AABox& box) const { // If we have a keyholeRadius, check that first, since it's cheaper if (_keyholeRadius >= 0.0f) { - keyholeResult = boxInSphere(box, _position, _keyholeRadius); + keyholeResult = boxInKeyhole(box); } if (keyholeResult == INSIDE) { return keyholeResult; @@ -503,7 +498,7 @@ const int hullVertexLookup[MAX_POSSIBLE_COMBINATIONS][MAX_SHADOW_VERTEX_COUNT+1] {6, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, BOTTOM_RIGHT_FAR, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, TOP_LEFT_NEAR}, // back, top, left }; -VoxelProjectedPolygon ViewFrustum::getProjectedShadow(const AABox& box) const { +VoxelProjectedPolygon ViewFrustum::getProjectedPolygon(const AABox& box) const { glm::vec3 bottomNearRight = box.getCorner(); glm::vec3 topFarLeft = box.getCorner() + box.getSize(); int lookUp = ((_position.x < bottomNearRight.x) ) // 1 = right | compute 6-bit diff --git a/libraries/voxels/src/ViewFrustum.h b/libraries/voxels/src/ViewFrustum.h index 8ad18f6246..6833eb6134 100644 --- a/libraries/voxels/src/ViewFrustum.h +++ b/libraries/voxels/src/ViewFrustum.h @@ -89,14 +89,14 @@ public: void printDebugDetails() const; glm::vec2 projectPoint(glm::vec3 point, bool& pointInView) const; - VoxelProjectedPolygon getProjectedShadow(const AABox& box) const; + VoxelProjectedPolygon getProjectedPolygon(const AABox& box) const; private: // Used for keyhole calculations - ViewFrustum::location pointInSphere(const glm::vec3& point, const glm::vec3& center, float radius) const; - ViewFrustum::location sphereInSphere(const glm::vec3& centerA, float radiusA, const glm::vec3& centerB, float radiusB) const; - ViewFrustum::location boxInSphere(const AABox& box, const glm::vec3& center, float radius) const; + ViewFrustum::location pointInKeyhole(const glm::vec3& point) const; + ViewFrustum::location sphereInKeyhole(const glm::vec3& center, float radius) const; + ViewFrustum::location boxInKeyhole(const AABox& box) const; // camera location/orientation attributes glm::vec3 _position; @@ -117,6 +117,7 @@ private: // keyhole attributes float _keyholeRadius; + AABox _keyholeBoundingBox; // Calculated values diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index ec9ae008e6..06554abba6 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1125,15 +1125,15 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp //node->printDebugDetails("upper section, params.wantOcclusionCulling... node="); AABox voxelBox = node->getAABox(); voxelBox.scale(TREE_SCALE); - VoxelProjectedPolygon* voxelShadow = new VoxelProjectedPolygon(params.viewFrustum->getProjectedShadow(voxelBox)); + VoxelProjectedPolygon* voxelPolygon = new VoxelProjectedPolygon(params.viewFrustum->getProjectedPolygon(voxelBox)); // In order to check occlusion culling, the shadow has to be "all in view" otherwise, we will ignore occlusion // culling and proceed as normal - if (voxelShadow->getAllInView()) { - //node->printDebugDetails("upper section, voxelShadow->getAllInView() node="); + if (voxelPolygon->getAllInView()) { + //node->printDebugDetails("upper section, voxelPolygon->getAllInView() node="); - CoverageMap::StorageResult result = params.map->checkMap(voxelShadow, false); - delete voxelShadow; // cleanup + CoverageMap::StorageResult result = params.map->checkMap(voxelPolygon, false); + delete voxelPolygon; // cleanup if (result == CoverageMap::OCCLUDED) { //node->printDebugDetails("upper section, non-Leaf is occluded!! node="); //args->nonLeavesOccluded++; @@ -1147,7 +1147,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp //node->printDebugDetails("upper section, shadow Not in view node="); // If this shadow wasn't "all in view" then we ignored it for occlusion culling, but // we do need to clean up memory and proceed as normal... - delete voxelShadow; + delete voxelPolygon; } } } @@ -1241,17 +1241,18 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp AABox voxelBox = childNode->getAABox(); voxelBox.scale(TREE_SCALE); - VoxelProjectedPolygon* voxelShadow = new VoxelProjectedPolygon(params.viewFrustum->getProjectedShadow(voxelBox)); + VoxelProjectedPolygon* voxelPolygon = new VoxelProjectedPolygon( + params.viewFrustum->getProjectedPolygon(voxelBox)); // In order to check occlusion culling, the shadow has to be "all in view" otherwise, we will ignore occlusion // culling and proceed as normal - if (voxelShadow->getAllInView()) { - CoverageMap::StorageResult result = params.map->checkMap(voxelShadow, true); + if (voxelPolygon->getAllInView()) { + CoverageMap::StorageResult result = params.map->checkMap(voxelPolygon, true); // In all cases where the shadow wasn't stored, we need to free our own memory. // In the case where it is stored, the CoverageMap will free memory for us later. if (result != CoverageMap::STORED) { - delete voxelShadow; + delete voxelPolygon; } // If while attempting to add this voxel's shadow, we determined it was occluded, then @@ -1260,7 +1261,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp childIsOccluded = true; } } else { - delete voxelShadow; + delete voxelPolygon; } } // wants occlusion culling & isLeaf()