good progress on merging polygons

This commit is contained in:
ZappoMan 2013-07-01 21:39:56 -07:00
parent f764a8d609
commit 015ff85cea
8 changed files with 890 additions and 24 deletions

View file

@ -2475,6 +2475,30 @@ void Application::renderCoverageMapsRecursively(CoverageMap* map) {
for (int i = 0; i < map->getPolygonCount(); i++) {
VoxelProjectedPolygon* polygon = map->getPolygon(i);
if (polygon->getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM)) {
glColor3f(.5,0,0); // dark red
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT | PROJECTION_TOP)) {
glColor3f(0,.5,0); // dark green
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT)) {
glColor3f(.5,.5,0); // dark yellow
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT)) {
glColor3f(.5,.5,.5); // gray
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT | PROJECTION_TOP)) {
glColor3f(0,0,1); // Blue
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT | PROJECTION_BOTTOM)) {
glColor3f(.5,0,.5); // dark magenta
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM)) {
glColor3f(1,0,0); // red
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP)) {
glColor3f(1,0,1); // magenta
} else if (polygon->getProjectionType() == (PROJECTION_NEAR)) {
glColor3f(1,1,0); // yellow
} else if (polygon->getProjectionType() == (PROJECTION_FAR | PROJECTION_RIGHT | PROJECTION_BOTTOM)) {
glColor3f(0,.5,.5); // dark cyan
} else {
glColor3f(0,0,1);
}
glm::vec2 firstPoint = getScaledScreenPoint(polygon->getVertex(0));
glm::vec2 lastPoint(firstPoint);

View file

@ -440,3 +440,25 @@ int insertIntoSortedArrays(void* value, float key, int originalIndex,
return -1; // error case
}
int removeFromSortedArrays(void* value, void** valueArray, float* keyArray, int* originalIndexArray,
int currentCount, int maxCount) {
int i = 0;
if (currentCount > 0) {
while (i < currentCount && value != valueArray[i]) {
i++;
}
if (value == valueArray[i] && i < currentCount) {
// i is the location of the item we were looking for
// shift array elements to the left
memmove(&valueArray[i], &valueArray[i + 1], sizeof(void*) * ((currentCount-1) - i));
memmove(&keyArray[i], &keyArray[i + 1], sizeof(float) * ((currentCount-1) - i));
if (originalIndexArray) {
memmove(&originalIndexArray[i], &originalIndexArray[i + 1], sizeof(int) * ((currentCount-1) - i));
}
return currentCount-1;
}
}
return -1; // error case
}

View file

@ -88,6 +88,11 @@ int insertIntoSortedArrays(void* value, float key, int originalIndex,
void** valueArray, float* keyArray, int* originalIndexArray,
int currentCount, int maxCount);
int removeFromSortedArrays(void* value, void** valueArray, float* keyArray, int* originalIndexArray,
int currentCount, int maxCount);
// Helper Class for debugging
class debug {
public:

View file

@ -196,6 +196,7 @@ CoverageMapStorageResult CoverageMap::checkMap(VoxelProjectedPolygon* polygon, b
bool fitsInAHalf = false;
// Check each half of the box independently
/**
if (_topHalf.contains(polygonBox)) {
result = _topHalf.checkRegion(polygon, polygonBox, storeIt);
storeIn = &_topHalf;
@ -213,6 +214,7 @@ CoverageMapStorageResult CoverageMap::checkMap(VoxelProjectedPolygon* polygon, b
storeIn = &_rightHalf;
fitsInAHalf = true;
}
**/
// if we got this far, there are one of two possibilities, either a polygon doesn't fit
// in one of the halves, or it did fit, but it wasn't occluded by anything only in that
@ -239,6 +241,7 @@ CoverageMapStorageResult CoverageMap::checkMap(VoxelProjectedPolygon* polygon, b
// if we made it here, then it means the polygon being stored is not occluded
// at this level of the quad tree, so we can continue to insert it into the map.
// First we check to see if it fits in any of our sub maps
if (false) {
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
BoundingBox childMapBoundingBox = getChildBoundingBox(i);
if (childMapBoundingBox.contains(polygon->getBoundingBox())) {
@ -268,6 +271,7 @@ CoverageMapStorageResult CoverageMap::checkMap(VoxelProjectedPolygon* polygon, b
return result;
}
}
}
// if we got this far, then the polygon is in our bounding box, but doesn't fit in
// any of our child bounding boxes, so we should add it here.
if (storeIt) {
@ -397,13 +401,53 @@ int CoverageRegion::_tooSmallSkips = 0;
int CoverageRegion::_outOfOrderPolygon = 0;
int CoverageRegion::_clippedPolygons = 0;
bool CoverageRegion::mergeItemsInArray(VoxelProjectedPolygon* seed, bool seedInArray) {
for (int i = 0; i < _polygonCount; i++) {
VoxelProjectedPolygon* otherPolygon = _polygons[i];
if (otherPolygon->canMerge(*seed)) {
otherPolygon->merge(*seed);
if (seedInArray) {
const int IGNORED = NULL;
// remove this otherOtherPolygon for our polygon array
_polygonCount = removeFromSortedArrays((void*)seed,
(void**)_polygons, _polygonDistances, IGNORED,
_polygonCount, _polygonArraySize);
_totalPolygons--;
}
//printLog("_polygonCount=%d\n",_polygonCount);
// clean up
if (_managePolygons) {
delete seed;
}
// Now run again using our newly merged polygon as the seed
mergeItemsInArray(otherPolygon, true);
return true;
}
}
return false;
}
// just handles storage in the array, doesn't test for occlusion or
// determining if this is the correct map to store in!
void CoverageRegion::storeInArray(VoxelProjectedPolygon* polygon) {
_totalPolygons++;
_currentCoveredBounds.explandToInclude(polygon->getBoundingBox());
// Before we actually store this polygon in the array, check to see if this polygon can be merged to any of the existing
// polygons already in our array.
if (mergeItemsInArray(polygon, false)) {
return; // exit early
}
// only after we attempt to merge!
_totalPolygons++;
if (_polygonArraySize < _polygonCount + 1) {
growPolygonArray();
@ -414,11 +458,11 @@ void CoverageRegion::storeInArray(VoxelProjectedPolygon* polygon) {
// in the list. We still check to see if the polygon is "in front" of the target polygon before we test occlusion. Since
// sometimes things come out of order.
const bool SORT_BY_SIZE = false;
const int IGNORED = NULL;
if (SORT_BY_SIZE) {
// This old code assumes that polygons will always be added in z-buffer order, but that doesn't seem to
// be a good assumption. So instead, we will need to sort this by distance. Use a binary search to find the
// insertion point in this array, and shift the array accordingly
const int IGNORED = NULL;
float area = polygon->getBoundingBox().area();
float reverseArea = 4.0f - area;
//printLog("store by size area=%f reverse area=%f\n", area, reverseArea);
@ -458,13 +502,13 @@ CoverageMapStorageResult CoverageRegion::checkRegion(VoxelProjectedPolygon* poly
// 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

View file

@ -59,6 +59,9 @@ private:
float* _polygonSizes;
void growPolygonArray();
static const int DEFAULT_GROW_SIZE = 100;
bool mergeItemsInArray(VoxelProjectedPolygon* seed, bool seedInArray);
};
class CoverageMap {

View file

@ -461,7 +461,7 @@ const int hullVertexLookup[MAX_POSSIBLE_COMBINATIONS][MAX_PROJECTED_POLYGON_VERT
//0
{0}, // inside
{4, BOTTOM_RIGHT_NEAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_RIGHT_NEAR}, // right
{4, BOTTOM_LEFT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR, BOTTOM_LEFT_FAR }, // left
{4, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR }, // left
{0}, // n/a
//4
@ -480,20 +480,25 @@ const int hullVertexLookup[MAX_POSSIBLE_COMBINATIONS][MAX_PROJECTED_POLYGON_VERT
{0}, // n/a
{0}, // n/a
//16
{4, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR, BOTTOM_LEFT_NEAR}, // front or near
{6, BOTTOM_RIGHT_NEAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR, BOTTOM_LEFT_NEAR}, // front, right
{6, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR}, // front, left
{4, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR }, // front or near
{6, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR }, // front, right
{6, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR, }, // front, left
{0}, // n/a
//20
{6, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR, BOTTOM_LEFT_NEAR, BOTTOM_LEFT_FAR, BOTTOM_RIGHT_FAR }, // front,bottom
{6, BOTTOM_LEFT_NEAR, BOTTOM_LEFT_FAR, BOTTOM_RIGHT_FAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR }, // front,bottom
//21
{6, BOTTOM_LEFT_NEAR, BOTTOM_LEFT_FAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR }, //front,bottom,right
//22
{6, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR, BOTTOM_LEFT_FAR, BOTTOM_RIGHT_FAR }, //front,bottom,left
{6, BOTTOM_LEFT_FAR, BOTTOM_RIGHT_FAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR }, //front,bottom,left
{0}, // n/a
{6, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, TOP_LEFT_FAR, TOP_LEFT_NEAR, BOTTOM_LEFT_NEAR}, // front, top
{6, BOTTOM_RIGHT_NEAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_LEFT_FAR, TOP_LEFT_NEAR, BOTTOM_LEFT_NEAR}, // front, top, right
{6, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, TOP_LEFT_FAR, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR}, // front, top, left
{6, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, TOP_LEFT_FAR, TOP_LEFT_NEAR}, // front, top
{6, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_LEFT_FAR, TOP_LEFT_NEAR }, // front, top, right
{6, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, TOP_LEFT_FAR }, // front, top, left
{0}, // n/a
{0}, // n/a
{0}, // n/a
@ -553,7 +558,7 @@ VoxelProjectedPolygon ViewFrustum::getProjectedPolygon(const AABox& box) const {
projectedPolygon.setVertex(i, projectedPoint);
}
/***/
/***
// Now that we've got the polygon, if it extends beyond the clipping window, then let's clip it
// NOTE: This clipping does not improve our overall performance. It basically causes more polygons to
// end up in the same quad/half and so the polygon lists get longer, and that's more calls to polygon.occludes()
@ -574,6 +579,8 @@ VoxelProjectedPolygon ViewFrustum::getProjectedPolygon(const AABox& box) const {
projectedPolygon.setVertex(i, clippedVertices[i]);
}
delete[] clippedVertices;
lookUp += PROJECTION_CLIPPED;
}
/***/
}
@ -582,5 +589,6 @@ VoxelProjectedPolygon ViewFrustum::getProjectedPolygon(const AABox& box) const {
projectedPolygon.setDistance(distance);
projectedPolygon.setAnyInView(anyPointsInView);
projectedPolygon.setAllInView(allPointsInView);
projectedPolygon.setProjectionType(lookUp); // remember the projection type
return projectedPolygon;
}

View file

@ -369,4 +369,751 @@ bool VoxelProjectedPolygon::intersectsOnAxes(const VoxelProjectedPolygon& testee
return true;
}
bool VoxelProjectedPolygon::canMerge(const VoxelProjectedPolygon& that) const {
// RIGHT/NEAR
// LEFT/NEAR
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)
)
) {
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(5)) {
return true;
}
if (getVertex(0) == that.getVertex(1) && getVertex(5) == that.getVertex(4)) {
return true;
}
if (getVertex(2) == that.getVertex(1) && getVertex(3) == that.getVertex(4)) {
return true;
}
if (getVertex(1) == that.getVertex(2) && getVertex(4) == that.getVertex(3)) {
return true;
}
}
// NEAR/BOTTOM
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM)
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(3) == that.getVertex(4)) {
return true;
}
if (getVertex(5) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
return true;
}
if (getVertex(1) == that.getVertex(0) && getVertex(2) == that.getVertex(3)) {
return true;
}
if (getVertex(0) == that.getVertex(1) && getVertex(3) == that.getVertex(2)) {
return true;
}
}
// NEAR/TOP
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP)
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(1) == that.getVertex(2)) {
return true;
}
if (getVertex(5) == that.getVertex(0) && getVertex(2) == that.getVertex(1)) {
return true;
}
if (getVertex(4) == that.getVertex(5) && getVertex(3) == that.getVertex(2)) {
return true;
}
if (getVertex(5) == that.getVertex(4) && getVertex(2) == that.getVertex(3)) {
return true;
}
}
// RIGHT/NEAR & NEAR/RIGHT/TOP
// LEFT/NEAR & NEAR/LEFT/TOP
if (
((getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
return true;
}
}
// RIGHT/NEAR & NEAR/RIGHT/TOP
// LEFT/NEAR & NEAR/LEFT/TOP
if (
((that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
return true;
}
}
// RIGHT/NEAR & NEAR/RIGHT/BOTTOM
// NEAR/LEFT & NEAR/LEFT/BOTTOM
if (
((that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
return true;
}
}
// RIGHT/NEAR & NEAR/RIGHT/BOTTOM
// NEAR/LEFT & NEAR/LEFT/BOTTOM
if (
((getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
return true;
}
}
// NEAR/TOP & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP ))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(1) == that.getVertex(2)) {
return true;
}
}
// NEAR/TOP & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP ))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(2) == that.getVertex(1)) {
return true;
}
}
// NEAR/BOTTOM & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM ))
)
{
if (getVertex(2) == that.getVertex(3) && getVertex(3) == that.getVertex(0)) {
return true;
}
}
// NEAR/BOTTOM & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM ))
)
{
if (getVertex(3) == that.getVertex(2) && getVertex(0) == that.getVertex(3)) {
return true;
}
}
// NEAR/RIGHT & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(0) == that.getVertex(1) && getVertex(3) == that.getVertex(4)) {
return true;
}
}
// NEAR/RIGHT & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
return true;
}
}
// NEAR/LEFT & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT ))
)
{
if (getVertex(1) == that.getVertex(1) && getVertex(2) == that.getVertex(4)) {
return true;
}
}
// NEAR/LEFT & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT ))
)
{
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
return true;
}
}
// NEAR/RIGHT/BOTTOM & NEAR/BOTTOM
if (
(getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(1) == that.getVertex(2) && getVertex(5) == that.getVertex(4)) {
return true;
}
}
// NEAR/RIGHT/BOTTOM & NEAR/BOTTOM
if (
(that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(2) == that.getVertex(1) && getVertex(4) == that.getVertex(5)) {
return true;
}
}
// RIGHT/NEAR/BOTTOM
// RIGHT/NEAR/TOP
// LEFT/NEAR/BOTTOM
// LEFT/NEAR/TOP
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM ) ||
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP ) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM ) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP )
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
return true;
}
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
return true;
}
if (getVertex(2) == that.getVertex(1) && getVertex(4) == that.getVertex(5)) {
return true;
}
if (getVertex(1) == that.getVertex(2) && getVertex(5) == that.getVertex(4)) {
return true;
}
if (getVertex(1) == that.getVertex(0) && getVertex(3) == that.getVertex(4)) {
return true;
}
if (getVertex(0) == that.getVertex(1) && getVertex(4) == that.getVertex(3)) {
return true;
}
}
return false;
}
void VoxelProjectedPolygon::merge(const VoxelProjectedPolygon& that) {
// RIGHT/NEAR
// LEFT/NEAR
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)
)
) {
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(5)) {
//setVertex(0, this.getVertex(0)); // no change
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
//setVertex(5, this.getVertex(5)); // no change
return; // done
}
if (getVertex(0) == that.getVertex(1) && getVertex(5) == that.getVertex(4)) {
setVertex(0, that.getVertex(0));
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, that.getVertex(4)); // no change
setVertex(5, that.getVertex(5));
return; // done
}
if (getVertex(2) == that.getVertex(1) && getVertex(3) == that.getVertex(4)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, that.getVertex(5)); // no change
return; // done
}
if (getVertex(1) == that.getVertex(2) && getVertex(4) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, that.getVertex(3)); // no change
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
}
// NEAR/BOTTOM
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM)
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(3) == that.getVertex(4)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, that.getVertex(5)); // no change
return; // done
}
if (getVertex(5) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, that.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, that.getVertex(3)); // no change
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
if (getVertex(1) == that.getVertex(0) && getVertex(2) == that.getVertex(3)) {
//setVertex(0, this.getVertex(0)); // no change
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
//setVertex(3, that.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, that.getVertex(5)); // no change
return; // done
}
if (getVertex(0) == that.getVertex(1) && getVertex(3) == that.getVertex(2)) {
setVertex(0, that.getVertex(0));
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, that.getVertex(2)); // no change
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
}
// NEAR/TOP
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP)
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(1) == that.getVertex(2)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, that.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, that.getVertex(5)); // no change
return; // done
}
if (getVertex(5) == that.getVertex(0) && getVertex(2) == that.getVertex(1)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, that.getVertex(1)); // no change
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
if (getVertex(4) == that.getVertex(5) && getVertex(3) == that.getVertex(2)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, that.getVertex(1)); // no change
//setVertex(2, that.getVertex(2)); // no change
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
//setVertex(5, that.getVertex(5)); // no change
return; // done
}
if (getVertex(5) == that.getVertex(4) && getVertex(2) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, that.getVertex(3)); // no change
setVertex(5, that.getVertex(5));
return; // done
}
}
// RIGHT/NEAR & NEAR/RIGHT/TOP
// LEFT/NEAR & NEAR/LEFT/TOP
if (
((getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
setProjectionType((PROJECTION_RIGHT | PROJECTION_NEAR));
return; // done
}
}
// RIGHT/NEAR & NEAR/RIGHT/TOP
// LEFT/NEAR & NEAR/LEFT/TOP
if (
((that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, this.getVertex(5)); // no change
//setProjectionType((PROJECTION_RIGHT | PROJECTION_NEAR)); // no change
return; // done
}
}
// RIGHT/NEAR & NEAR/RIGHT/BOTTOM
// NEAR/LEFT & NEAR/LEFT/BOTTOM
if (
((that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
//setProjectionType((PROJECTION_RIGHT | PROJECTION_NEAR)); // no change
return; // done
}
}
// RIGHT/NEAR & NEAR/RIGHT/BOTTOM
// NEAR/LEFT & NEAR/LEFT/BOTTOM
if (
((getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, this.getVertex(5)); // no change
setProjectionType((PROJECTION_RIGHT | PROJECTION_NEAR));
return; // done
}
}
// NEAR/TOP & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP ))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(1) == that.getVertex(2)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, this.getVertex(3)); // no change
//setVertexCount(4); // no change
//setProjectionType((PROJECTION_NEAR)); // no change
return; // done
}
}
// NEAR/TOP & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP ))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(2) == that.getVertex(1)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
setVertexCount(4);
setProjectionType((PROJECTION_NEAR));
return; // done
}
}
// NEAR/BOTTOM & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM ))
)
{
if (getVertex(2) == that.getVertex(3) && getVertex(3) == that.getVertex(0)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
setVertex(2, that.getVertex(4));
setVertex(3, that.getVertex(5));
//setVertexCount(4); // no change
//setProjectionType((PROJECTION_NEAR)); // no change
}
}
// NEAR/BOTTOM & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM ))
)
{
if (getVertex(3) == that.getVertex(2) && getVertex(0) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, getVertex(4));
setVertex(3, getVertex(5));
setVertexCount(4);
setProjectionType((PROJECTION_NEAR));
return; // done
}
}
// NEAR/RIGHT & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(0) == that.getVertex(1) && getVertex(3) == that.getVertex(4)) {
setVertex(0, that.getVertex(0));
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
setVertex(3, that.getVertex(5));
//setVertexCount(4); // no change
//setProjectionType((PROJECTION_NEAR)); // no change
}
}
// NEAR/RIGHT & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
//setVertex(0, this.getVertex(0)); // no change
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
setVertex(3, getVertex(5));
setVertexCount(4);
setProjectionType((PROJECTION_NEAR));
return; // done
}
}
// NEAR/LEFT & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT ))
)
{
if (getVertex(1) == that.getVertex(1) && getVertex(2) == that.getVertex(4)) {
//setVertex(0, this.getVertex()); // no change
setVertex(1, that.getVertex(2));
setVertex(2, that.getVertex(3));
//setVertex(3, this.getVertex(3)); // no change
//setVertexCount(4); // no change
//setProjectionType((PROJECTION_NEAR)); // no change
return; // done
}
}
// NEAR/LEFT & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT ))
)
{
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, getVertex(2));
setVertex(2, getVertex(3));
setVertex(3, that.getVertex(3));
setVertexCount(4);
setProjectionType((PROJECTION_NEAR));
return; // done
}
}
// NEAR/RIGHT/BOTTOM & NEAR/BOTTOM
if (
(getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(1) == that.getVertex(2) && getVertex(5) == that.getVertex(4)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
setVertex(5, that.getVertex(5));
return; // done
}
}
// NEAR/RIGHT/BOTTOM & NEAR/BOTTOM
if (
(that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(2) == that.getVertex(1) && getVertex(4) == that.getVertex(5)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
//setVertex(5, this.getVertex(5)); // no change
setProjectionType((PROJECTION_BOTTOM | PROJECTION_NEAR));
return; // done
}
}
// RIGHT/NEAR/BOTTOM
// RIGHT/NEAR/TOP
// LEFT/NEAR/BOTTOM
// LEFT/NEAR/TOP
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM ) ||
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP ) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM ) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP )
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, this.getVertex(5)); // no change
return; // done
}
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
if (getVertex(2) == that.getVertex(1) && getVertex(4) == that.getVertex(5)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
//setVertex(5, this.getVertex(5)); // no change
return; // done
}
if (getVertex(1) == that.getVertex(2) && getVertex(5) == that.getVertex(4)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
setVertex(5, that.getVertex(5));
return; // done
}
// if this.([1],[3]) == that.([0],[4]) then create polygon: this.[0], that.[1], that.[2], that.[3], this.[4], this.[5]
if (getVertex(1) == that.getVertex(0) && getVertex(3) == that.getVertex(4)) {
//setVertex(0, this.getVertex(0)); // no change
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, this.getVertex(5)); // no change
return; // done
}
// if this.([0],[4]) == that.([1],[3]) then create polygon: that.[0], this.[1], this.[2], this.[3], that.[4], that.[5]
if (getVertex(0) == that.getVertex(1) && getVertex(4) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, this.getVertex(3)); // no change
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
}
}

View file

@ -49,6 +49,14 @@ private:
bool _set;
};
const int PROJECTION_RIGHT = 1;
const int PROJECTION_LEFT = 2;
const int PROJECTION_BOTTOM = 4;
const int PROJECTION_TOP = 8;
const int PROJECTION_NEAR = 16;
const int PROJECTION_FAR = 32;
const int PROJECTION_CLIPPED = 64;
class VoxelProjectedPolygon {
public:
@ -64,16 +72,18 @@ public:
const ProjectedVertices& getVertices() const { return _vertices; };
const glm::vec2& getVertex(int i) const { return _vertices[i]; };
void setVertex(int vertex, const glm::vec2& point);
int getVertexCount() const { return _vertexCount; };
void setVertexCount(int vertexCount) { _vertexCount = vertexCount; };
float getDistance() const { return _distance; }
void setDistance(float distance) { _distance = distance; }
int getVertexCount() const { return _vertexCount; };
void setVertexCount(int vertexCount) { _vertexCount = vertexCount; };
float getDistance() const { return _distance; }
void setDistance(float distance) { _distance = distance; }
bool getAnyInView() const { return _anyInView; };
void setAnyInView(bool anyInView) { _anyInView = anyInView; };
bool getAllInView() const { return _allInView; };
void setAllInView(bool allInView) { _allInView = allInView; };
void setProjectionType(unsigned char type) { _projectionType = type; };
unsigned char getProjectionType() const { return _projectionType; };
bool getAnyInView() const { return _anyInView; };
void setAnyInView(bool anyInView) { _anyInView = anyInView; };
bool getAllInView() const { return _allInView; };
void setAllInView(bool allInView) { _allInView = allInView; };
bool pointInside(const glm::vec2& point, bool* matchesVertex = NULL) const;
bool occludes(const VoxelProjectedPolygon& occludee, bool checkAllInView = false) const;
@ -82,8 +92,10 @@ public:
bool intersects(const BoundingBox& box) const;
bool matches(const VoxelProjectedPolygon& testee) const;
bool matches(const BoundingBox& testee) const;
bool intersectsOnAxes(const VoxelProjectedPolygon& testee) const;
bool canMerge(const VoxelProjectedPolygon& that) const;
void merge(const VoxelProjectedPolygon& that); // replaces vertices of this with new merged version
float getMaxX() const { return _maxX; }
float getMaxY() const { return _maxY; }
@ -109,6 +121,7 @@ private:
float _distance;
bool _anyInView; // if any points are in view
bool _allInView; // if all points are in view
unsigned char _projectionType;
};