mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 15:33:10 +02:00
Add LOD culling to the server protocol.
- Add LOD/distance culling to VoxelTree:encodeTreeBitstreamRecursion() and VoxelTree::searchForColoredNodesRecursion() - added new levels to boundaryDistanceForRenderLevel() - added more spheres to the scene to get a better sense of LOD behavior
This commit is contained in:
parent
a638542aa0
commit
accda966d5
5 changed files with 90 additions and 30 deletions
|
@ -55,10 +55,6 @@ VoxelSystem::~VoxelSystem() {
|
|||
pthread_mutex_destroy(&bufferWriteLock);
|
||||
}
|
||||
|
||||
void VoxelSystem::setViewerAvatar(Avatar *newViewerAvatar) {
|
||||
viewerAvatar = newViewerAvatar;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Method: VoxelSystem::loadVoxelsFile()
|
||||
// Description: Loads HiFidelity encoded Voxels from a binary file. The current file
|
||||
|
@ -180,7 +176,7 @@ void VoxelSystem::copyWrittenDataToReadArrays() {
|
|||
int VoxelSystem::treeToArrays(VoxelNode* currentNode, const glm::vec3& nodePosition) {
|
||||
int voxelsAdded = 0;
|
||||
float halfUnitForVoxel = powf(0.5, *currentNode->octalCode) * (0.5 * TREE_SCALE);
|
||||
glm::vec3 viewerPosition = viewerAvatar->getPosition();
|
||||
glm::vec3 viewerPosition = _camera->getPosition(); //_viewerAvatar->getPosition();
|
||||
|
||||
// debug LOD code
|
||||
glm::vec3 debugNodePosition;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <VoxelTree.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include "Avatar.h"
|
||||
#include "Camera.h"
|
||||
#include "Util.h"
|
||||
#include "world.h"
|
||||
|
||||
|
@ -34,7 +35,8 @@ public:
|
|||
void render();
|
||||
void setVoxelsRendered(int v) {voxelsRendered = v;};
|
||||
int getVoxelsRendered() {return voxelsRendered;};
|
||||
void setViewerAvatar(Avatar *newViewerAvatar);
|
||||
void setViewerAvatar(Avatar *newViewerAvatar) { _viewerAvatar = newViewerAvatar; };
|
||||
void setCamera(Camera* newCamera) { _camera = newCamera; };
|
||||
void loadVoxelsFile(const char* fileName,bool wantColorRandomizer);
|
||||
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer);
|
||||
|
||||
|
@ -67,7 +69,8 @@ private:
|
|||
static float _minDistance;
|
||||
|
||||
int voxelsRendered;
|
||||
Avatar *viewerAvatar;
|
||||
Avatar* _viewerAvatar;
|
||||
Camera* _camera;
|
||||
VoxelTree *tree;
|
||||
GLfloat *readVerticesArray;
|
||||
GLubyte *readColorsArray;
|
||||
|
|
|
@ -299,6 +299,7 @@ void init(void)
|
|||
{
|
||||
voxels.init();
|
||||
voxels.setViewerAvatar(&myAvatar);
|
||||
voxels.setCamera(&myCamera);
|
||||
|
||||
handControl.setScreenDimensions(WIDTH, HEIGHT);
|
||||
|
||||
|
|
|
@ -84,9 +84,27 @@ int boundaryDistanceForRenderLevel(unsigned int renderLevel) {
|
|||
case 7:
|
||||
return 12;
|
||||
break;
|
||||
default:
|
||||
case 8:
|
||||
return 10;
|
||||
break;
|
||||
case 9:
|
||||
return 6;
|
||||
break;
|
||||
case 10:
|
||||
return 4.5;
|
||||
break;
|
||||
case 11:
|
||||
return 3;
|
||||
break;
|
||||
case 12:
|
||||
return 2.25;
|
||||
break;
|
||||
case 13:
|
||||
return 1.5;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -817,10 +835,12 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
|
|||
}
|
||||
|
||||
float distance = childNode->distanceToCamera(viewFrustum);
|
||||
|
||||
inViewCount = insertIntoSortedArrays((void*)childNode, distance, i,
|
||||
(void**)&inViewChildren, (float*)&distancesToChildren, (int*)&positionOfChildren,
|
||||
inViewCount, MAX_CHILDREN);
|
||||
|
||||
if (distance < boundaryDistanceForRenderLevel(*childNode->octalCode + 1)) {
|
||||
inViewCount = insertIntoSortedArrays((void*)childNode, distance, i,
|
||||
(void**)&inViewChildren, (float*)&distancesToChildren, (int*)&positionOfChildren,
|
||||
inViewCount, MAX_CHILDREN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -920,6 +940,14 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
return bytesAtThisLevel;
|
||||
}
|
||||
|
||||
float distance = node->distanceToCamera(viewFrustum);
|
||||
float boundaryDistance = boundaryDistanceForRenderLevel(*node->octalCode + 1);
|
||||
|
||||
// If we're too far away for our render level, then just return
|
||||
if (distance >= boundaryDistance) {
|
||||
return bytesAtThisLevel;
|
||||
}
|
||||
|
||||
// If we're at a node that is out of view, then we can return, because no nodes below us will be in view!
|
||||
// although technically, we really shouldn't ever be here, because our callers shouldn't be calling us if
|
||||
// we're out of view
|
||||
|
@ -954,26 +982,28 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
for (int i = 0; i < MAX_CHILDREN; i++) {
|
||||
VoxelNode* childNode = node->children[i];
|
||||
bool childExists = (childNode != NULL);
|
||||
|
||||
bool childIsColored = (childExists && childNode->isColored());
|
||||
bool childIsInView = (childExists && childNode->isInView(viewFrustum));
|
||||
bool childIsLeaf = (childExists && childNode->isLeaf());
|
||||
|
||||
if (childIsInView) {
|
||||
inViewCount++;
|
||||
// Before we determine consider this further, let's see if it's in our LOD scope...
|
||||
float distance = childNode->distanceToCamera(viewFrustum);
|
||||
float boundaryDistance = boundaryDistanceForRenderLevel(*childNode->octalCode + 1);
|
||||
|
||||
if (distance < boundaryDistance) {
|
||||
inViewCount++;
|
||||
|
||||
// track children in view as existing and not a leaf, if they're a leaf,
|
||||
// we don't care about recursing deeper on them, and we don't consider their
|
||||
// subtree to exist
|
||||
if (!childIsLeaf) {
|
||||
childrenExistBits += (1 << (7 - i));
|
||||
inViewNotLeafCount++;
|
||||
}
|
||||
// track children in view as existing and not a leaf, if they're a leaf,
|
||||
// we don't care about recursing deeper on them, and we don't consider their
|
||||
// subtree to exist
|
||||
if (!(childExists && childNode->isLeaf())) {
|
||||
childrenExistBits += (1 << (7 - i));
|
||||
inViewNotLeafCount++;
|
||||
}
|
||||
|
||||
// track children with actual color
|
||||
if (childIsColored) {
|
||||
childrenColoredBits += (1 << (7 - i));
|
||||
inViewWithColorCount++;
|
||||
// track children with actual color
|
||||
if (childExists && childNode->isColored()) {
|
||||
childrenColoredBits += (1 << (7 - i));
|
||||
inViewWithColorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1016,7 +1046,6 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
// of handling things. For example, in case of child iteration, it needs to unset the child exist bit for
|
||||
// this child.
|
||||
// add our node the the list of extra nodes to output later...
|
||||
|
||||
bag.insert(node);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ const float DEATH_STAR_RADIUS = 4.0;
|
|||
const float MAX_CUBE = 0.05f;
|
||||
|
||||
const int VOXEL_SEND_INTERVAL_USECS = 100 * 1000;
|
||||
const int PACKETS_PER_CLIENT_PER_INTERVAL = 5;
|
||||
const int PACKETS_PER_CLIENT_PER_INTERVAL = 2;
|
||||
|
||||
const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4;
|
||||
|
||||
|
@ -68,6 +68,16 @@ void addSphere(VoxelTree * tree,bool random, bool wantColorRandomizer) {
|
|||
tree->createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer);
|
||||
}
|
||||
|
||||
int _nodeCount=0;
|
||||
bool countVoxelsOperation(VoxelNode* node, bool down, void* extraData) {
|
||||
if (down) {
|
||||
if (node->isColored()){
|
||||
_nodeCount++;
|
||||
}
|
||||
}
|
||||
return true; // keep going
|
||||
}
|
||||
|
||||
void addSphereScene(VoxelTree * tree, bool wantColorRandomizer) {
|
||||
printf("adding scene of spheres...\n");
|
||||
|
||||
|
@ -80,6 +90,8 @@ void addSphereScene(VoxelTree * tree, bool wantColorRandomizer) {
|
|||
tree->createSphere(0.25,0.5,0.5,0.5,(1.0/sphereBaseSize),true,wantColorRandomizer);
|
||||
printf("one sphere added...\n");
|
||||
tree->createSphere(0.030625,0.5,0.5,(0.25-0.06125),(1.0/(sphereBaseSize*2)),true,true);
|
||||
|
||||
|
||||
printf("two spheres added...\n");
|
||||
tree->createSphere(0.030625,(1.0-0.030625),(1.0-0.030625),(1.0-0.06125),(1.0/(sphereBaseSize*2)),true,true);
|
||||
printf("three spheres added...\n");
|
||||
|
@ -88,6 +100,25 @@ void addSphereScene(VoxelTree * tree, bool wantColorRandomizer) {
|
|||
tree->createSphere(0.030625,(1.0-0.030625),0.06125,(1.0-0.06125),(1.0/(sphereBaseSize*2)),true,true);
|
||||
printf("five spheres added...\n");
|
||||
tree->createSphere(0.06125,0.125,0.125,(1.0-0.125),(1.0/(sphereBaseSize*2)),true,true);
|
||||
|
||||
float radius = 0.0125f;
|
||||
printf("6 spheres added...\n");
|
||||
tree->createSphere(radius,0.25,radius*5.0f,0.25,(1.0/(4096)),true,true);
|
||||
printf("7 spheres added...\n");
|
||||
tree->createSphere(radius,0.125,radius*5.0f,0.25,(1.0/(4096)),true,true);
|
||||
printf("8 spheres added...\n");
|
||||
tree->createSphere(radius,0.075,radius*5.0f,0.25,(1.0/(4096)),true,true);
|
||||
printf("9 spheres added...\n");
|
||||
tree->createSphere(radius,0.05,radius*5.0f,0.25,(1.0/(4096)),true,true);
|
||||
printf("10 spheres added...\n");
|
||||
tree->createSphere(radius,0.025,radius*5.0f,0.25,(1.0/(4096)),true,true);
|
||||
printf("11 spheres added...\n");
|
||||
|
||||
_nodeCount=0;
|
||||
tree->recurseTreeWithOperation(countVoxelsOperation);
|
||||
printf("Nodes after adding scene %d nodes\n",_nodeCount);
|
||||
|
||||
|
||||
printf("DONE adding scene of spheres...\n");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue