mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-26 02:55:25 +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);
|
pthread_mutex_destroy(&bufferWriteLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::setViewerAvatar(Avatar *newViewerAvatar) {
|
|
||||||
viewerAvatar = newViewerAvatar;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Method: VoxelSystem::loadVoxelsFile()
|
// Method: VoxelSystem::loadVoxelsFile()
|
||||||
// Description: Loads HiFidelity encoded Voxels from a binary file. The current file
|
// 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 VoxelSystem::treeToArrays(VoxelNode* currentNode, const glm::vec3& nodePosition) {
|
||||||
int voxelsAdded = 0;
|
int voxelsAdded = 0;
|
||||||
float halfUnitForVoxel = powf(0.5, *currentNode->octalCode) * (0.5 * TREE_SCALE);
|
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
|
// debug LOD code
|
||||||
glm::vec3 debugNodePosition;
|
glm::vec3 debugNodePosition;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <VoxelTree.h>
|
#include <VoxelTree.h>
|
||||||
#include <ViewFrustum.h>
|
#include <ViewFrustum.h>
|
||||||
#include "Avatar.h"
|
#include "Avatar.h"
|
||||||
|
#include "Camera.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
|
|
||||||
|
@ -34,7 +35,8 @@ public:
|
||||||
void render();
|
void render();
|
||||||
void setVoxelsRendered(int v) {voxelsRendered = v;};
|
void setVoxelsRendered(int v) {voxelsRendered = v;};
|
||||||
int getVoxelsRendered() {return voxelsRendered;};
|
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 loadVoxelsFile(const char* fileName,bool wantColorRandomizer);
|
||||||
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, 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;
|
static float _minDistance;
|
||||||
|
|
||||||
int voxelsRendered;
|
int voxelsRendered;
|
||||||
Avatar *viewerAvatar;
|
Avatar* _viewerAvatar;
|
||||||
|
Camera* _camera;
|
||||||
VoxelTree *tree;
|
VoxelTree *tree;
|
||||||
GLfloat *readVerticesArray;
|
GLfloat *readVerticesArray;
|
||||||
GLubyte *readColorsArray;
|
GLubyte *readColorsArray;
|
||||||
|
|
|
@ -299,6 +299,7 @@ void init(void)
|
||||||
{
|
{
|
||||||
voxels.init();
|
voxels.init();
|
||||||
voxels.setViewerAvatar(&myAvatar);
|
voxels.setViewerAvatar(&myAvatar);
|
||||||
|
voxels.setCamera(&myCamera);
|
||||||
|
|
||||||
handControl.setScreenDimensions(WIDTH, HEIGHT);
|
handControl.setScreenDimensions(WIDTH, HEIGHT);
|
||||||
|
|
||||||
|
|
|
@ -84,9 +84,27 @@ int boundaryDistanceForRenderLevel(unsigned int renderLevel) {
|
||||||
case 7:
|
case 7:
|
||||||
return 12;
|
return 12;
|
||||||
break;
|
break;
|
||||||
default:
|
case 8:
|
||||||
|
return 10;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
return 6;
|
return 6;
|
||||||
break;
|
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);
|
float distance = childNode->distanceToCamera(viewFrustum);
|
||||||
|
|
||||||
inViewCount = insertIntoSortedArrays((void*)childNode, distance, i,
|
if (distance < boundaryDistanceForRenderLevel(*childNode->octalCode + 1)) {
|
||||||
(void**)&inViewChildren, (float*)&distancesToChildren, (int*)&positionOfChildren,
|
inViewCount = insertIntoSortedArrays((void*)childNode, distance, i,
|
||||||
inViewCount, MAX_CHILDREN);
|
(void**)&inViewChildren, (float*)&distancesToChildren, (int*)&positionOfChildren,
|
||||||
|
inViewCount, MAX_CHILDREN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -920,6 +940,14 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
||||||
return bytesAtThisLevel;
|
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!
|
// 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
|
// although technically, we really shouldn't ever be here, because our callers shouldn't be calling us if
|
||||||
// we're out of view
|
// we're out of view
|
||||||
|
@ -954,26 +982,28 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
||||||
for (int i = 0; i < MAX_CHILDREN; i++) {
|
for (int i = 0; i < MAX_CHILDREN; i++) {
|
||||||
VoxelNode* childNode = node->children[i];
|
VoxelNode* childNode = node->children[i];
|
||||||
bool childExists = (childNode != NULL);
|
bool childExists = (childNode != NULL);
|
||||||
|
|
||||||
bool childIsColored = (childExists && childNode->isColored());
|
|
||||||
bool childIsInView = (childExists && childNode->isInView(viewFrustum));
|
bool childIsInView = (childExists && childNode->isInView(viewFrustum));
|
||||||
bool childIsLeaf = (childExists && childNode->isLeaf());
|
|
||||||
|
|
||||||
if (childIsInView) {
|
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,
|
// 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
|
// we don't care about recursing deeper on them, and we don't consider their
|
||||||
// subtree to exist
|
// subtree to exist
|
||||||
if (!childIsLeaf) {
|
if (!(childExists && childNode->isLeaf())) {
|
||||||
childrenExistBits += (1 << (7 - i));
|
childrenExistBits += (1 << (7 - i));
|
||||||
inViewNotLeafCount++;
|
inViewNotLeafCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// track children with actual color
|
// track children with actual color
|
||||||
if (childIsColored) {
|
if (childExists && childNode->isColored()) {
|
||||||
childrenColoredBits += (1 << (7 - i));
|
childrenColoredBits += (1 << (7 - i));
|
||||||
inViewWithColorCount++;
|
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
|
// of handling things. For example, in case of child iteration, it needs to unset the child exist bit for
|
||||||
// this child.
|
// this child.
|
||||||
// add our node the the list of extra nodes to output later...
|
// add our node the the list of extra nodes to output later...
|
||||||
|
|
||||||
bag.insert(node);
|
bag.insert(node);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ const float DEATH_STAR_RADIUS = 4.0;
|
||||||
const float MAX_CUBE = 0.05f;
|
const float MAX_CUBE = 0.05f;
|
||||||
|
|
||||||
const int VOXEL_SEND_INTERVAL_USECS = 100 * 1000;
|
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;
|
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);
|
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) {
|
void addSphereScene(VoxelTree * tree, bool wantColorRandomizer) {
|
||||||
printf("adding scene of spheres...\n");
|
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);
|
tree->createSphere(0.25,0.5,0.5,0.5,(1.0/sphereBaseSize),true,wantColorRandomizer);
|
||||||
printf("one sphere added...\n");
|
printf("one sphere added...\n");
|
||||||
tree->createSphere(0.030625,0.5,0.5,(0.25-0.06125),(1.0/(sphereBaseSize*2)),true,true);
|
tree->createSphere(0.030625,0.5,0.5,(0.25-0.06125),(1.0/(sphereBaseSize*2)),true,true);
|
||||||
|
|
||||||
|
|
||||||
printf("two spheres added...\n");
|
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);
|
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");
|
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);
|
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");
|
printf("five spheres added...\n");
|
||||||
tree->createSphere(0.06125,0.125,0.125,(1.0-0.125),(1.0/(sphereBaseSize*2)),true,true);
|
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");
|
printf("DONE adding scene of spheres...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue