Beispiel #1
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) {
                int* IGNORED_ADDRESS = NULL;
                // remove this otherOtherPolygon for our polygon array
                _polygonCount = removeFromSortedArrays((void*)seed,
                                                       (void**)_polygons, _polygonDistances, IGNORED_ADDRESS,
                                                       _polygonCount, _polygonArraySize);
                _totalPolygons--;
            }

            //qDebug("_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;
}
Beispiel #2
0
CoverageMapStorageResult CoverageRegion::checkRegion(VoxelProjectedPolygon* polygon, const BoundingBox& polygonBox, bool storeIt) {

    CoverageMapStorageResult result = DOESNT_FIT;

    if (_isRoot || _myBoundingBox.contains(polygonBox)) {
        result = NOT_STORED; // if we got here, then we DO fit...

        // 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) {
                                if (getPolygonCount() < MAX_POLYGONS_PER_REGION) {
                                    storeInArray(polygon);
                                    return STORED;
                                } else {
                                    CoverageRegion::_regionFullSkips++;
                                    return NOT_STORED;
                                }
                            } else {
                                _tooSmallSkips++;
                                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;
                }
            }
        }
    }
    return result;
}
Beispiel #3
0
// possible results = STORED/NOT_STORED, OCCLUDED, DOESNT_FIT
CoverageMap::StorageResult CoverageMap::checkMap(VoxelProjectedPolygon* polygon, bool storeIt) {
    if (_isRoot || _myBoundingBox.contains(polygon->getBoundingBox())) {
        // 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.
            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()) {
                    if (storeIt) {
                        storeInArray(polygon);
                        return 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;
            }
        }
        // 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
        for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
            BoundingBox childMapBoundingBox = getChildBoundingBox(i);
            if (childMapBoundingBox.contains(polygon->getBoundingBox())) {
                // if no child map exists yet, then create it
                if (!_childMaps[i]) {
                    _childMaps[i] = new CoverageMap(childMapBoundingBox, NOT_ROOT, _managePolygons);
                }
                return _childMaps[i]->checkMap(polygon, storeIt);
            }
        }
        // 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) {
            storeInArray(polygon);
            return STORED;
        } else {
            return NOT_STORED;
        }
    }
    return DOESNT_FIT;
}
bool VoxelProjectedPolygon::occludes(const VoxelProjectedPolygon& occludee, bool checkAllInView) const {
    
    // if we are completely out of view, then we definitely don't occlude!
    // if the occludee is completely out of view, then we also don't occlude it
    //
    // this is true, but unfortunately, we're not quite handling projects in the
    // case when SOME points are in view and others are not. So, we will not consider
    // occlusion for any shadows that are partially in view.
    if (checkAllInView && (!getAllInView() || !occludee.getAllInView())) {
        return false;
    }

    // first check the bounding boxes, the occludee must be fully within the boounding box of this shadow
    if ((occludee.getMaxX() > getMaxX()) ||
        (occludee.getMaxY() > getMaxY()) ||
        (occludee.getMinX() < getMinX()) ||
        (occludee.getMinY() < getMinY())) {
        return false;
    }
    
    // if we got this far, then check each vertex of the occludee, if all those points
    // are inside our polygon, then the tested occludee is fully occluded
    for(int i = 0; i < occludee.getVertexCount(); i++) {
        if (!pointInside(occludee.getVertex(i))) {
            return false;
        }
    }
    
    // if we got this far, then indeed the occludee is fully occluded by us
    return true;
}