diff --git a/shared/src/VoxelTree.cpp b/shared/src/VoxelTree.cpp index 12a2d3d4b5..8bb57b6989 100644 --- a/shared/src/VoxelTree.cpp +++ b/shared/src/VoxelTree.cpp @@ -13,91 +13,99 @@ const int MAX_TREE_SLICE_BYTES = 26; VoxelTree::VoxelTree() { rootNode = new VoxelNode(); + rootNode->octalCode = new unsigned char[1]; + *rootNode->octalCode = (char)0; } -char * VoxelTree::loadBitstream(char * bitstreamBuffer, - VoxelNode *bitstreamRootNode, - char ** startSplitPtr) { - static char **packetSplitPtr = startSplitPtr; +unsigned char * VoxelTree::loadBitstreamBuffer(char *& bitstreamBuffer, + unsigned char * stopOctalCode, + VoxelNode *currentVoxelNode) +{ + static char *initialBitstreamPos = bitstreamBuffer; - if (bitstreamRootNode->childMask != 0) { - - if (bitstreamRootNode == rootNode || (bitstreamBuffer + MAX_TREE_SLICE_BYTES - *packetSplitPtr) > MAX_VOXEL_PACKET_SIZE) { - // we need to add a packet split here + char firstIndexToCheck = 0; + + // we'll only be writing data if we're lower than + // or at the same level as the stopOctalCode + if (*currentVoxelNode->octalCode >= *stopOctalCode) { + if (currentVoxelNode->childMask != 0) { + 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 (bitstreamRootNode == rootNode) { - // set the packetSplitPtr and increment bitstream buffer by 1 for leading V - *packetSplitPtr = bitstreamBuffer; - - // lead packet with a V + if (strcmp((char *)stopOctalCode, (char *)currentVoxelNode->octalCode) == 0) { + // this is is the root node for this packet + // add the leading V *(bitstreamBuffer++) = 'V'; - // root node octal code length byte is 0 - *(bitstreamBuffer++) = 0; + + // 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 + char *colorPointer = bitstreamBuffer + 1; + + for (int i = 0; i < 8; i++) { + + // check if the child exists and is not transparent + if (currentVoxelNode->children[i] != NULL + && currentVoxelNode->children[i]->color[3] != 0) { + + // copy in the childs color to bitstreamBuffer + memcpy(colorPointer, currentVoxelNode->children[i]->color, 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); + + // copy the childMask to the current position of the bitstreamBuffer + // and push the buffer pointer forwards + + *(bitstreamBuffer++) = currentVoxelNode->childMask; + } else { + // if this node is a leaf, return a NULL stop code + // it has been visited + return NULL; + } + } else { + firstIndexToCheck = *stopOctalCode > 0 + ? branchIndexWithDescendant(currentVoxelNode->octalCode, stopOctalCode) + : 0; + } + + unsigned char * childStopOctalCode = NULL; + + 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 (*currentVoxelNode->octalCode < *stopOctalCode + && i > firstIndexToCheck + && childStopOctalCode == NULL) { + return currentVoxelNode->children[i]->octalCode; } else { - // increment packetSplitPtr and set the pointer it points to - // to the beginning of this tree section - - // bistreamBuffer is incremented for leading V - *(++packetSplitPtr) = bitstreamBuffer; - - // lead packet with a V - *(bitstreamBuffer++) = 'V'; - - // add the octal code for the current root - int bytesForOctalCode = bytesRequiredForCodeLength(*bitstreamRootNode->octalCode); - memcpy(bitstreamBuffer, bitstreamRootNode->octalCode, bytesForOctalCode); - - // push the bitstreamBuffer forwards by the number of bytes used for the octal code - bitstreamBuffer += bytesForOctalCode; - } - - // set the color bit for this node - *(bitstreamBuffer++) = (int)(bitstreamRootNode->color[3] != 0); - - // copy this node's color into the bitstreamBuffer, if required - if (bitstreamRootNode->color[3] != 0) { - memcpy(bitstreamBuffer, bitstreamRootNode->color, 3); - bitstreamBuffer += 3; + childStopOctalCode = loadBitstreamBuffer(bitstreamBuffer, stopOctalCode, currentVoxelNode->children[i]); } } - // default color mask is 0, increment pointer for colors - *(bitstreamBuffer++) = 0; - - // keep a colorPointer so we can check how many colors were added - char *colorPointer = bitstreamBuffer; - - for (int i = 0; i < 8; i++) { - // grab this child - VoxelNode *child = bitstreamRootNode->children[i]; - - // check if the child exists and is not transparent - if (child != NULL && child->color[3] != 0) { - - // copy in the childs color to bitstreamBuffer - memcpy(colorPointer, child->color, 3); - colorPointer += 3; - - // set the colorMask by bitshifting the value of childExists - *(bitstreamBuffer - 1) += (1 << (7 - i)); - } - } - - // push the bitstreamBuffer forwards for the number of added colors - bitstreamBuffer += (colorPointer - bitstreamBuffer); - // copy the childMask to the current position of the bitstreamBuffer - // and push the buffer pointer forwards - *(bitstreamBuffer++) = bitstreamRootNode->childMask; - - for (int j = 0; j < 8; j++) { - // make sure we have a child to visit - if (bitstreamRootNode->children[j] != NULL) { - bitstreamBuffer = loadBitstream(bitstreamBuffer, - bitstreamRootNode->children[j]); - } + if (childStopOctalCode != NULL) { + break; } } - return bitstreamBuffer; + return childStopOctalCode; } \ No newline at end of file diff --git a/shared/src/VoxelTree.h b/shared/src/VoxelTree.h index f53ff81f53..2bf6aa944e 100644 --- a/shared/src/VoxelTree.h +++ b/shared/src/VoxelTree.h @@ -20,12 +20,10 @@ public: VoxelNode *rootNode; - void addBitstreamPacketMarker(); + unsigned char * loadBitstreamBuffer(char *& bitstreamBuffer, + unsigned char * octalCode, + VoxelNode *currentVoxelNode); - void outputDebugInformation(VoxelNode *currentRootNode = NULL); - char * loadBitstream(char * bitstreamBuffer, - VoxelNode *bitstreamRootNode, - char ** curPacketSplitPtr = NULL); }; #endif /* defined(__hifi__VoxelTree__) */ diff --git a/voxel/src/main.cpp b/voxel/src/main.cpp index 523cf16572..59d38327db 100644 --- a/voxel/src/main.cpp +++ b/voxel/src/main.cpp @@ -39,12 +39,10 @@ char DOMAIN_HOSTNAME[] = "highfidelity.below92.com"; char DOMAIN_IP[100] = ""; // IP Address will be re-set by lookup on startup const int DOMAINSERVER_PORT = 40102; -const int MAX_VOXEL_TREE_DEPTH_LEVELS = 1; -const int MAX_VOXEL_BITSTREAM_BYTES = 100000; +const int MAX_VOXEL_TREE_DEPTH_LEVELS = 5; AgentList agentList(VOXEL_LISTEN_PORT); in_addr_t localAddress; -char voxelBitStream[MAX_VOXEL_BITSTREAM_BYTES]; unsigned char randomColorValue() { return MIN_BRIGHTNESS + (rand() % (255 - MIN_BRIGHTNESS)); @@ -96,8 +94,6 @@ void randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) { // give this child it's octal code currentRootNode->children[i]->octalCode = childOctalCode(currentRootNode->octalCode, i); - printf("Child node in position %d at level %d\n", i, MAX_VOXEL_TREE_DEPTH_LEVELS - levelsToGo); - // fill out the lower levels of the tree using that node as the root node randomlyFillVoxelTree(levelsToGo - 1, currentRootNode->children[i]); @@ -192,24 +188,22 @@ int main(int argc, const char * argv[]) // create an octal code buffer and load it with 0 so that the recursive tree fill can give // octal codes to the tree nodes that it is creating randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode); - - char *packetSplitsPtrs[MAX_VOXEL_BITSTREAM_BYTES / MAX_PACKET_SIZE] = {}; - + + char *voxelPacket = new char[MAX_VOXEL_PACKET_SIZE]; + char *voxelPacketEnd; // returned unsigned char * is end of last write to bitstream - char *lastPacketSplit = randomTree.loadBitstream(voxelBitStream, randomTree.rootNode, packetSplitsPtrs); + int packetCount = 0; - // set the last packet split pointer to lastPacketSplit - for (int i = 1; i < MAX_VOXEL_BITSTREAM_BYTES / MAX_PACKET_SIZE; i++) { - if (packetSplitsPtrs[i] == NULL) { - if (lastPacketSplit != NULL) { - // lastPacketSplit has not been read yet - // set this packetSplitPtr to that and set it NULL so we know it's been read - packetSplitsPtrs[i] = lastPacketSplit; - lastPacketSplit = NULL; - } else { - // no more split pointers to read, break out - break; - } + unsigned char *stopOctal = randomTree.rootNode->octalCode; + + while (true) { + voxelPacketEnd = voxelPacket; + stopOctal = randomTree.loadBitstreamBuffer(voxelPacketEnd, stopOctal, randomTree.rootNode); + + printf("Packet %d is %ld bytes\n", ++packetCount, voxelPacketEnd - voxelPacket); + + if (stopOctal == NULL) { + break; } } @@ -221,34 +215,34 @@ int main(int argc, const char * argv[]) int sentVoxels = 0; // loop to send to agents requesting data - while (true) { - if (agentList.getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) { - if (packetData[0] == 'I') { - printf("Sending voxels to agent at address %s\n", inet_ntoa(agentPublicAddress.sin_addr)); - - // send the bitstream to the client - for (int i = 1; i < MAX_VOXEL_BITSTREAM_BYTES / MAX_PACKET_SIZE; i++) { - if (packetSplitsPtrs[i] == NULL) { - // no more split pointers to read, break out - break; - } - - // figure out the number of bytes in this packet - int thisPacketBytes = packetSplitsPtrs[i] - packetSplitsPtrs[i - 1]; - - agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress, - packetSplitsPtrs[i - 1], - thisPacketBytes); - - - // output the bits in each byte of this packet - for (int j = 0; j < thisPacketBytes; j++) { - outputBits(*(packetSplitsPtrs[i - 1] + j)); - } - } - } - } - } +// while (true) { +// if (agentList.getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) { +// if (packetData[0] == 'I') { +// printf("Sending voxels to agent at address %s\n", inet_ntoa(agentPublicAddress.sin_addr)); +// +// // send the bitstream to the client +// for (int i = 1; i < MAX_VOXEL_BITSTREAM_BYTES / MAX_PACKET_SIZE; i++) { +// if (packetSplitsPtrs[i] == NULL) { +// // no more split pointers to read, break out +// break; +// } +// +// // figure out the number of bytes in this packet +// int thisPacketBytes = packetSplitsPtrs[i] - packetSplitsPtrs[i - 1]; +// +// agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress, +// packetSplitsPtrs[i - 1], +// thisPacketBytes); +// +// +// // output the bits in each byte of this packet +// for (int j = 0; j < thisPacketBytes; j++) { +// outputBits(*(packetSplitsPtrs[i - 1] + j)); +// } +// } +// } +// } +// } pthread_join(reportAliveThread, NULL);