From 8ec5298c4af4f8e473cc83756d82ed03a2d3dc10 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 22 Mar 2013 12:01:30 -0700 Subject: [PATCH] add groundwork for LOD specific transmissions from VS --- shared/src/AgentList.h | 4 +-- shared/src/VoxelTree.cpp | 60 +++++++++++++++++++++---------- shared/src/VoxelTree.h | 6 ++-- voxel/src/VoxelAgentData.cpp | 4 +-- voxel/src/VoxelAgentData.h | 2 +- voxel/src/main.cpp | 70 +++++++++++++++++++++++------------- 6 files changed, 96 insertions(+), 50 deletions(-) diff --git a/shared/src/AgentList.h b/shared/src/AgentList.h index 18dc8945da..954bdfc334 100644 --- a/shared/src/AgentList.h +++ b/shared/src/AgentList.h @@ -36,6 +36,7 @@ class AgentList { UDPSocket& getAgentSocket(); int updateList(unsigned char *packetData, size_t dataBytes); + int indexOfMatchingAgent(sockaddr *senderAddress); bool addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType); void processAgentData(sockaddr *senderAddress, void *packetData, size_t dataBytes); void updateAgentWithData(sockaddr *senderAddress, void *packetData, size_t dataBytes); @@ -48,8 +49,7 @@ class AgentList { UDPSocket agentSocket; std::vector agents; pthread_t removeSilentAgentsThread; - - int indexOfMatchingAgent(sockaddr *senderAddress); + void handlePingReply(sockaddr *agentAddress); }; diff --git a/shared/src/VoxelTree.cpp b/shared/src/VoxelTree.cpp index bde83ec067..200c7f89ae 100644 --- a/shared/src/VoxelTree.cpp +++ b/shared/src/VoxelTree.cpp @@ -7,6 +7,7 @@ // #include +#include #include "SharedUtil.h" #include "OctalCode.h" #include "VoxelTree.h" @@ -27,6 +28,22 @@ VoxelTree::~VoxelTree() { } } +int VoxelTree::levelForViewerPosition(float *position) { + // get the distance to the viewer + // for now the voxel tree starts at 0,0,0 + float distance = sqrtf(powf(position[0] + 30, 2) + powf(position[2] + 30, 2)); + + // go through the if else branch to return the right level + // this is a gross way to do this for now for a friday demo + if (distance >= 50) { + return 3; + } else if (distance >= 20) { + return 4; + } else { + return 5; + } +} + VoxelNode * VoxelTree::nodeForOctalCode(VoxelNode *ancestorNode, unsigned char * needleCode) { // find the appropriate branch index based on this ancestorNode if (*needleCode == 0) { @@ -135,7 +152,8 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, int bufferSizeByt unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, unsigned char * stopOctalCode, - VoxelNode *currentVoxelNode) + VoxelNode *currentVoxelNode, + int deepestLevel) { static unsigned char *initialBitstreamPos = bitstreamBuffer; @@ -188,7 +206,9 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, // copy the childMask to the current position of the bitstreamBuffer // and push the buffer pointer forwards - *(bitstreamBuffer++) = currentVoxelNode->childMask; + *(bitstreamBuffer++) = *currentVoxelNode->octalCode < deepestLevel + ? currentVoxelNode->childMask + : 0; } else { firstIndexToCheck = *stopOctalCode > 0 ? branchIndexWithDescendant(currentVoxelNode->octalCode, stopOctalCode) @@ -197,26 +217,28 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, 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 { - if (oneAtBit(currentVoxelNode->childMask, i)) { - childStopOctalCode = loadBitstreamBuffer(bitstreamBuffer, stopOctalCode, currentVoxelNode->children[i]); + if (*currentVoxelNode->octalCode < deepestLevel) { + 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 { - childStopOctalCode = NULL; + if (oneAtBit(currentVoxelNode->childMask, i)) { + childStopOctalCode = loadBitstreamBuffer(bitstreamBuffer, stopOctalCode, currentVoxelNode->children[i], deepestLevel); + } else { + childStopOctalCode = NULL; + } } } - } - - if (childStopOctalCode != NULL) { - break; + + if (childStopOctalCode != NULL) { + break; + } } } diff --git a/shared/src/VoxelTree.h b/shared/src/VoxelTree.h index a7ea8e3275..e69b12a910 100644 --- a/shared/src/VoxelTree.h +++ b/shared/src/VoxelTree.h @@ -24,10 +24,12 @@ public: VoxelNode *rootNode; + int levelForViewerPosition(float * position); void readBitstreamToTree(unsigned char * bitstream, int bufferSizeBytes); unsigned char * loadBitstreamBuffer(unsigned char *& bitstreamBuffer, - unsigned char * octalCode, - VoxelNode *currentVoxelNode); + unsigned char * octalCode, + VoxelNode *currentVoxelNode, + int deepestLevel); void printTreeForDebugging(VoxelNode *startNode); }; diff --git a/voxel/src/VoxelAgentData.cpp b/voxel/src/VoxelAgentData.cpp index 0bd5345973..7f7d5727b5 100644 --- a/voxel/src/VoxelAgentData.cpp +++ b/voxel/src/VoxelAgentData.cpp @@ -9,7 +9,7 @@ #include "VoxelAgentData.h" VoxelAgentData::VoxelAgentData() { - lastSeenLevel = 0; + lastSentLevel = 0; } VoxelAgentData::~VoxelAgentData() { @@ -17,7 +17,7 @@ VoxelAgentData::~VoxelAgentData() { } VoxelAgentData::VoxelAgentData(const VoxelAgentData &otherAgentData) { - lastSeenLevel = otherAgentData.lastSeenLevel; + lastSentLevel = otherAgentData.lastSentLevel; memcpy(position, otherAgentData.position, sizeof(float) * 3); } diff --git a/voxel/src/VoxelAgentData.h b/voxel/src/VoxelAgentData.h index 64e8230c84..6d66d06013 100644 --- a/voxel/src/VoxelAgentData.h +++ b/voxel/src/VoxelAgentData.h @@ -15,7 +15,7 @@ class VoxelAgentData : public AgentData { public: float position[3]; - int lastSeenLevel; + int lastSentLevel; VoxelAgentData(); ~VoxelAgentData(); diff --git a/voxel/src/main.cpp b/voxel/src/main.cpp index 3ff65d9ec5..6427e73454 100644 --- a/voxel/src/main.cpp +++ b/voxel/src/main.cpp @@ -14,6 +14,8 @@ #include #include #include +#include "VoxelAgentData.h" +#include #ifdef _WIN32 #include "Syssocket.h" @@ -41,7 +43,7 @@ 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 = 4; +const int MAX_VOXEL_TREE_DEPTH_LEVELS = 6; AgentList agentList(VOXEL_LISTEN_PORT); in_addr_t localAddress; @@ -85,7 +87,7 @@ int randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) { createdChildren = false; for (int i = 0; i < 8; i++) { - if (randomBoolean() || levelsToGo == MAX_VOXEL_TREE_DEPTH_LEVELS) { + if (((i == 0 || i == 1 | i == 4 | i == 5) && (randomBoolean() || levelsToGo != 1)) ) { // create a new VoxelNode to put here currentRootNode->children[i] = new VoxelNode(); @@ -129,6 +131,13 @@ int randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) { } } +void attachVoxelAgentDataToAgent(Agent *newAgent) { + if (newAgent->getLinkedData() == NULL) { + newAgent->setLinkedData(new VoxelAgentData()); + } +} + + int main(int argc, const char * argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); @@ -168,6 +177,8 @@ int main(int argc, const char * argv[]) pthread_t reportAliveThread; pthread_create(&reportAliveThread, NULL, reportAliveToDS, NULL); + agentList.linkedDataCreateCallback = &attachVoxelAgentDataToAgent; + srand((unsigned)time(0)); // use our method to create a random voxel tree @@ -184,34 +195,45 @@ int main(int argc, const char * argv[]) int packetCount; int totalBytesSent; - sockaddr_in agentPublicAddress; - + sockaddr agentPublicAddress; + char *packetData = new char[MAX_PACKET_SIZE]; ssize_t receivedBytes; // loop to send to agents requesting data while (true) { - if (agentList.getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) { - if (packetData[0] == 'I') { - stopOctal = randomTree.rootNode->octalCode; - packetCount = 0; - - while (stopOctal != NULL) { - voxelPacketEnd = voxelPacket; - stopOctal = randomTree.loadBitstreamBuffer(voxelPacketEnd, stopOctal, randomTree.rootNode); - - agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress, - voxelPacket, - voxelPacketEnd - voxelPacket); - - packetCount++; - totalBytesSent += voxelPacketEnd - voxelPacket; + if (agentList.getAgentSocket().receive(&agentPublicAddress, packetData, &receivedBytes)) { + if (packetData[0] == 'H') { + agentList.addOrUpdateAgent(&agentPublicAddress, &agentPublicAddress, packetData[0]); + agentList.updateAgentWithData(&agentPublicAddress, (void *)packetData, receivedBytes); + + VoxelAgentData *agentData = (VoxelAgentData *) agentList.getAgents()[agentList.indexOfMatchingAgent(&agentPublicAddress)].getLinkedData(); + int newLevel = 6; + if (newLevel > agentData->lastSentLevel) { + // the agent has already received a deeper level than this from us + // do nothing + + stopOctal = randomTree.rootNode->octalCode; + packetCount = 0; + totalBytesSent = 0; + + while (stopOctal != NULL) { + voxelPacketEnd = voxelPacket; + stopOctal = randomTree.loadBitstreamBuffer(voxelPacketEnd, + stopOctal, + randomTree.rootNode, + newLevel); + + agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress, + voxelPacket, + voxelPacketEnd - voxelPacket); + + packetCount++; + totalBytesSent += voxelPacketEnd - voxelPacket; + } + + agentData->lastSentLevel = newLevel; } - - printf("%d packets sent to agent %s totalling %d bytes\n", - packetCount, - inet_ntoa(agentPublicAddress.sin_addr), - totalBytesSent); } } }