make animation-server work with jurisdictions

This commit is contained in:
ZappoMan 2013-08-20 11:08:20 -07:00
parent 5e7e6fc9d7
commit 0f7ea55e82
10 changed files with 113 additions and 104 deletions

View file

@ -20,6 +20,7 @@
#include <JurisdictionListener.h> #include <JurisdictionListener.h>
#include <SceneUtils.h> #include <SceneUtils.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <VoxelEditPacketSender.h>
#include <VoxelTree.h> #include <VoxelTree.h>
#ifdef _WIN32 #ifdef _WIN32
@ -52,26 +53,9 @@ unsigned long bytesSent = 0;
JurisdictionListener* jurisdictionListener = NULL; JurisdictionListener* jurisdictionListener = NULL;
VoxelEditPacketSender* voxelEditPacketSender = NULL;
static void sendVoxelEditMessage(PACKET_TYPE type, VoxelDetail& detail) {
unsigned char* bufferOut;
int sizeOut;
if (createVoxelEditMessage(type, 0, 1, &detail, bufferOut, sizeOut)){
::packetsSent++;
::bytesSent += sizeOut;
if (::shouldShowPacketsPerSecond) {
printf("sending packet of size=%d\n",sizeOut);
}
NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1);
delete[] bufferOut;
}
}
glm::vec3 rotatePoint(glm::vec3 point, float angle) { glm::vec3 rotatePoint(glm::vec3 point, float angle) {
// First, create the quaternion based on this angle of rotation // First, create the quaternion based on this angle of rotation
glm::quat q(glm::vec3(0, -angle, 0)); glm::quat q(glm::vec3(0, -angle, 0));
@ -146,8 +130,6 @@ const BugPart bugParts[VOXELS_PER_BUG] = {
static void renderMovingBug() { static void renderMovingBug() {
VoxelDetail details[VOXELS_PER_BUG]; VoxelDetail details[VOXELS_PER_BUG];
unsigned char* bufferOut;
int sizeOut;
// Generate voxels for where bug used to be // Generate voxels for where bug used to be
for (int i = 0; i < VOXELS_PER_BUG; i++) { for (int i = 0; i < VOXELS_PER_BUG; i++) {
@ -168,17 +150,7 @@ static void renderMovingBug() {
// send the "erase message" first... // send the "erase message" first...
PACKET_TYPE message = PACKET_TYPE_ERASE_VOXEL; PACKET_TYPE message = PACKET_TYPE_ERASE_VOXEL;
if (createVoxelEditMessage(message, 0, VOXELS_PER_BUG, (VoxelDetail*)&details, bufferOut, sizeOut)){ ::voxelEditPacketSender->queueVoxelEditMessages(message, VOXELS_PER_BUG, (VoxelDetail*)&details);
::packetsSent++;
::bytesSent += sizeOut;
if (::shouldShowPacketsPerSecond) {
printf("sending packet of size=%d\n", sizeOut);
}
NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1);
delete[] bufferOut;
}
// Move the bug... // Move the bug...
if (moveBugInLine) { if (moveBugInLine) {
@ -238,17 +210,7 @@ static void renderMovingBug() {
// send the "create message" ... // send the "create message" ...
message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE;
if (createVoxelEditMessage(message, 0, VOXELS_PER_BUG, (VoxelDetail*)&details, bufferOut, sizeOut)){ ::voxelEditPacketSender->queueVoxelEditMessages(message, VOXELS_PER_BUG, (VoxelDetail*)&details);
::packetsSent++;
::bytesSent += sizeOut;
if (::shouldShowPacketsPerSecond) {
printf("sending packet of size=%d\n", sizeOut);
}
NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1);
delete[] bufferOut;
}
} }
@ -284,7 +246,7 @@ static void sendVoxelBlinkMessage() {
PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE;
sendVoxelEditMessage(message, detail); ::voxelEditPacketSender->sendVoxelEditMessage(message, detail);
} }
bool stringOfLightsInitialized = false; bool stringOfLightsInitialized = false;
@ -302,8 +264,6 @@ static void sendBlinkingStringOfLights() {
PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully! PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully!
float lightScale = STRING_OF_LIGHTS_SIZE; float lightScale = STRING_OF_LIGHTS_SIZE;
static VoxelDetail details[LIGHTS_PER_SEGMENT]; static VoxelDetail details[LIGHTS_PER_SEGMENT];
unsigned char* bufferOut;
int sizeOut;
// first initialized the string of lights if needed... // first initialized the string of lights if needed...
if (!stringOfLightsInitialized) { if (!stringOfLightsInitialized) {
@ -343,19 +303,7 @@ static void sendBlinkingStringOfLights() {
details[indexInSegment].blue = offColor[2]; details[indexInSegment].blue = offColor[2];
} }
// send entire segment at once ::voxelEditPacketSender->queueVoxelEditMessages(message, LIGHTS_PER_SEGMENT, (VoxelDetail*)&details);
if (createVoxelEditMessage(message, 0, LIGHTS_PER_SEGMENT, (VoxelDetail*)&details, bufferOut, sizeOut)){
::packetsSent++;
::bytesSent += sizeOut;
if (::shouldShowPacketsPerSecond) {
printf("sending packet of size=%d\n",sizeOut);
}
NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1);
delete[] bufferOut;
}
} }
stringOfLightsInitialized = true; stringOfLightsInitialized = true;
} else { } else {
@ -386,17 +334,7 @@ static void sendBlinkingStringOfLights() {
details[1].blue = onColor[2]; details[1].blue = onColor[2];
// send both changes in same message // send both changes in same message
if (createVoxelEditMessage(message, 0, 2, (VoxelDetail*)&details, bufferOut, sizeOut)){ ::voxelEditPacketSender->queueVoxelEditMessages(message, 2, (VoxelDetail*)&details);
::packetsSent++;
::bytesSent += sizeOut;
if (::shouldShowPacketsPerSecond) {
printf("sending packet of size=%d\n",sizeOut);
}
NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1);
delete[] bufferOut;
}
} }
} }
@ -432,8 +370,6 @@ void sendDanceFloor() {
PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully! PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully!
float lightScale = DANCE_FLOOR_LIGHT_SIZE; float lightScale = DANCE_FLOOR_LIGHT_SIZE;
static VoxelDetail details[DANCE_FLOOR_VOXELS_PER_PACKET]; static VoxelDetail details[DANCE_FLOOR_VOXELS_PER_PACKET];
unsigned char* bufferOut;
int sizeOut;
// first initialized the billboard of lights if needed... // first initialized the billboard of lights if needed...
if (!::danceFloorInitialized) { if (!::danceFloorInitialized) {
@ -510,16 +446,7 @@ void sendDanceFloor() {
} }
if (item == DANCE_FLOOR_VOXELS_PER_PACKET - 1) { if (item == DANCE_FLOOR_VOXELS_PER_PACKET - 1) {
if (createVoxelEditMessage(message, 0, DANCE_FLOOR_VOXELS_PER_PACKET, ::voxelEditPacketSender->queueVoxelEditMessages(message, DANCE_FLOOR_VOXELS_PER_PACKET, (VoxelDetail*)&details);
(VoxelDetail*)&details, bufferOut, sizeOut)){
::packetsSent++;
::bytesSent += sizeOut;
if (::shouldShowPacketsPerSecond) {
printf("sending packet of size=%d\n", sizeOut);
}
NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1);
delete[] bufferOut;
}
} }
} }
} }
@ -559,8 +486,6 @@ static void sendBillboard() {
PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully! PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully!
float lightScale = BILLBOARD_LIGHT_SIZE; float lightScale = BILLBOARD_LIGHT_SIZE;
static VoxelDetail details[VOXELS_PER_PACKET]; static VoxelDetail details[VOXELS_PER_PACKET];
unsigned char* bufferOut;
int sizeOut;
// first initialized the billboard of lights if needed... // first initialized the billboard of lights if needed...
if (!billboardInitialized) { if (!billboardInitialized) {
@ -608,15 +533,7 @@ static void sendBillboard() {
} }
if (item == VOXELS_PER_PACKET - 1) { if (item == VOXELS_PER_PACKET - 1) {
if (createVoxelEditMessage(message, 0, VOXELS_PER_PACKET, (VoxelDetail*)&details, bufferOut, sizeOut)){ ::voxelEditPacketSender->queueVoxelEditMessages(message, VOXELS_PER_PACKET, (VoxelDetail*)&details);
::packetsSent++;
::bytesSent += sizeOut;
if (::shouldShowPacketsPerSecond) {
printf("sending packet of size=%d\n", sizeOut);
}
NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1);
delete[] bufferOut;
}
} }
} }
} }
@ -639,8 +556,6 @@ void doBuildStreet() {
PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully! PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully!
static VoxelDetail details[BRICKS_PER_PACKET]; static VoxelDetail details[BRICKS_PER_PACKET];
unsigned char* bufferOut;
int sizeOut;
for (int z = 0; z < ROAD_LENGTH; z++) { for (int z = 0; z < ROAD_LENGTH; z++) {
for (int x = 0; x < ROAD_WIDTH; x++) { for (int x = 0; x < ROAD_WIDTH; x++) {
@ -661,15 +576,7 @@ void doBuildStreet() {
details[item].blue = randomTone; details[item].blue = randomTone;
if (item == BRICKS_PER_PACKET - 1) { if (item == BRICKS_PER_PACKET - 1) {
if (createVoxelEditMessage(message, 0, BRICKS_PER_PACKET, (VoxelDetail*)&details, bufferOut, sizeOut)){ ::voxelEditPacketSender->queueVoxelEditMessages(message, BRICKS_PER_PACKET, (VoxelDetail*)&details);
::packetsSent++;
::bytesSent += sizeOut;
if (true || ::shouldShowPacketsPerSecond) {
printf("building road sending packet of size=%d\n", sizeOut);
}
NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1);
delete[] bufferOut;
}
} }
} }
} }
@ -710,6 +617,10 @@ void* animateVoxels(void* args) {
doBuildStreet(); doBuildStreet();
} }
if (::voxelEditPacketSender) {
::voxelEditPacketSender->flushQueue();
}
uint64_t end = usecTimestampNow(); uint64_t end = usecTimestampNow();
uint64_t elapsedSeconds = (end - ::start) / 1000000; uint64_t elapsedSeconds = (end - ::start) / 1000000;
if (::shouldShowPacketsPerSecond) { if (::shouldShowPacketsPerSecond) {
@ -788,6 +699,15 @@ int main(int argc, const char * argv[])
::jurisdictionListener->initialize(true); ::jurisdictionListener->initialize(true);
} }
// Create out VoxelEditPacketSender
::voxelEditPacketSender = new VoxelEditPacketSender;
if (::voxelEditPacketSender) {
::voxelEditPacketSender->initialize(true);
if (::jurisdictionListener) {
::voxelEditPacketSender->setVoxelServerJurisdictions(::jurisdictionListener->getJurisdictions());
}
}
srand((unsigned)time(0)); srand((unsigned)time(0));
pthread_t animateVoxelThread; pthread_t animateVoxelThread;
@ -829,5 +749,10 @@ int main(int argc, const char * argv[])
delete ::jurisdictionListener; delete ::jurisdictionListener;
} }
if (::voxelEditPacketSender) {
::voxelEditPacketSender->terminate();
delete ::voxelEditPacketSender;
}
return 0; return 0;
} }

View file

@ -255,6 +255,38 @@ bool createVoxelEditMessage(unsigned char command, short int sequence,
return success; return success;
} }
/// encodes the voxel details portion of a voxel edit message
bool encodeVoxelEditMessageDetails(unsigned char command, int voxelCount, VoxelDetail* voxelDetails,
unsigned char* bufferOut, int sizeIn, int& sizeOut) {
bool success = true; // assume the best
unsigned char* copyAt = bufferOut;
sizeOut = 0;
for (int i = 0; i < voxelCount && success; i++) {
// get the coded voxel
unsigned char* voxelData = pointToVoxel(voxelDetails[i].x,voxelDetails[i].y,voxelDetails[i].z,
voxelDetails[i].s,voxelDetails[i].red,voxelDetails[i].green,voxelDetails[i].blue);
int lengthOfVoxelData = bytesRequiredForCodeLength(*voxelData)+SIZE_OF_COLOR_DATA;
// make sure we have room to copy this voxel
if (sizeOut + lengthOfVoxelData > sizeIn) {
success = false;
} else {
// add it to our message
memcpy(copyAt, voxelData, lengthOfVoxelData);
copyAt += lengthOfVoxelData;
sizeOut += lengthOfVoxelData;
}
// cleanup
delete[] voxelData;
}
return success;
}
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Function: pointToVoxel() // Function: pointToVoxel()
// Description: Given a universal point with location x,y,z this will return the voxel // Description: Given a universal point with location x,y,z this will return the voxel

View file

@ -81,9 +81,15 @@ struct VoxelDetail {
}; };
unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r = 0, unsigned char g = 0, unsigned char b = 0); unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r = 0, unsigned char g = 0, unsigned char b = 0);
// Creates a full Voxel edit message, including command header, sequence, and details
bool createVoxelEditMessage(unsigned char command, short int sequence, bool createVoxelEditMessage(unsigned char command, short int sequence,
int voxelCount, VoxelDetail* voxelDetails, unsigned char*& bufferOut, int& sizeOut); int voxelCount, VoxelDetail* voxelDetails, unsigned char*& bufferOut, int& sizeOut);
/// encodes the voxel details portion of a voxel edit message
bool encodeVoxelEditMessageDetails(unsigned char command, int voxelCount, VoxelDetail* voxelDetails,
unsigned char* bufferOut, int sizeIn, int& sizeOut);
#ifdef _WIN32 #ifdef _WIN32
void usleep(int waitTime); void usleep(int waitTime);
#endif #endif

View file

@ -48,13 +48,19 @@ bool JurisdictionListener::queueJurisdictionRequest() {
} }
void JurisdictionListener::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { void JurisdictionListener::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
printf("processPacket()\n");
if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION) { if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION) {
printf("processPacket()... PACKET_TYPE_VOXEL_JURISDICTION\n");
Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress);
if (node) { if (node) {
uint16_t nodeID = node->getNodeID(); uint16_t nodeID = node->getNodeID();
JurisdictionMap map; JurisdictionMap map;
map.unpackFromMessage(packetData, packetLength); map.unpackFromMessage(packetData, packetLength);
_jurisdictions[nodeID] = map; _jurisdictions[nodeID] = map;
qDebug() << "Got a new map...\n";
map.displayDebugDetails();
} }
} }
} }

View file

@ -27,7 +27,7 @@ public:
JurisdictionListener(PacketSenderNotify* notify = NULL); JurisdictionListener(PacketSenderNotify* notify = NULL);
virtual bool process(); virtual bool process();
const NodeToJurisdictionMap& getJurisdictions() const { return _jurisdictions; }; NodeToJurisdictionMap* getJurisdictions() { return &_jurisdictions; };
protected: protected:
/// Callback for processing of received packets. Will process any queued PACKET_TYPE_VOXEL_JURISDICTION and update the /// Callback for processing of received packets. Will process any queued PACKET_TYPE_VOXEL_JURISDICTION and update the

View file

@ -9,6 +9,7 @@
#include <QtCore/QSettings> #include <QtCore/QSettings>
#include <QtCore/QString> #include <QtCore/QString>
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QDebug>
#include <PacketHeaders.h> #include <PacketHeaders.h>
@ -181,6 +182,18 @@ bool JurisdictionMap::readFromFile(const char* filename) {
return true; return true;
} }
void JurisdictionMap::displayDebugDetails() {
QString rootNodeValue = octalCodeToHexString(_rootOctalCode);
qDebug() << "root:" << rootNodeValue << "\n";
for (int i = 0; i < _endNodes.size(); i++) {
QString value = octalCodeToHexString(_endNodes[i]);
qDebug() << "End node[" << i << "]: " << rootNodeValue << "\n";
}
}
bool JurisdictionMap::writeToFile(const char* filename) { bool JurisdictionMap::writeToFile(const char* filename) {
QString settingsFile(filename); QString settingsFile(filename);
QSettings settings(settingsFile, QSettings::IniFormat); QSettings settings(settingsFile, QSettings::IniFormat);

View file

@ -53,6 +53,8 @@ public:
int unpackFromMessage(unsigned char* sourceBuffer, int availableBytes); int unpackFromMessage(unsigned char* sourceBuffer, int availableBytes);
int packIntoMessage(unsigned char* destinationBuffer, int availableBytes); int packIntoMessage(unsigned char* destinationBuffer, int availableBytes);
void displayDebugDetails();
private: private:
void copyContents(const JurisdictionMap& other); // use assignment instead void copyContents(const JurisdictionMap& other); // use assignment instead

View file

@ -25,6 +25,7 @@ JurisdictionSender::JurisdictionSender(JurisdictionMap* map, PacketSenderNotify*
void JurisdictionSender::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { void JurisdictionSender::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) { if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
printf("processPacket()... PACKET_TYPE_VOXEL_JURISDICTION_REQUEST\n");
Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress);
if (node) { if (node) {
uint16_t nodeID = node->getNodeID(); uint16_t nodeID = node->getNodeID();
@ -59,6 +60,9 @@ bool JurisdictionSender::process() {
if (node->getActiveSocket() != NULL) { if (node->getActiveSocket() != NULL) {
sockaddr* nodeAddress = node->getActiveSocket(); sockaddr* nodeAddress = node->getActiveSocket();
printf("JurisdictionSender::process()... queuePacketForSending(PACKET_TYPE_VOXEL_JURISDICTION)\n");
queuePacketForSending(*nodeAddress, bufferOut, sizeOut); queuePacketForSending(*nodeAddress, bufferOut, sizeOut);
nodeCount++; nodeCount++;
// remove it from the set // remove it from the set
@ -68,6 +72,8 @@ bool JurisdictionSender::process() {
// set our packets per second to be the number of nodes // set our packets per second to be the number of nodes
setPacketsPerSecond(nodeCount); setPacketsPerSecond(nodeCount);
} else {
printf("JurisdictionSender::process()... no jurisdiction!!!\n");
} }
continueProcessing = PacketSender::process(); continueProcessing = PacketSender::process();

View file

@ -48,6 +48,21 @@ void VoxelEditPacketSender::actuallySendMessage(uint16_t nodeID, unsigned char*
} }
} }
void VoxelEditPacketSender::queueVoxelEditMessages(PACKET_TYPE type, int numberOfDetails, VoxelDetail* details) {
if (!_shouldSend) {
return; // bail early
}
for (int i = 0; i < numberOfDetails; i++) {
static unsigned char bufferOut[MAX_PACKET_SIZE];
int sizeOut = 0;
if (encodeVoxelEditMessageDetails(type, 1, &details[i], &bufferOut[0], MAX_PACKET_SIZE, sizeOut)) {
queueVoxelEditMessage(type, bufferOut, sizeOut);
}
}
}
void VoxelEditPacketSender::queueVoxelEditMessage(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length) { void VoxelEditPacketSender::queueVoxelEditMessage(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length) {
if (!_shouldSend) { if (!_shouldSend) {

View file

@ -37,6 +37,10 @@ public:
/// node or nodes the packet should be sent to. /// node or nodes the packet should be sent to.
void queueVoxelEditMessage(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length); void queueVoxelEditMessage(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length);
/// Queues an array of several voxel edit messages. Will potentially send a pending multi-command packet. Determines
/// which voxel-server node or nodes the packet should be sent to.
void queueVoxelEditMessages(PACKET_TYPE type, int numberOfDetails, VoxelDetail* details);
/// flushes all queued packets for all nodes /// flushes all queued packets for all nodes
void flushQueue(); void flushQueue();