optimized CoverageRegion to track _currentCoveredBounds and not test polygons in the tested ocludee is not in those covered bounds

This commit is contained in:
ZappoMan 2013-06-19 23:34:45 -07:00
parent 517ff0f3cf
commit 758fadd6a9
4 changed files with 89 additions and 27 deletions

View file

@ -13,6 +13,7 @@
int CoverageMap::_mapCount = 0;
int CoverageMap::_checkMapRootCalls = 0;
int CoverageMap::_notAllInView = 0;
bool CoverageMap::wantDebugging = false;
const BoundingBox CoverageMap::ROOT_BOUNDING_BOX = BoundingBox(glm::vec2(-2.f,-2.f), glm::vec2(4.f,4.f));
@ -84,16 +85,22 @@ void CoverageMap::erase() {
printLog("MINIMUM_POLYGON_AREA_TO_STORE=%f\n",MINIMUM_POLYGON_AREA_TO_STORE);
printLog("_mapCount=%d\n",_mapCount);
printLog("_checkMapRootCalls=%d\n",_checkMapRootCalls);
printLog("_notAllInView=%d\n",_notAllInView);
printLog("_maxPolygonsUsed=%d\n",CoverageRegion::_maxPolygonsUsed);
printLog("_totalPolygons=%d\n",CoverageRegion::_totalPolygons);
printLog("_occlusionTests=%d\n",CoverageRegion::_occlusionTests);
printLog("_regionSkips=%d\n",CoverageRegion::_regionSkips);
printLog("_tooSmallSkips=%d\n",CoverageRegion::_tooSmallSkips);
printLog("_outOfOrderPolygon=%d\n",CoverageRegion::_outOfOrderPolygon);
CoverageRegion::_maxPolygonsUsed = 0;
CoverageRegion::_totalPolygons = 0;
CoverageRegion::_occlusionTests = 0;
CoverageRegion::_regionSkips = 0;
CoverageRegion::_tooSmallSkips = 0;
CoverageRegion::_outOfOrderPolygon = 0;
_mapCount = 0;
_checkMapRootCalls = 0;
_notAllInView = 0;
}
}
@ -131,6 +138,7 @@ CoverageMapStorageResult CoverageMap::checkMap(VoxelProjectedPolygon* polygon, b
// short circuit: we don't handle polygons that aren't all in view, so, if the polygon in question is
// not in view, then we just discard it with a DOESNT_FIT, this saves us time checking values later.
if (!polygon->getAllInView()) {
_notAllInView++;
return DOESNT_FIT;
}
@ -195,6 +203,7 @@ CoverageMapStorageResult CoverageMap::checkMap(VoxelProjectedPolygon* polygon, b
storeIn->storeInArray(polygon);
return STORED;
} else {
CoverageRegion::_tooSmallSkips++;
return NOT_STORED;
}
} else {
@ -297,6 +306,8 @@ const char* CoverageRegion::getRegionName() const {
int CoverageRegion::_maxPolygonsUsed = 0;
int CoverageRegion::_totalPolygons = 0;
int CoverageRegion::_occlusionTests = 0;
int CoverageRegion::_regionSkips = 0;
int CoverageRegion::_tooSmallSkips = 0;
int CoverageRegion::_outOfOrderPolygon = 0;
// just handles storage in the array, doesn't test for occlusion or
@ -305,6 +316,8 @@ void CoverageRegion::storeInArray(VoxelProjectedPolygon* polygon) {
_totalPolygons++;
_currentCoveredBounds.explandToInclude(polygon->getBoundingBox());
if (_polygonArraySize < _polygonCount + 1) {
growPolygonArray();
}
@ -316,7 +329,7 @@ void CoverageRegion::storeInArray(VoxelProjectedPolygon* polygon) {
_polygonCount = insertIntoSortedArrays((void*)polygon, polygon->getDistance(), IGNORED,
(void**)_polygons, _polygonDistances, IGNORED,
_polygonCount, _polygonArraySize);
// Debugging and Optimization Tuning code.
if (_polygonCount > _maxPolygonsUsed) {
_maxPolygonsUsed = _polygonCount;
@ -335,37 +348,43 @@ CoverageMapStorageResult CoverageRegion::checkRegion(VoxelProjectedPolygon* poly
if (_isRoot || _myBoundingBox.contains(polygonBox)) {
result = NOT_STORED; // if we got here, then we DO fit...
// check to make sure this polygon isn't occluded by something at this level
for (int i = 0; i < _polygonCount; i++) {
VoxelProjectedPolygon* polygonAtThisLevel = _polygons[i];
// Check to make sure that the polygon in question is "behind" the polygon in the list
// otherwise, we don't need to test it's occlusion (although, it means we've potentially
// added an item previously that may be occluded??? Is that possible? Maybe not, because two
// voxels can't have the exact same outline. So one occludes the other, they can't both occlude
// each other.
// only actually check the polygons if this polygon is in the covered bounds for this region
if (!_currentCoveredBounds.contains(polygonBox)) {
_regionSkips += _polygonCount;
} else {
// check to make sure this polygon isn't occluded by something at this level
for (int i = 0; i < _polygonCount; i++) {
VoxelProjectedPolygon* polygonAtThisLevel = _polygons[i];
// Check to make sure that the polygon in question is "behind" the polygon in the list
// otherwise, we don't need to test it's occlusion (although, it means we've potentially
// added an item previously that may be occluded??? Is that possible? Maybe not, because two
// voxels can't have the exact same outline. So one occludes the other, they can't both occlude
// each other.
_occlusionTests++;
if (polygonAtThisLevel->occludes(*polygon)) {
// if the polygonAtThisLevel is actually behind the one we're inserting, then we don't
// want to report our inserted one as occluded, but we do want to add our inserted one.
if (polygonAtThisLevel->getDistance() >= polygon->getDistance()) {
_outOfOrderPolygon++;
if (storeIt) {
if (polygon->getBoundingBox().area() > CoverageMap::MINIMUM_POLYGON_AREA_TO_STORE) {
//printLog("storing polygon of area: %f\n",polygon->getBoundingBox().area());
storeInArray(polygon);
return STORED;
_occlusionTests++;
if (polygonAtThisLevel->occludes(*polygon)) {
// if the polygonAtThisLevel is actually behind the one we're inserting, then we don't
// want to report our inserted one as occluded, but we do want to add our inserted one.
if (polygonAtThisLevel->getDistance() >= polygon->getDistance()) {
_outOfOrderPolygon++;
if (storeIt) {
if (polygon->getBoundingBox().area() > CoverageMap::MINIMUM_POLYGON_AREA_TO_STORE) {
//printLog("storing polygon of area: %f\n",polygon->getBoundingBox().area());
storeInArray(polygon);
return STORED;
} else {
_tooSmallSkips++;
return NOT_STORED;
}
} else {
return NOT_STORED;
}
} else {
return NOT_STORED;
}
// this polygon is occluded by a closer polygon, so don't store it, and let the caller know
return OCCLUDED;
}
// this polygon is occluded by a closer polygon, so don't store it, and let the caller know
return OCCLUDED;
}
}
}

View file

@ -31,6 +31,8 @@ public:
static int _maxPolygonsUsed;
static int _totalPolygons;
static int _occlusionTests;
static int _regionSkips;
static int _tooSmallSkips;
static int _outOfOrderPolygon;
@ -41,6 +43,7 @@ private:
bool _isRoot; // is this map the root, if so, it never returns DOESNT_FIT
BoundingBox _myBoundingBox;
BoundingBox _currentCoveredBounds; // area in this region currently covered by some polygon
bool _managePolygons; // will the coverage map delete the polygons on destruct
RegionName _regionName;
int _polygonCount; // how many polygons at this level
@ -89,6 +92,7 @@ private:
static int _mapCount;
static int _checkMapRootCalls;
static int _notAllInView;
};

View file

@ -35,7 +35,7 @@ BoundingBox BoundingBox::rightHalf() const {
}
bool BoundingBox::contains(const BoundingBox& box) const {
return (
return ( _set &&
(box.corner.x >= corner.x) &&
(box.corner.y >= corner.y) &&
(box.corner.x + box.size.x <= corner.x + size.x) &&
@ -43,6 +43,40 @@ bool BoundingBox::contains(const BoundingBox& box) const {
);
};
void BoundingBox::explandToInclude(const BoundingBox& box) {
if (!_set) {
corner = box.corner;
size = box.size;
_set = true;
} else {
// example:
// original bounding [c:1,1 s:1,1] => [1,1]->[2,2]
// expand to include [c:0.5,0.5 s:2,2] => [0.5,0.5]->[2.5,2.5]
// new bounding [0.5,0.5]->[2.5,2.5] or [c:0.5,0.5 s:2,2]
if (box.corner.x < corner.x) {
corner.x = box.corner.x;
size.x += (corner.x - box.corner.x);
}
// new state... [c:0.5,1 s:1.5,1]
if (box.corner.y < corner.y) {
corner.y = box.corner.y;
size.y += (corner.y - box.corner.y);
}
// new state... [c:0.5,0.5 s:1.5,1.5]
if ((box.corner.x + box.size.x) > (corner.x + size.x)) {
size.x += ((box.corner.x + box.size.x) - (corner.x + size.x));
}
// new state... [c:0.5,0.5 s:2,1.5]
if ((box.corner.y + box.size.y) > (corner.y + size.y)) {
size.y += ((box.corner.y + box.size.y) - (corner.y + size.y));
}
// new state... [c:0.5,0.5 s:2,2]
}
}
void BoundingBox::printDebugDetails(const char* label) const {
if (label) {
printLog(label);

View file

@ -16,10 +16,13 @@ typedef glm::vec2 ShadowVertices[MAX_SHADOW_VERTEX_COUNT];
class BoundingBox {
public:
BoundingBox(glm::vec2 corner, glm::vec2 size) : corner(corner), size(size) {};
BoundingBox(glm::vec2 corner, glm::vec2 size) : corner(corner), size(size), _set(true) {};
BoundingBox() : _set(false) {};
glm::vec2 corner;
glm::vec2 size;
bool contains(const BoundingBox& box) const;
void explandToInclude(const BoundingBox& box);
float area() const { return size.x * size.y; };
BoundingBox topHalf() const;
@ -28,6 +31,8 @@ public:
BoundingBox rightHalf() const;
void printDebugDetails(const char* label=NULL) const;
private:
bool _set;
};
class VoxelProjectedPolygon {