cr cleanup, remove loadBitstreamBuffer()

This commit is contained in:
ZappoMan 2013-04-30 11:06:30 -07:00
parent 7d801e99d1
commit 447de68fb5
3 changed files with 13 additions and 276 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -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";