mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 17:14:59 +02:00
cr cleanup, remove loadBitstreamBuffer()
This commit is contained in:
parent
7d801e99d1
commit
447de68fb5
3 changed files with 13 additions and 276 deletions
|
@ -308,199 +308,6 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) {
|
|||
lastCreatedNode->setColor(newColor);
|
||||
}
|
||||
|
||||
unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer,
|
||||
VoxelNode *currentVoxelNode,
|
||||
MarkerNode *currentMarkerNode,
|
||||
const glm::vec3& agentPosition,
|
||||
float thisNodePosition[3],
|
||||
const ViewFrustum& viewFrustum,
|
||||
bool viewFrustumCulling,
|
||||
unsigned char * stopOctalCode)
|
||||
{
|
||||
unsigned char * childStopOctalCode = NULL;
|
||||
static unsigned char *initialBitstreamPos = bitstreamBuffer;
|
||||
|
||||
if (stopOctalCode == NULL) {
|
||||
stopOctalCode = rootNode->octalCode;
|
||||
}
|
||||
|
||||
// check if we have any children
|
||||
bool hasAtLeastOneChild;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (currentVoxelNode->children[i] != NULL) {
|
||||
hasAtLeastOneChild = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have at least one child, check if it will be worth recursing into our children
|
||||
if (hasAtLeastOneChild) {
|
||||
|
||||
int firstIndexToCheck = 0;
|
||||
unsigned char * childMaskPointer = NULL;
|
||||
|
||||
float halfUnitForVoxel = powf(0.5, *currentVoxelNode->octalCode) * (0.5 * TREE_SCALE);
|
||||
float distanceToVoxelCenter = sqrtf(powf(agentPosition[0] - thisNodePosition[0] - halfUnitForVoxel, 2) +
|
||||
powf(agentPosition[1] - thisNodePosition[1] - halfUnitForVoxel, 2) +
|
||||
powf(agentPosition[2] - thisNodePosition[2] - halfUnitForVoxel, 2));
|
||||
|
||||
if (distanceToVoxelCenter < boundaryDistanceForRenderLevel(*currentVoxelNode->octalCode + 1)) {
|
||||
|
||||
// write this voxel's data if we're below or at
|
||||
// or at the same level as the stopOctalCode
|
||||
|
||||
if (*currentVoxelNode->octalCode >= *stopOctalCode) {
|
||||
|
||||
if ((bitstreamBuffer - initialBitstreamPos) + MAX_TREE_SLICE_BYTES > MAX_VOXEL_PACKET_SIZE) {
|
||||
// we can't send this packet, not enough room
|
||||
// return our octal code as the stop
|
||||
return currentVoxelNode->octalCode;
|
||||
}
|
||||
|
||||
if (strcmp((char *)stopOctalCode, (char *)currentVoxelNode->octalCode) == 0) {
|
||||
// this is is the root node for this packet
|
||||
// add the leading V
|
||||
*(bitstreamBuffer++) = PACKET_HEADER_VOXEL_DATA;
|
||||
|
||||
// add its octal code to the packet
|
||||
int octalCodeBytes = bytesRequiredForCodeLength(*currentVoxelNode->octalCode);
|
||||
|
||||
memcpy(bitstreamBuffer, currentVoxelNode->octalCode, octalCodeBytes);
|
||||
bitstreamBuffer += octalCodeBytes;
|
||||
}
|
||||
|
||||
// default color mask is 0, increment pointer for colors
|
||||
*bitstreamBuffer = 0;
|
||||
|
||||
// keep a colorPointer so we can check how many colors were added
|
||||
unsigned char *colorPointer = bitstreamBuffer + 1;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
// Rules for including a child:
|
||||
// 1) child must exists
|
||||
if ((currentVoxelNode->children[i] != NULL)) {
|
||||
// 2) child must have a color...
|
||||
if (currentVoxelNode->children[i]->isColored()) {
|
||||
unsigned char* childOctalCode = currentVoxelNode->children[i]->octalCode;
|
||||
|
||||
float childPosition[3];
|
||||
copyFirstVertexForCode(childOctalCode,(float*)&childPosition);
|
||||
childPosition[0] *= TREE_SCALE; // scale it up
|
||||
childPosition[1] *= TREE_SCALE; // scale it up
|
||||
childPosition[2] *= TREE_SCALE; // scale it up
|
||||
|
||||
float halfChildVoxel = powf(0.5, *childOctalCode) * (0.5 * TREE_SCALE);
|
||||
float fullChildVoxel = halfChildVoxel * 2.0f;
|
||||
AABox childBox;
|
||||
childBox.setBox(glm::vec3(childPosition[0], childPosition[1], childPosition[2]),
|
||||
fullChildVoxel, fullChildVoxel, fullChildVoxel);
|
||||
|
||||
bool childInView = !viewFrustumCulling ||
|
||||
(ViewFrustum::OUTSIDE != viewFrustum.boxInFrustum(childBox));
|
||||
|
||||
/// XXXBHG - debug code, switch this to true, and we'll send everything but include false coloring
|
||||
// on voxels based on whether or not they match these rules.
|
||||
bool falseColorInsteadOfCulling = false;
|
||||
bool sendChild = childInView || falseColorInsteadOfCulling;
|
||||
|
||||
// if we sendAnyway, we'll do false coloring of the voxels based on childInView
|
||||
if (sendChild) {
|
||||
|
||||
// copy in the childs color to bitstreamBuffer
|
||||
if (childInView) {
|
||||
// true color
|
||||
memcpy(colorPointer, currentVoxelNode->children[i]->getTrueColor(), 3);
|
||||
} else {
|
||||
unsigned char red[3] = {255,0,0};
|
||||
if (!childInView) {
|
||||
// If not in view, color them red
|
||||
memcpy(colorPointer, red, 3);
|
||||
}
|
||||
}
|
||||
colorPointer += 3;
|
||||
|
||||
// set the colorMask by bitshifting the value of childExists
|
||||
*bitstreamBuffer += (1 << (7 - i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// push the bitstreamBuffer forwards for the number of added colors
|
||||
bitstreamBuffer += (colorPointer - bitstreamBuffer);
|
||||
|
||||
// maintain a pointer to this spot in the buffer so we can set our child mask
|
||||
// depending on the results of the recursion below
|
||||
childMaskPointer = bitstreamBuffer++;
|
||||
|
||||
// reset the childMaskPointer for this node to 0
|
||||
*childMaskPointer = 0;
|
||||
} else {
|
||||
firstIndexToCheck = *stopOctalCode > 0
|
||||
? branchIndexWithDescendant(currentVoxelNode->octalCode, stopOctalCode)
|
||||
: 0;
|
||||
}
|
||||
|
||||
unsigned char * arrBufferBeforeChild = bitstreamBuffer;
|
||||
|
||||
for (int i = firstIndexToCheck; i < 8; i ++) {
|
||||
// ask the child to load this bitstream buffer
|
||||
// if they or their descendants fill the MTU we will receive the childStopOctalCode back
|
||||
if (currentVoxelNode->children[i] != NULL) {
|
||||
if (!oneAtBit(currentMarkerNode->childrenVisitedMask, i)) {
|
||||
|
||||
// create the marker node for this child if it does not yet exist
|
||||
if (currentMarkerNode->children[i] == NULL) {
|
||||
currentMarkerNode->children[i] = new MarkerNode();
|
||||
}
|
||||
|
||||
float childNodePosition[3];
|
||||
copyFirstVertexForCode(currentVoxelNode->children[i]->octalCode,(float*)&childNodePosition);
|
||||
childNodePosition[0] *= TREE_SCALE; // scale it up
|
||||
childNodePosition[1] *= TREE_SCALE; // scale it up
|
||||
childNodePosition[2] *= TREE_SCALE; // scale it up
|
||||
|
||||
// ask the child to load the bitstream buffer with their data
|
||||
childStopOctalCode = loadBitstreamBuffer(bitstreamBuffer,
|
||||
currentVoxelNode->children[i],
|
||||
currentMarkerNode->children[i],
|
||||
agentPosition,
|
||||
childNodePosition,
|
||||
viewFrustum,
|
||||
viewFrustumCulling,
|
||||
stopOctalCode);
|
||||
|
||||
if (bitstreamBuffer - arrBufferBeforeChild > 0) {
|
||||
// this child added data to the packet - add it to our child mask
|
||||
if (childMaskPointer != NULL) {
|
||||
*childMaskPointer += (1 << (7 - i));
|
||||
}
|
||||
|
||||
arrBufferBeforeChild = bitstreamBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (childStopOctalCode != NULL) {
|
||||
break;
|
||||
} else {
|
||||
// this child node has been covered
|
||||
// add the appropriate bit to the childrenVisitedMask for the current marker node
|
||||
currentMarkerNode->childrenVisitedMask += 1 << (7 - i);
|
||||
|
||||
// if we are above the stopOctal and we got a NULL code
|
||||
// we cannot go to the next child
|
||||
// so break and return the NULL stop code
|
||||
if (*currentVoxelNode->octalCode < *stopOctalCode) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return childStopOctalCode;
|
||||
}
|
||||
|
||||
void VoxelTree::processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes) {
|
||||
// XXXBHG: validate buffer is at least 4 bytes long? other guards??
|
||||
unsigned short int itemNumber = (*((unsigned short int*)&bitstream[1]));
|
||||
|
@ -861,8 +668,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, const Vi
|
|||
|
||||
int currentEncodeLevel = 0;
|
||||
int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel,
|
||||
node, viewFrustum,
|
||||
outputBuffer, availableBytes, bag);
|
||||
node, viewFrustum,
|
||||
outputBuffer, availableBytes, bag);
|
||||
|
||||
// if childBytesWritten == 1 then something went wrong... that's not possible
|
||||
assert(childBytesWritten != 1);
|
||||
|
@ -890,9 +697,9 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, const Vi
|
|||
// NOTE: This recursive function DOES NOT add the octcode to the buffer. It's assumed that the caller has
|
||||
// already done that.
|
||||
int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
|
||||
VoxelNode* node, const ViewFrustum& viewFrustum,
|
||||
unsigned char* outputBuffer, int availableBytes,
|
||||
VoxelNodeBag& bag) const {
|
||||
VoxelNode* node, const ViewFrustum& viewFrustum,
|
||||
unsigned char* outputBuffer, int availableBytes,
|
||||
VoxelNodeBag& bag) const {
|
||||
// How many bytes have we written so far at this level;
|
||||
int bytesAtThisLevel = 0;
|
||||
|
||||
|
@ -978,7 +785,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
// write the color data...
|
||||
for (int i = 0; i < MAX_CHILDREN; i++) {
|
||||
if (oneAtBit(childrenColoredBits, i)) {
|
||||
memcpy(writeToThisLevelBuffer,&node->children[i]->getColor(),BYTES_PER_COLOR);
|
||||
memcpy(writeToThisLevelBuffer, &node->children[i]->getColor(), BYTES_PER_COLOR);
|
||||
writeToThisLevelBuffer += BYTES_PER_COLOR; // move the pointer for color
|
||||
bytesAtThisLevel += BYTES_PER_COLOR; // keep track of byte count for color
|
||||
}
|
||||
|
@ -998,7 +805,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
|
||||
// If we have enough room to copy our local results into the buffer, then do so...
|
||||
if (availableBytes >= bytesAtThisLevel) {
|
||||
memcpy(outputBuffer,&thisLevelBuffer[0],bytesAtThisLevel);
|
||||
memcpy(outputBuffer, &thisLevelBuffer[0], bytesAtThisLevel);
|
||||
|
||||
outputBuffer += bytesAtThisLevel;
|
||||
availableBytes -= bytesAtThisLevel;
|
||||
|
@ -1033,8 +840,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
VoxelNode* childNode = node->children[i];
|
||||
|
||||
int thisLevel = currentEncodeLevel;
|
||||
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel,
|
||||
childNode, viewFrustum, outputBuffer, availableBytes, bag);
|
||||
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode,
|
||||
viewFrustum, outputBuffer, availableBytes, bag);
|
||||
|
||||
// if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space,
|
||||
// basically, the children below don't contain any info.
|
||||
|
@ -1052,7 +859,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
// so, if the child returns 2 bytes out, we can actually consider that an empty tree also!!
|
||||
//
|
||||
// we can make this act like no bytes out, by just resetting the bytes out in this case
|
||||
if (2 == childTreeBytesOut) {
|
||||
if (childTreeBytesOut == 2) {
|
||||
childTreeBytesOut = 0; // this is the degenerate case of a tree with no colors and no child trees
|
||||
}
|
||||
|
||||
|
@ -1062,17 +869,15 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
|
||||
// If we had previously started writing, and if the child DIDN'T write any bytes,
|
||||
// then we want to remove their bit from the childExistsPlaceHolder bitmask
|
||||
if (0 == childTreeBytesOut) {
|
||||
if (childTreeBytesOut == 0) {
|
||||
// remove this child's bit...
|
||||
childrenExistBits -= (1 << (7 - i));
|
||||
|
||||
// repair the child exists mask
|
||||
*childExistsPlaceHolder = childrenExistBits;
|
||||
// Note: no need to move the pointer, cause we already stored this
|
||||
} // end if (0 == childTreeBytesOut)
|
||||
} // end if (childTreeBytesOut == 0)
|
||||
} // end if (oneAtBit(childrenExistBits, i))
|
||||
} // end for
|
||||
} // end keepDiggingDeeper
|
||||
return bytesAtThisLevel;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,15 +45,6 @@ public:
|
|||
void deleteVoxelCodeFromTree(unsigned char *codeBuffer);
|
||||
void printTreeForDebugging(VoxelNode *startNode);
|
||||
void reaverageVoxelColors(VoxelNode *startNode);
|
||||
unsigned char * loadBitstreamBuffer(unsigned char*& bitstreamBuffer,
|
||||
VoxelNode* currentVoxelNode,
|
||||
MarkerNode* currentMarkerNode,
|
||||
const glm::vec3& agentPosition,
|
||||
float thisNodePosition[3],
|
||||
const ViewFrustum& viewFrustum,
|
||||
bool viewFrustumCulling,
|
||||
unsigned char* octalCode = NULL);
|
||||
|
||||
void loadVoxelsFile(const char* fileName, bool wantColorRandomizer);
|
||||
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer);
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ VoxelTree randomTree;
|
|||
bool wantColorRandomizer = false;
|
||||
bool debugViewFrustum = false;
|
||||
bool viewFrustumCulling = true; // for now
|
||||
bool newVoxelDistributor = false; // for now
|
||||
|
||||
void addSphere(VoxelTree * tree,bool random, bool wantColorRandomizer) {
|
||||
float r = random ? randFloatInRange(0.05,0.1) : 0.25;
|
||||
|
@ -81,10 +80,6 @@ bool countVoxelsOperation(VoxelNode* node, bool down, void* extraData) {
|
|||
void addSphereScene(VoxelTree * tree, bool wantColorRandomizer) {
|
||||
printf("adding scene of spheres...\n");
|
||||
|
||||
// The old voxel distributor has a hard time with smaller voxels and more
|
||||
// complex scenes... so if we're using the old distributor make our scene
|
||||
// simple with larger sized voxels
|
||||
//int sphereBaseSize = ::newVoxelDistributor ? 512 : 256;
|
||||
int sphereBaseSize = 256;
|
||||
|
||||
tree->createSphere(0.25,0.5,0.5,0.5,(1.0/sphereBaseSize),true,wantColorRandomizer);
|
||||
|
@ -305,16 +300,6 @@ void *distributeVoxelsToListeners(void *args) {
|
|||
AgentList* agentList = AgentList::getInstance();
|
||||
timeval lastSendTime;
|
||||
|
||||
unsigned char *stopOctal;
|
||||
int packetCount;
|
||||
|
||||
int totalBytesSent;
|
||||
|
||||
unsigned char *voxelPacket = new unsigned char[MAX_VOXEL_PACKET_SIZE];
|
||||
unsigned char *voxelPacketEnd;
|
||||
|
||||
float treeRoot[3] = {0, 0, 0};
|
||||
|
||||
while (true) {
|
||||
gettimeofday(&lastSendTime, NULL);
|
||||
|
||||
|
@ -337,47 +322,7 @@ void *distributeVoxelsToListeners(void *args) {
|
|||
|
||||
viewFrustum.calculate();
|
||||
|
||||
if (::newVoxelDistributor) {
|
||||
newDistributeHelper(agentList, agent, agentData, viewFrustum);
|
||||
} else {
|
||||
stopOctal = NULL;
|
||||
packetCount = 0;
|
||||
totalBytesSent = 0;
|
||||
randomTree.leavesWrittenToBitstream = 0;
|
||||
|
||||
for (int j = 0; j < PACKETS_PER_CLIENT_PER_INTERVAL; j++) {
|
||||
voxelPacketEnd = voxelPacket;
|
||||
stopOctal = randomTree.loadBitstreamBuffer(voxelPacketEnd,
|
||||
randomTree.rootNode,
|
||||
agentData->rootMarkerNode,
|
||||
agentData->getPosition(),
|
||||
treeRoot,
|
||||
viewFrustum,
|
||||
::viewFrustumCulling,
|
||||
stopOctal);
|
||||
|
||||
agentList->getAgentSocket().send(agent->getActiveSocket(), voxelPacket, voxelPacketEnd - voxelPacket);
|
||||
|
||||
packetCount++;
|
||||
totalBytesSent += voxelPacketEnd - voxelPacket;
|
||||
|
||||
// XXXBHG Hack Attack: This is temporary code to help debug an issue.
|
||||
// Normally we use this break to prevent resending voxels that an agent has
|
||||
// already visited. But since we might be modifying the voxel tree we might
|
||||
// want to always send. This is a hack to test the behavior
|
||||
bool alwaysSend = true;
|
||||
if (!alwaysSend && agentData->rootMarkerNode->childrenVisitedMask == 255) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// for any agent that has a root marker node with 8 visited children
|
||||
// recursively delete its marker nodes so we can revisit
|
||||
if (agentData->rootMarkerNode->childrenVisitedMask == 255) {
|
||||
delete agentData->rootMarkerNode;
|
||||
agentData->rootMarkerNode = new MarkerNode();
|
||||
}
|
||||
}
|
||||
newDistributeHelper(agentList, agent, agentData, viewFrustum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -433,10 +378,6 @@ int main(int argc, const char * argv[])
|
|||
::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER);
|
||||
printf("wantColorRandomizer=%s\n", (::wantColorRandomizer ? "yes" : "no"));
|
||||
|
||||
const char* OLD_VOXEL_DISTRIBUTOR = "--OldVoxelDistributor";
|
||||
::newVoxelDistributor = !cmdOptionExists(argc, argv, OLD_VOXEL_DISTRIBUTOR);
|
||||
printf("newVoxelDistributor=%s\n", (::newVoxelDistributor ? "yes" : "no"));
|
||||
|
||||
// Check to see if the user passed in a command line option for loading a local
|
||||
// Voxel File. If so, load it now.
|
||||
const char* INPUT_FILE = "-i";
|
||||
|
|
Loading…
Reference in a new issue