mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 19:13:38 +02:00
latest cut at occlusion culling
This commit is contained in:
parent
b3ef9868e3
commit
e2d22a8e21
9 changed files with 115 additions and 8 deletions
|
@ -60,6 +60,8 @@
|
|||
#include "renderer/ProgramObject.h"
|
||||
#include "ui/TextRenderer.h"
|
||||
|
||||
#include <CoverageMap.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const bool TESTING_AVATAR_TOUCH = false;
|
||||
|
@ -965,7 +967,6 @@ void Application::doFalseColorizeInView() {
|
|||
}
|
||||
|
||||
void Application::doFalseColorizeOccluded() {
|
||||
_debugShowVirtualOccluders->setChecked(true);
|
||||
_voxels.falseColorizeOccluded();
|
||||
}
|
||||
|
||||
|
@ -1912,6 +1913,9 @@ glm::vec2 Application::getScreenPoint(glm::vec3 voxelPoint) {
|
|||
void Application::renderVirtualOccluders() {
|
||||
|
||||
if (_debugShowVirtualOccluders->isChecked()) {
|
||||
CoverageMap map(BoundingBox(glm::vec2(-1.f,-1.f), glm::vec2(2.f,2.f))); // screen coverage
|
||||
|
||||
|
||||
glLineWidth(2.0);
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(0,0,1);
|
||||
|
@ -1919,11 +1923,16 @@ void Application::renderVirtualOccluders() {
|
|||
AABox boxA(glm::vec3(0,0,0), 0.0125);
|
||||
boxA.scale(TREE_SCALE);
|
||||
VoxelProjectedShadow shadowA = _viewFrustum.getProjectedShadow(boxA);
|
||||
|
||||
|
||||
AABox boxB(glm::vec3(0.0125,0,0.025), 0.0125);
|
||||
boxB.scale(TREE_SCALE);
|
||||
VoxelProjectedShadow shadowB = _viewFrustum.getProjectedShadow(boxB);
|
||||
|
||||
//CoverageMap::StorageResult result;
|
||||
//result = map.storeInMap(&shadowB); // test this first since it's closer in Z-buffer
|
||||
//result = map.storeInMap(&shadowA);
|
||||
|
||||
bool shadowAoccludesB = shadowA.occludes(shadowB);
|
||||
bool shadowBoccludesA = shadowB.occludes(shadowA);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "Application.h"
|
||||
#include "Log.h"
|
||||
#include "VoxelConstants.h"
|
||||
#include "CoverageMap.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "renderer/ProgramObject.h"
|
||||
|
||||
|
@ -1159,9 +1160,10 @@ void VoxelSystem::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* dest
|
|||
struct FalseColorizeOccludedArgs {
|
||||
VoxelProjectedShadow occluder;
|
||||
ViewFrustum* viewFrustum;
|
||||
CoverageMap* map;
|
||||
};
|
||||
|
||||
bool VoxelSystem::falseColorizeOccludedOperation(VoxelNode* node, void* extraData) {
|
||||
bool VoxelSystem::falseColorizeTestOccludedOperation(VoxelNode* node, void* extraData) {
|
||||
FalseColorizeOccludedArgs* args = (FalseColorizeOccludedArgs*) extraData;
|
||||
if (node->isColored()) {
|
||||
AABox voxelBox = node->getAABox();
|
||||
|
@ -1174,7 +1176,7 @@ bool VoxelSystem::falseColorizeOccludedOperation(VoxelNode* node, void* extraDat
|
|||
return true; // keep going!
|
||||
}
|
||||
|
||||
void VoxelSystem::falseColorizeOccluded() {
|
||||
void VoxelSystem::falseColorizeTestOccluded() {
|
||||
FalseColorizeOccludedArgs args;
|
||||
args.viewFrustum = Application::getInstance()->getViewFrustum();
|
||||
|
||||
|
@ -1182,7 +1184,36 @@ void VoxelSystem::falseColorizeOccluded() {
|
|||
box.scale(TREE_SCALE);
|
||||
args.occluder = args.viewFrustum->getProjectedShadow(box);
|
||||
|
||||
_tree->recurseTreeWithOperation(falseColorizeOccludedOperation,(void*)&args);
|
||||
_tree->recurseTreeWithOperation(falseColorizeTestOccludedOperation,(void*)&args);
|
||||
setupNewVoxelsForDrawing();
|
||||
}
|
||||
|
||||
bool VoxelSystem::falseColorizeOccludedOperation(VoxelNode* node, void* extraData) {
|
||||
FalseColorizeOccludedArgs* args = (FalseColorizeOccludedArgs*) extraData;
|
||||
if (node->isColored() && node->isLeaf()) {
|
||||
AABox voxelBox = node->getAABox();
|
||||
voxelBox.scale(TREE_SCALE);
|
||||
VoxelProjectedShadow* voxelShadow = new VoxelProjectedShadow(args->viewFrustum->getProjectedShadow(voxelBox));
|
||||
CoverageMap::StorageResult result = args->map->storeInMap(voxelShadow);
|
||||
if (result == CoverageMap::OCCLUDED) {
|
||||
node->setFalseColor(255, 0, 0);
|
||||
}
|
||||
}
|
||||
return true; // keep going!
|
||||
}
|
||||
|
||||
void VoxelSystem::falseColorizeOccluded() {
|
||||
CoverageMap map(BoundingBox(glm::vec2(-1.f,-1.f), glm::vec2(2.f,2.f)), true);
|
||||
FalseColorizeOccludedArgs args;
|
||||
args.viewFrustum = Application::getInstance()->getViewFrustum();
|
||||
args.map = ↦
|
||||
|
||||
AABox box(glm::vec3(0.0125,0,0.025), 0.0125);
|
||||
box.scale(TREE_SCALE);
|
||||
args.occluder = args.viewFrustum->getProjectedShadow(box);
|
||||
|
||||
_tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedOperation,
|
||||
args.viewFrustum->getPosition(), (void*)&args);
|
||||
setupNewVoxelsForDrawing();
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
void falseColorizeDistanceFromView(ViewFrustum* viewFrustum);
|
||||
void falseColorizeRandomEveryOther();
|
||||
void falseColorizeOccluded();
|
||||
void falseColorizeTestOccluded();
|
||||
|
||||
void killLocalVoxels();
|
||||
void setRenderPipelineWarnings(bool on) { _renderWarningsOn = on; };
|
||||
|
@ -122,6 +123,7 @@ private:
|
|||
static bool falseColorizeRandomEveryOtherOperation(VoxelNode* node, void* extraData);
|
||||
static bool collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* extraData);
|
||||
static bool falseColorizeOccludedOperation(VoxelNode* node, void* extraData);
|
||||
static bool falseColorizeTestOccludedOperation(VoxelNode* node, void* extraData);
|
||||
|
||||
int updateNodeInArraysAsFullVBO(VoxelNode* node);
|
||||
int updateNodeInArraysAsPartialVBO(VoxelNode* node);
|
||||
|
|
|
@ -9,6 +9,11 @@
|
|||
#include <string>
|
||||
|
||||
CoverageMap::~CoverageMap() {
|
||||
if (_managePolygons) {
|
||||
for (int i = 0; i < _polygonCount; i++) {
|
||||
delete _polygons[i];
|
||||
}
|
||||
}
|
||||
if (_polygons) {
|
||||
delete[] _polygons;
|
||||
}
|
||||
|
@ -111,7 +116,7 @@ CoverageMap::StorageResult CoverageMap::storeInMap(VoxelProjectedShadow* polygon
|
|||
if (childMapBoundingBox.contains(polygon->getBoundingBox())) {
|
||||
// if no child map exists yet, then create it
|
||||
if (!_childMaps[i]) {
|
||||
_childMaps[i] = new CoverageMap(childMapBoundingBox);
|
||||
_childMaps[i] = new CoverageMap(childMapBoundingBox, _managePolygons);
|
||||
}
|
||||
return _childMaps[i]->storeInMap(polygon);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,8 @@ class CoverageMap {
|
|||
public:
|
||||
static const int NUMBER_OF_CHILDREN = 4;
|
||||
|
||||
CoverageMap(BoundingBox boundingBox) : _myBoundingBox(boundingBox) { init(); };
|
||||
CoverageMap(BoundingBox boundingBox, bool managePolygons = false) :
|
||||
_myBoundingBox(boundingBox), _managePolygons(managePolygons) { init(); };
|
||||
~CoverageMap();
|
||||
|
||||
typedef enum {STORED, OCCLUDED, DOESNT_FIT} StorageResult;
|
||||
|
@ -60,6 +61,7 @@ private:
|
|||
void storeInArray(VoxelProjectedShadow* polygon);
|
||||
|
||||
BoundingBox _myBoundingBox;
|
||||
bool _managePolygons; // will the coverage map delete the polygons on destruct
|
||||
int _polygonCount; // how many polygons at this level
|
||||
int _polygonArraySize; // how much room is there to store polygons at this level
|
||||
VoxelProjectedShadow** _polygons;
|
||||
|
|
|
@ -18,6 +18,7 @@ bool BoundingBox::contains(const BoundingBox& box) const {
|
|||
);
|
||||
};
|
||||
|
||||
|
||||
void VoxelProjectedShadow::setVertex(int vertex, const glm::vec2& point) {
|
||||
_vertices[vertex] = point;
|
||||
|
||||
|
@ -92,4 +93,14 @@ bool VoxelProjectedShadow::pointInside(const glm::vec2& point) const {
|
|||
return ((intersections & 1) == 1);
|
||||
}
|
||||
|
||||
void VoxelProjectedShadow::printDebugDetails() const {
|
||||
printf("VoxelProjectedShadow...");
|
||||
printf(" minX=%f maxX=%f minY=%f maxY=%f\n", getMinX(), getMaxX(), getMinY(), getMaxY());
|
||||
printf(" vertex count=%d \n", getVertexCount());
|
||||
for (int i = 0; i < getVertexCount(); i++) {
|
||||
glm::vec2 point = getVertex(i);
|
||||
printf(" vertex[%d] = %f, %f \n", i, point.x, point.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ public:
|
|||
class VoxelProjectedShadow {
|
||||
|
||||
public:
|
||||
|
||||
VoxelProjectedShadow(int vertexCount = 0) :
|
||||
_vertexCount(vertexCount), _maxX(-FLT_MAX), _maxY(-FLT_MAX), _minX(FLT_MAX), _minY(FLT_MAX)
|
||||
{ };
|
||||
|
@ -49,6 +48,8 @@ public:
|
|||
return BoundingBox(glm::vec2(_minX,_minY), glm::vec2(_maxX - _minX, _maxY - _minY));
|
||||
};
|
||||
|
||||
void printDebugDetails() const;
|
||||
|
||||
private:
|
||||
int _vertexCount;
|
||||
ShadowVertices _vertices;
|
||||
|
|
|
@ -68,7 +68,48 @@ void VoxelTree::recurseNodeWithOperation(VoxelNode* node,RecurseVoxelTreeOperati
|
|||
}
|
||||
}
|
||||
|
||||
VoxelNode * VoxelTree::nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode) const {
|
||||
// Recurses voxel tree calling the RecurseVoxelTreeOperation function for each node.
|
||||
// stops recursion if operation function returns false.
|
||||
void VoxelTree::recurseTreeWithOperationDistanceSorted(RecurseVoxelTreeOperation operation,
|
||||
const glm::vec3& point, void* extraData) {
|
||||
recurseNodeWithOperationDistanceSorted(rootNode, operation, point, extraData);
|
||||
}
|
||||
|
||||
// Recurses voxel node with an operation function
|
||||
void VoxelTree::recurseNodeWithOperationDistanceSorted(VoxelNode* node, RecurseVoxelTreeOperation operation,
|
||||
const glm::vec3& point, void* extraData) {
|
||||
if (operation(node, extraData)) {
|
||||
// determine the distance sorted order of our children
|
||||
|
||||
VoxelNode* sortedChildren[NUMBER_OF_CHILDREN];
|
||||
float distancesToChildren[NUMBER_OF_CHILDREN];
|
||||
int indexOfChildren[NUMBER_OF_CHILDREN]; // not really needed
|
||||
int currentCount = 0;
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
VoxelNode* childNode = node->getChildAtIndex(i);
|
||||
if (childNode) {
|
||||
float distance = glm::distance(point, childNode->getCenter());
|
||||
currentCount = insertIntoSortedArrays((void*)childNode, distance, i,
|
||||
(void**)&sortedChildren, (float*)&distancesToChildren,
|
||||
(int*)&indexOfChildren, currentCount, NUMBER_OF_CHILDREN);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < currentCount; i++) {
|
||||
VoxelNode* childNode = sortedChildren[i];
|
||||
if (childNode) {
|
||||
recurseNodeWithOperationDistanceSorted(childNode, operation, point, extraData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VoxelNode* VoxelTree::nodeForOctalCode(VoxelNode* ancestorNode,
|
||||
unsigned char* needleCode, VoxelNode** parentOfFoundNode) const {
|
||||
// find the appropriate branch index based on this ancestorNode
|
||||
if (*needleCode > 0) {
|
||||
int branchForNeedle = branchIndexWithDescendant(ancestorNode->getOctalCode(), needleCode);
|
||||
|
|
|
@ -67,6 +67,8 @@ public:
|
|||
creationMode mode, bool destructive = false, bool debug = false);
|
||||
|
||||
void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
|
||||
void recurseTreeWithOperationDistanceSorted(RecurseVoxelTreeOperation operation,
|
||||
const glm::vec3& point, void* extraData=NULL);
|
||||
|
||||
int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
|
||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum,
|
||||
|
@ -117,6 +119,9 @@ private:
|
|||
static bool countVoxelsOperation(VoxelNode* node, void* extraData);
|
||||
|
||||
void recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData);
|
||||
void recurseNodeWithOperationDistanceSorted(VoxelNode* node, RecurseVoxelTreeOperation operation,
|
||||
const glm::vec3& point, void* extraData);
|
||||
|
||||
VoxelNode* nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode) const;
|
||||
VoxelNode* createMissingNode(VoxelNode* lastParentNode, unsigned char* deepestCodeToCreate);
|
||||
int readNodeData(VoxelNode *destinationNode, unsigned char* nodeData, int bufferSizeBytes,
|
||||
|
|
Loading…
Reference in a new issue