mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 02:36:54 +02:00
Merge pull request #950 from ZappoMan/multi_VS_assigments
Make VoxelServer class run as multiple instances
This commit is contained in:
commit
b6548303d1
15 changed files with 305 additions and 237 deletions
|
@ -100,7 +100,6 @@ void childClient() {
|
||||||
|
|
||||||
// run the deployed assignment
|
// run the deployed assignment
|
||||||
deployedAssignment->run();
|
deployedAssignment->run();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
qDebug("Received a bad destination socket for assignment.\n");
|
qDebug("Received a bad destination socket for assignment.\n");
|
||||||
}
|
}
|
||||||
|
@ -154,6 +153,7 @@ void sigchldHandler(int sig) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parentMonitor() {
|
void parentMonitor() {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QMap>
|
||||||
#include <QtCore/QMutex>
|
#include <QtCore/QMutex>
|
||||||
|
|
||||||
#include <civetweb.h>
|
#include <civetweb.h>
|
||||||
|
@ -58,7 +59,7 @@ unsigned char* addNodeToBroadcastPacket(unsigned char* currentPosition, Node* no
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mongooseRequestHandler(struct mg_connection *conn) {
|
static int mongooseRequestHandler(struct mg_connection *conn) {
|
||||||
const struct mg_request_info *ri = mg_get_request_info(conn);
|
const struct mg_request_info* ri = mg_get_request_info(conn);
|
||||||
|
|
||||||
if (strcmp(ri->uri, "/assignment") == 0 && strcmp(ri->request_method, "POST") == 0) {
|
if (strcmp(ri->uri, "/assignment") == 0 && strcmp(ri->request_method, "POST") == 0) {
|
||||||
// return a 200
|
// return a 200
|
||||||
|
@ -131,7 +132,7 @@ int main(int argc, const char* argv[]) {
|
||||||
in_addr_t serverLocalAddress = getLocalAddress();
|
in_addr_t serverLocalAddress = getLocalAddress();
|
||||||
|
|
||||||
nodeList->startSilentNodeRemovalThread();
|
nodeList->startSilentNodeRemovalThread();
|
||||||
|
|
||||||
timeval lastStatSendTime = {};
|
timeval lastStatSendTime = {};
|
||||||
const char ASSIGNMENT_SERVER_OPTION[] = "-a";
|
const char ASSIGNMENT_SERVER_OPTION[] = "-a";
|
||||||
|
|
||||||
|
@ -159,6 +160,15 @@ int main(int argc, const char* argv[]) {
|
||||||
Assignment voxelServerAssignment(Assignment::CreateCommand,
|
Assignment voxelServerAssignment(Assignment::CreateCommand,
|
||||||
Assignment::VoxelServerType,
|
Assignment::VoxelServerType,
|
||||||
Assignment::LocalLocation);
|
Assignment::LocalLocation);
|
||||||
|
|
||||||
|
// Handle Domain/Voxel Server configuration command line arguments
|
||||||
|
const char VOXEL_CONFIG_OPTION[] = "--voxelServerConfig";
|
||||||
|
const char* voxelServerConfig = getCmdOption(argc, argv, VOXEL_CONFIG_OPTION);
|
||||||
|
if (voxelServerConfig) {
|
||||||
|
qDebug("Reading Voxel Server Configuration.\n");
|
||||||
|
qDebug() << " config: " << voxelServerConfig << "\n";
|
||||||
|
voxelServerAssignment.setPayload((uchar*)voxelServerConfig, strlen(voxelServerConfig) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
// construct a local socket to send with our created assignments to the global AS
|
// construct a local socket to send with our created assignments to the global AS
|
||||||
sockaddr_in localSocket = {};
|
sockaddr_in localSocket = {};
|
||||||
|
@ -167,13 +177,13 @@ int main(int argc, const char* argv[]) {
|
||||||
localSocket.sin_addr.s_addr = serverLocalAddress;
|
localSocket.sin_addr.s_addr = serverLocalAddress;
|
||||||
|
|
||||||
// setup the mongoose web server
|
// setup the mongoose web server
|
||||||
struct mg_context *ctx;
|
struct mg_context* ctx;
|
||||||
struct mg_callbacks callbacks = {};
|
struct mg_callbacks callbacks = {};
|
||||||
|
|
||||||
QString documentRoot = QString("%1/resources/web").arg(QCoreApplication::applicationDirPath());
|
QString documentRoot = QString("%1/resources/web").arg(QCoreApplication::applicationDirPath());
|
||||||
|
|
||||||
// list of options. Last element must be NULL.
|
// list of options. Last element must be NULL.
|
||||||
const char *options[] = {"listening_ports", "8080",
|
const char* options[] = {"listening_ports", "8080",
|
||||||
"document_root", documentRoot.toStdString().c_str(), NULL};
|
"document_root", documentRoot.toStdString().c_str(), NULL};
|
||||||
|
|
||||||
callbacks.begin_request = mongooseRequestHandler;
|
callbacks.begin_request = mongooseRequestHandler;
|
||||||
|
@ -214,10 +224,9 @@ int main(int argc, const char* argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const int MIN_VOXEL_SERVER_CHECKS = 10;
|
const int MIN_VOXEL_SERVER_CHECKS = 10;
|
||||||
if (checkForVoxelServerAttempt > MIN_VOXEL_SERVER_CHECKS &&
|
if (checkForVoxelServerAttempt > MIN_VOXEL_SERVER_CHECKS && voxelServerCount == 0 &&
|
||||||
voxelServerCount == 0 &&
|
|
||||||
std::find(::assignmentQueue.begin(), ::assignmentQueue.end(), &voxelServerAssignment) == ::assignmentQueue.end()) {
|
std::find(::assignmentQueue.begin(), ::assignmentQueue.end(), &voxelServerAssignment) == ::assignmentQueue.end()) {
|
||||||
qDebug("Missing a Voxel Server and assignment not in queue. Adding.\n");
|
qDebug("Missing a voxel server and assignment not in queue. Adding.\n");
|
||||||
::assignmentQueue.push_front(&voxelServerAssignment);
|
::assignmentQueue.push_front(&voxelServerAssignment);
|
||||||
}
|
}
|
||||||
checkForVoxelServerAttempt++;
|
checkForVoxelServerAttempt++;
|
||||||
|
|
|
@ -165,12 +165,10 @@ int Assignment::packToBuffer(unsigned char* buffer) {
|
||||||
|
|
||||||
numPackedBytes += packSocket(buffer + numPackedBytes, socketToPack);
|
numPackedBytes += packSocket(buffer + numPackedBytes, socketToPack);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_numPayloadBytes) {
|
if (_numPayloadBytes) {
|
||||||
memcpy(buffer + numPackedBytes, _payload, _numPayloadBytes);
|
memcpy(buffer + numPackedBytes, _payload, _numPayloadBytes);
|
||||||
numPackedBytes += _numPayloadBytes;
|
numPackedBytes += _numPayloadBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
return numPackedBytes;
|
return numPackedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ public:
|
||||||
|
|
||||||
const sockaddr* getAttachedLocalSocket() { return _attachedLocalSocket; }
|
const sockaddr* getAttachedLocalSocket() { return _attachedLocalSocket; }
|
||||||
void setAttachedLocalSocket(const sockaddr* attachedLocalSocket);
|
void setAttachedLocalSocket(const sockaddr* attachedLocalSocket);
|
||||||
|
|
||||||
/// Packs the assignment to the passed buffer
|
/// Packs the assignment to the passed buffer
|
||||||
/// \param buffer the buffer in which to pack the assignment
|
/// \param buffer the buffer in which to pack the assignment
|
||||||
/// \return number of bytes packed into buffer
|
/// \return number of bytes packed into buffer
|
||||||
|
|
|
@ -28,14 +28,17 @@ VoxelNodeData::VoxelNodeData(Node* owningNode) :
|
||||||
_voxelPacket = new unsigned char[MAX_VOXEL_PACKET_SIZE];
|
_voxelPacket = new unsigned char[MAX_VOXEL_PACKET_SIZE];
|
||||||
_voxelPacketAt = _voxelPacket;
|
_voxelPacketAt = _voxelPacket;
|
||||||
resetVoxelPacket();
|
resetVoxelPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelNodeData::initializeVoxelSendThread(VoxelServer* voxelServer) {
|
||||||
// Create voxel sending thread...
|
// Create voxel sending thread...
|
||||||
uint16_t nodeID = getOwningNode()->getNodeID();
|
uint16_t nodeID = getOwningNode()->getNodeID();
|
||||||
_voxelSendThread = new VoxelSendThread(nodeID);
|
_voxelSendThread = new VoxelSendThread(nodeID, voxelServer);
|
||||||
_voxelSendThread->initialize(true);
|
_voxelSendThread->initialize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void VoxelNodeData::resetVoxelPacket() {
|
void VoxelNodeData::resetVoxelPacket() {
|
||||||
// If we're moving, and the client asked for low res, then we force monochrome, otherwise, use
|
// If we're moving, and the client asked for low res, then we force monochrome, otherwise, use
|
||||||
// the clients requested color state.
|
// the clients requested color state.
|
||||||
|
@ -57,8 +60,10 @@ void VoxelNodeData::writeToPacket(unsigned char* buffer, int bytes) {
|
||||||
VoxelNodeData::~VoxelNodeData() {
|
VoxelNodeData::~VoxelNodeData() {
|
||||||
delete[] _voxelPacket;
|
delete[] _voxelPacket;
|
||||||
|
|
||||||
_voxelSendThread->terminate();
|
if (_voxelSendThread) {
|
||||||
delete _voxelSendThread;
|
_voxelSendThread->terminate();
|
||||||
|
delete _voxelSendThread;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VoxelNodeData::updateCurrentViewFrustum() {
|
bool VoxelNodeData::updateCurrentViewFrustum() {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <VoxelSceneStats.h>
|
#include <VoxelSceneStats.h>
|
||||||
|
|
||||||
class VoxelSendThread;
|
class VoxelSendThread;
|
||||||
|
class VoxelServer;
|
||||||
|
|
||||||
class VoxelNodeData : public AvatarData {
|
class VoxelNodeData : public AvatarData {
|
||||||
public:
|
public:
|
||||||
|
@ -65,6 +66,9 @@ public:
|
||||||
|
|
||||||
VoxelSceneStats stats;
|
VoxelSceneStats stats;
|
||||||
|
|
||||||
|
void initializeVoxelSendThread(VoxelServer* voxelServer);
|
||||||
|
bool isVoxelSendThreadInitalized() { return _voxelSendThread; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VoxelNodeData(const VoxelNodeData &);
|
VoxelNodeData(const VoxelNodeData &);
|
||||||
VoxelNodeData& operator= (const VoxelNodeData&);
|
VoxelNodeData& operator= (const VoxelNodeData&);
|
||||||
|
|
|
@ -16,10 +16,11 @@ extern EnvironmentData environmentData[3];
|
||||||
|
|
||||||
#include "VoxelSendThread.h"
|
#include "VoxelSendThread.h"
|
||||||
#include "VoxelServer.h"
|
#include "VoxelServer.h"
|
||||||
#include "VoxelServerState.h"
|
#include "VoxelServerConsts.h"
|
||||||
|
|
||||||
VoxelSendThread::VoxelSendThread(uint16_t nodeID) :
|
VoxelSendThread::VoxelSendThread(uint16_t nodeID, VoxelServer* myServer) :
|
||||||
_nodeID(nodeID) {
|
_nodeID(nodeID),
|
||||||
|
_myServer(myServer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VoxelSendThread::process() {
|
bool VoxelSendThread::process() {
|
||||||
|
@ -35,7 +36,7 @@ bool VoxelSendThread::process() {
|
||||||
// Sometimes the node data has not yet been linked, in which case we can't really do anything
|
// Sometimes the node data has not yet been linked, in which case we can't really do anything
|
||||||
if (nodeData) {
|
if (nodeData) {
|
||||||
bool viewFrustumChanged = nodeData->updateCurrentViewFrustum();
|
bool viewFrustumChanged = nodeData->updateCurrentViewFrustum();
|
||||||
if (::debugVoxelSending) {
|
if (_myServer->wantsDebugVoxelSending()) {
|
||||||
printf("nodeData->updateCurrentViewFrustum() changed=%s\n", debug::valueOf(viewFrustumChanged));
|
printf("nodeData->updateCurrentViewFrustum() changed=%s\n", debug::valueOf(viewFrustumChanged));
|
||||||
}
|
}
|
||||||
deepestLevelVoxelDistributor(node, nodeData, viewFrustumChanged);
|
deepestLevelVoxelDistributor(node, nodeData, viewFrustumChanged);
|
||||||
|
@ -47,7 +48,7 @@ bool VoxelSendThread::process() {
|
||||||
if (usecToSleep > 0) {
|
if (usecToSleep > 0) {
|
||||||
usleep(usecToSleep);
|
usleep(usecToSleep);
|
||||||
} else {
|
} else {
|
||||||
if (::debugVoxelSending) {
|
if (_myServer->wantsDebugVoxelSending()) {
|
||||||
std::cout << "Last send took too much time, not sleeping!\n";
|
std::cout << "Last send took too much time, not sleeping!\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +95,7 @@ void VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
|
||||||
/// Version of voxel distributor that sends the deepest LOD level at once
|
/// Version of voxel distributor that sends the deepest LOD level at once
|
||||||
void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nodeData, bool viewFrustumChanged) {
|
void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nodeData, bool viewFrustumChanged) {
|
||||||
|
|
||||||
pthread_mutex_lock(&::treeLock);
|
_myServer->lockTree();
|
||||||
|
|
||||||
int truePacketsSent = 0;
|
int truePacketsSent = 0;
|
||||||
int trueBytesSent = 0;
|
int trueBytesSent = 0;
|
||||||
|
@ -113,7 +114,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
if (wantColor != nodeData->getCurrentPacketIsColor()) {
|
if (wantColor != nodeData->getCurrentPacketIsColor()) {
|
||||||
|
|
||||||
if (nodeData->isPacketWaiting()) {
|
if (nodeData->isPacketWaiting()) {
|
||||||
if (::debugVoxelSending) {
|
if (_myServer->wantsDebugVoxelSending()) {
|
||||||
printf("wantColor=%s --- SENDING PARTIAL PACKET! nodeData->getCurrentPacketIsColor()=%s\n",
|
printf("wantColor=%s --- SENDING PARTIAL PACKET! nodeData->getCurrentPacketIsColor()=%s\n",
|
||||||
debug::valueOf(wantColor), debug::valueOf(nodeData->getCurrentPacketIsColor()));
|
debug::valueOf(wantColor), debug::valueOf(nodeData->getCurrentPacketIsColor()));
|
||||||
}
|
}
|
||||||
|
@ -121,7 +122,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (::debugVoxelSending) {
|
if (_myServer->wantsDebugVoxelSending()) {
|
||||||
printf("wantColor=%s --- FIXING HEADER! nodeData->getCurrentPacketIsColor()=%s\n",
|
printf("wantColor=%s --- FIXING HEADER! nodeData->getCurrentPacketIsColor()=%s\n",
|
||||||
debug::valueOf(wantColor), debug::valueOf(nodeData->getCurrentPacketIsColor()));
|
debug::valueOf(wantColor), debug::valueOf(nodeData->getCurrentPacketIsColor()));
|
||||||
}
|
}
|
||||||
|
@ -129,7 +130,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (::debugVoxelSending) {
|
if (_myServer->wantsDebugVoxelSending()) {
|
||||||
printf("wantColor=%s getCurrentPacketIsColor()=%s, viewFrustumChanged=%s, getWantLowResMoving()=%s\n",
|
printf("wantColor=%s getCurrentPacketIsColor()=%s, viewFrustumChanged=%s, getWantLowResMoving()=%s\n",
|
||||||
debug::valueOf(wantColor), debug::valueOf(nodeData->getCurrentPacketIsColor()),
|
debug::valueOf(wantColor), debug::valueOf(nodeData->getCurrentPacketIsColor()),
|
||||||
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->getWantLowResMoving()));
|
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->getWantLowResMoving()));
|
||||||
|
@ -137,7 +138,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
|
|
||||||
const ViewFrustum* lastViewFrustum = wantDelta ? &nodeData->getLastKnownViewFrustum() : NULL;
|
const ViewFrustum* lastViewFrustum = wantDelta ? &nodeData->getLastKnownViewFrustum() : NULL;
|
||||||
|
|
||||||
if (::debugVoxelSending) {
|
if (_myServer->wantsDebugVoxelSending()) {
|
||||||
printf("deepestLevelVoxelDistributor() viewFrustumChanged=%s, nodeBag.isEmpty=%s, viewSent=%s\n",
|
printf("deepestLevelVoxelDistributor() viewFrustumChanged=%s, nodeBag.isEmpty=%s, viewSent=%s\n",
|
||||||
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->nodeBag.isEmpty()),
|
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->nodeBag.isEmpty()),
|
||||||
debug::valueOf(nodeData->getViewSent())
|
debug::valueOf(nodeData->getViewSent())
|
||||||
|
@ -148,7 +149,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
// the current view frustum for things to send.
|
// the current view frustum for things to send.
|
||||||
if (viewFrustumChanged || nodeData->nodeBag.isEmpty()) {
|
if (viewFrustumChanged || nodeData->nodeBag.isEmpty()) {
|
||||||
uint64_t now = usecTimestampNow();
|
uint64_t now = usecTimestampNow();
|
||||||
if (::debugVoxelSending) {
|
if (_myServer->wantsDebugVoxelSending()) {
|
||||||
printf("(viewFrustumChanged=%s || nodeData->nodeBag.isEmpty() =%s)...\n",
|
printf("(viewFrustumChanged=%s || nodeData->nodeBag.isEmpty() =%s)...\n",
|
||||||
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->nodeBag.isEmpty()));
|
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->nodeBag.isEmpty()));
|
||||||
if (nodeData->getLastTimeBagEmpty() > 0) {
|
if (nodeData->getLastTimeBagEmpty() > 0) {
|
||||||
|
@ -166,7 +167,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
|
|
||||||
// if our view has changed, we need to reset these things...
|
// if our view has changed, we need to reset these things...
|
||||||
if (viewFrustumChanged) {
|
if (viewFrustumChanged) {
|
||||||
if (::dumpVoxelsOnMove) {
|
if (_myServer->wantDumpVoxelsOnMove()) {
|
||||||
nodeData->nodeBag.deleteAll();
|
nodeData->nodeBag.deleteAll();
|
||||||
}
|
}
|
||||||
nodeData->map.erase();
|
nodeData->map.erase();
|
||||||
|
@ -180,7 +181,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
|
|
||||||
nodeData->stats.sceneCompleted();
|
nodeData->stats.sceneCompleted();
|
||||||
|
|
||||||
if (::displayVoxelStats) {
|
if (_myServer->wantDisplayVoxelStats()) {
|
||||||
nodeData->stats.printDebugDetails();
|
nodeData->stats.printDebugDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,10 +192,10 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
if (isFullScene) {
|
if (isFullScene) {
|
||||||
nodeData->nodeBag.deleteAll();
|
nodeData->nodeBag.deleteAll();
|
||||||
}
|
}
|
||||||
nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged, ::serverTree.rootNode, ::jurisdiction);
|
nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged, _myServer->getServerTree().rootNode, _myServer->getJurisdiction());
|
||||||
|
|
||||||
// This is the start of "resending" the scene.
|
// This is the start of "resending" the scene.
|
||||||
nodeData->nodeBag.insert(serverTree.rootNode);
|
nodeData->nodeBag.insert(_myServer->getServerTree().rootNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have something in our nodeBag, then turn them into packets and send them out...
|
// If we have something in our nodeBag, then turn them into packets and send them out...
|
||||||
|
@ -203,8 +204,8 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
int packetsSentThisInterval = 0;
|
int packetsSentThisInterval = 0;
|
||||||
uint64_t start = usecTimestampNow();
|
uint64_t start = usecTimestampNow();
|
||||||
|
|
||||||
bool shouldSendEnvironments = ::sendEnvironments && shouldDo(ENVIRONMENT_SEND_INTERVAL_USECS, VOXEL_SEND_INTERVAL_USECS);
|
bool shouldSendEnvironments = _myServer->wantSendEnvironments() && shouldDo(ENVIRONMENT_SEND_INTERVAL_USECS, VOXEL_SEND_INTERVAL_USECS);
|
||||||
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - (shouldSendEnvironments ? 1 : 0)) {
|
while (packetsSentThisInterval < _myServer->getPacketsPerClientPerInterval() - (shouldSendEnvironments ? 1 : 0)) {
|
||||||
// Check to see if we're taking too long, and if so bail early...
|
// Check to see if we're taking too long, and if so bail early...
|
||||||
uint64_t now = usecTimestampNow();
|
uint64_t now = usecTimestampNow();
|
||||||
long elapsedUsec = (now - start);
|
long elapsedUsec = (now - start);
|
||||||
|
@ -212,7 +213,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
long usecRemaining = (VOXEL_SEND_INTERVAL_USECS - elapsedUsec);
|
long usecRemaining = (VOXEL_SEND_INTERVAL_USECS - elapsedUsec);
|
||||||
|
|
||||||
if (elapsedUsecPerPacket + SENDING_TIME_TO_SPARE > usecRemaining) {
|
if (elapsedUsecPerPacket + SENDING_TIME_TO_SPARE > usecRemaining) {
|
||||||
if (::debugVoxelSending) {
|
if (_myServer->wantsDebugVoxelSending()) {
|
||||||
printf("packetLoop() usecRemaining=%ld bailing early took %ld usecs to generate %d bytes in %d packets (%ld usec avg), %d nodes still to send\n",
|
printf("packetLoop() usecRemaining=%ld bailing early took %ld usecs to generate %d bytes in %d packets (%ld usec avg), %d nodes still to send\n",
|
||||||
usecRemaining, elapsedUsec, trueBytesSent, truePacketsSent, elapsedUsecPerPacket,
|
usecRemaining, elapsedUsec, trueBytesSent, truePacketsSent, elapsedUsecPerPacket,
|
||||||
nodeData->nodeBag.count());
|
nodeData->nodeBag.count());
|
||||||
|
@ -234,10 +235,10 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum,
|
WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum,
|
||||||
wantOcclusionCulling, coverageMap, boundaryLevelAdjust,
|
wantOcclusionCulling, coverageMap, boundaryLevelAdjust,
|
||||||
nodeData->getLastTimeBagEmpty(),
|
nodeData->getLastTimeBagEmpty(),
|
||||||
isFullScene, &nodeData->stats, ::jurisdiction);
|
isFullScene, &nodeData->stats, _myServer->getJurisdiction());
|
||||||
|
|
||||||
nodeData->stats.encodeStarted();
|
nodeData->stats.encodeStarted();
|
||||||
bytesWritten = serverTree.encodeTreeBitstream(subTree, _tempOutputBuffer, MAX_VOXEL_PACKET_SIZE - 1,
|
bytesWritten = _myServer->getServerTree().encodeTreeBitstream(subTree, _tempOutputBuffer, MAX_VOXEL_PACKET_SIZE - 1,
|
||||||
nodeData->nodeBag, params);
|
nodeData->nodeBag, params);
|
||||||
nodeData->stats.encodeStopped();
|
nodeData->stats.encodeStopped();
|
||||||
|
|
||||||
|
@ -254,17 +255,17 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||||
nodeData->resetVoxelPacket();
|
nodeData->resetVoxelPacket();
|
||||||
}
|
}
|
||||||
packetsSentThisInterval = PACKETS_PER_CLIENT_PER_INTERVAL; // done for now, no nodes left
|
packetsSentThisInterval = _myServer->getPacketsPerClientPerInterval(); // done for now, no nodes left
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// send the environment packet
|
// send the environment packet
|
||||||
if (shouldSendEnvironments) {
|
if (shouldSendEnvironments) {
|
||||||
int numBytesPacketHeader = populateTypeAndVersion(_tempOutputBuffer, PACKET_TYPE_ENVIRONMENT_DATA);
|
int numBytesPacketHeader = populateTypeAndVersion(_tempOutputBuffer, PACKET_TYPE_ENVIRONMENT_DATA);
|
||||||
int envPacketLength = numBytesPacketHeader;
|
int envPacketLength = numBytesPacketHeader;
|
||||||
int environmentsToSend = ::sendMinimalEnvironment ? 1 : sizeof(environmentData) / sizeof(EnvironmentData);
|
int environmentsToSend = _myServer->getSendMinimalEnvironment() ? 1 : _myServer->getEnvironmentDataCount();
|
||||||
|
|
||||||
for (int i = 0; i < environmentsToSend; i++) {
|
for (int i = 0; i < environmentsToSend; i++) {
|
||||||
envPacketLength += environmentData[i].getBroadcastData(_tempOutputBuffer + envPacketLength);
|
envPacketLength += _myServer->getEnvironmentData(i)->getBroadcastData(_tempOutputBuffer + envPacketLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), _tempOutputBuffer, envPacketLength);
|
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), _tempOutputBuffer, envPacketLength);
|
||||||
|
@ -283,7 +284,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
printf("WARNING! packetLoop() took %d milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
|
printf("WARNING! packetLoop() took %d milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
|
||||||
elapsedmsec, trueBytesSent, truePacketsSent, nodeData->nodeBag.count());
|
elapsedmsec, trueBytesSent, truePacketsSent, nodeData->nodeBag.count());
|
||||||
}
|
}
|
||||||
} else if (::debugVoxelSending) {
|
} else if (_myServer->wantsDebugVoxelSending()) {
|
||||||
printf("packetLoop() took %d milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
|
printf("packetLoop() took %d milliseconds to generate %d bytes in %d packets, %d nodes still to send\n",
|
||||||
elapsedmsec, trueBytesSent, truePacketsSent, nodeData->nodeBag.count());
|
elapsedmsec, trueBytesSent, truePacketsSent, nodeData->nodeBag.count());
|
||||||
}
|
}
|
||||||
|
@ -293,7 +294,7 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
if (nodeData->nodeBag.isEmpty()) {
|
if (nodeData->nodeBag.isEmpty()) {
|
||||||
nodeData->updateLastKnownViewFrustum();
|
nodeData->updateLastKnownViewFrustum();
|
||||||
nodeData->setViewSent(true);
|
nodeData->setViewSent(true);
|
||||||
if (::debugVoxelSending) {
|
if (_myServer->wantsDebugVoxelSending()) {
|
||||||
nodeData->map.printStats();
|
nodeData->map.printStats();
|
||||||
}
|
}
|
||||||
nodeData->map.erase(); // It would be nice if we could save this, and only reset it when the view frustum changes
|
nodeData->map.erase(); // It would be nice if we could save this, and only reset it when the view frustum changes
|
||||||
|
@ -301,6 +302,6 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
|
||||||
|
|
||||||
} // end if bag wasn't empty, and so we sent stuff...
|
} // end if bag wasn't empty, and so we sent stuff...
|
||||||
|
|
||||||
pthread_mutex_unlock(&::treeLock);
|
_myServer->unlockTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,17 +16,19 @@
|
||||||
#include <VoxelTree.h>
|
#include <VoxelTree.h>
|
||||||
#include <VoxelNodeBag.h>
|
#include <VoxelNodeBag.h>
|
||||||
#include "VoxelNodeData.h"
|
#include "VoxelNodeData.h"
|
||||||
|
#include "VoxelServer.h"
|
||||||
|
|
||||||
/// Threaded processor for sending voxel packets to a single client
|
/// Threaded processor for sending voxel packets to a single client
|
||||||
class VoxelSendThread : public virtual GenericThread {
|
class VoxelSendThread : public virtual GenericThread {
|
||||||
public:
|
public:
|
||||||
VoxelSendThread(uint16_t nodeID);
|
VoxelSendThread(uint16_t nodeID, VoxelServer* myServer);
|
||||||
protected:
|
protected:
|
||||||
/// Implements generic processing behavior for this thread.
|
/// Implements generic processing behavior for this thread.
|
||||||
virtual bool process();
|
virtual bool process();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t _nodeID;
|
uint16_t _nodeID;
|
||||||
|
VoxelServer* _myServer;
|
||||||
|
|
||||||
void handlePacketSend(Node* node, VoxelNodeData* nodeData, int& trueBytesSent, int& truePacketsSent);
|
void handlePacketSend(Node* node, VoxelNodeData* nodeData, int& trueBytesSent, int& truePacketsSent);
|
||||||
void deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nodeData, bool viewFrustumChanged);
|
void deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nodeData, bool viewFrustumChanged);
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include <OctalCode.h>
|
#include <OctalCode.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <NodeTypes.h>
|
#include <NodeTypes.h>
|
||||||
#include <EnvironmentData.h>
|
|
||||||
#include <VoxelTree.h>
|
#include <VoxelTree.h>
|
||||||
#include "VoxelNodeData.h"
|
#include "VoxelNodeData.h"
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
@ -23,11 +22,6 @@
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <JurisdictionSender.h>
|
#include <JurisdictionSender.h>
|
||||||
|
|
||||||
#include "NodeWatcher.h"
|
|
||||||
#include "VoxelPersistThread.h"
|
|
||||||
#include "VoxelSendThread.h"
|
|
||||||
#include "VoxelServerPacketProcessor.h"
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "Syssocket.h"
|
#include "Syssocket.h"
|
||||||
#include "Systime.h"
|
#include "Systime.h"
|
||||||
|
@ -38,34 +32,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "VoxelServer.h"
|
#include "VoxelServer.h"
|
||||||
#include "VoxelServerState.h"
|
#include "VoxelServerConsts.h"
|
||||||
|
|
||||||
const char* LOCAL_VOXELS_PERSIST_FILE = "resources/voxels.svo";
|
const char* LOCAL_VOXELS_PERSIST_FILE = "resources/voxels.svo";
|
||||||
const char* VOXELS_PERSIST_FILE = "/etc/highfidelity/voxel-server/resources/voxels.svo";
|
const char* VOXELS_PERSIST_FILE = "/etc/highfidelity/voxel-server/resources/voxels.svo";
|
||||||
char voxelPersistFilename[MAX_FILENAME_LENGTH];
|
|
||||||
int PACKETS_PER_CLIENT_PER_INTERVAL = 10;
|
|
||||||
VoxelTree serverTree(true); // this IS a reaveraging tree
|
|
||||||
bool wantVoxelPersist = true;
|
|
||||||
bool wantLocalDomain = false;
|
|
||||||
bool debugVoxelSending = false;
|
|
||||||
bool shouldShowAnimationDebug = false;
|
|
||||||
bool displayVoxelStats = false;
|
|
||||||
bool debugVoxelReceiving = false;
|
|
||||||
bool sendEnvironments = true;
|
|
||||||
bool sendMinimalEnvironment = false;
|
|
||||||
bool dumpVoxelsOnMove = false;
|
|
||||||
EnvironmentData environmentData[3];
|
|
||||||
int receivedPacketCount = 0;
|
|
||||||
JurisdictionMap* jurisdiction = NULL;
|
|
||||||
JurisdictionSender* jurisdictionSender = NULL;
|
|
||||||
VoxelServerPacketProcessor* voxelServerPacketProcessor = NULL;
|
|
||||||
VoxelPersistThread* voxelPersistThread = NULL;
|
|
||||||
pthread_mutex_t treeLock;
|
|
||||||
NodeWatcher nodeWatcher; // used to cleanup AGENT data when agents are killed
|
|
||||||
|
|
||||||
int VoxelServer::_argc = 0;
|
|
||||||
const char** VoxelServer::_argv = NULL;
|
|
||||||
bool VoxelServer::_dontKillOnMissingDomain = false;
|
|
||||||
|
|
||||||
void attachVoxelNodeDataToNode(Node* newNode) {
|
void attachVoxelNodeDataToNode(Node* newNode) {
|
||||||
if (newNode->getLinkedData() == NULL) {
|
if (newNode->getLinkedData() == NULL) {
|
||||||
|
@ -74,12 +44,48 @@ void attachVoxelNodeDataToNode(Node* newNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelServer::VoxelServer(Assignment::Command command, Assignment::Location location) :
|
VoxelServer::VoxelServer(Assignment::Command command, Assignment::Location location) :
|
||||||
Assignment(command, Assignment::VoxelServerType, location) {
|
Assignment(command, Assignment::VoxelServerType, location),
|
||||||
|
_serverTree(true) {
|
||||||
|
_argc = 0;
|
||||||
|
_argv = NULL;
|
||||||
|
_dontKillOnMissingDomain = false;
|
||||||
|
|
||||||
|
_packetsPerClientPerInterval = 10;
|
||||||
|
_wantVoxelPersist = true;
|
||||||
|
_wantLocalDomain = false;
|
||||||
|
_debugVoxelSending = false;
|
||||||
|
_shouldShowAnimationDebug = false;
|
||||||
|
_displayVoxelStats = false;
|
||||||
|
_debugVoxelReceiving = false;
|
||||||
|
_sendEnvironments = true;
|
||||||
|
_sendMinimalEnvironment = false;
|
||||||
|
_dumpVoxelsOnMove = false;
|
||||||
|
_jurisdiction = NULL;
|
||||||
|
_jurisdictionSender = NULL;
|
||||||
|
_voxelServerPacketProcessor = NULL;
|
||||||
|
_voxelPersistThread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelServer::VoxelServer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) {
|
VoxelServer::VoxelServer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes),
|
||||||
|
_serverTree(true) {
|
||||||
|
_argc = 0;
|
||||||
|
_argv = NULL;
|
||||||
|
_dontKillOnMissingDomain = false;
|
||||||
|
|
||||||
|
_packetsPerClientPerInterval = 10;
|
||||||
|
_wantVoxelPersist = true;
|
||||||
|
_wantLocalDomain = false;
|
||||||
|
_debugVoxelSending = false;
|
||||||
|
_shouldShowAnimationDebug = false;
|
||||||
|
_displayVoxelStats = false;
|
||||||
|
_debugVoxelReceiving = false;
|
||||||
|
_sendEnvironments = true;
|
||||||
|
_sendMinimalEnvironment = false;
|
||||||
|
_dumpVoxelsOnMove = false;
|
||||||
|
_jurisdiction = NULL;
|
||||||
|
_jurisdictionSender = NULL;
|
||||||
|
_voxelServerPacketProcessor = NULL;
|
||||||
|
_voxelPersistThread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelServer::setArguments(int argc, char** argv) {
|
void VoxelServer::setArguments(int argc, char** argv) {
|
||||||
|
@ -87,13 +93,13 @@ void VoxelServer::setArguments(int argc, char** argv) {
|
||||||
_argv = const_cast<const char**>(argv);
|
_argv = const_cast<const char**>(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelServer::setupDomainAndPort(const char* domain, int port) {
|
void VoxelServer::setupStandAlone(const char* domain, int port) {
|
||||||
NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, port);
|
NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, port);
|
||||||
|
|
||||||
// Handle Local Domain testing with the --local command line
|
// Handle Local Domain testing with the --local command line
|
||||||
const char* local = "--local";
|
const char* local = "--local";
|
||||||
::wantLocalDomain = strcmp(domain, local) == 0;
|
_wantLocalDomain = strcmp(domain, local) == 0;
|
||||||
if (::wantLocalDomain) {
|
if (_wantLocalDomain) {
|
||||||
printf("Local Domain MODE!\n");
|
printf("Local Domain MODE!\n");
|
||||||
NodeList::getInstance()->setDomainIPToLocalhost();
|
NodeList::getInstance()->setDomainIPToLocalhost();
|
||||||
} else {
|
} else {
|
||||||
|
@ -108,7 +114,7 @@ void VoxelServer::setupDomainAndPort(const char* domain, int port) {
|
||||||
|
|
||||||
//int main(int argc, const char * argv[]) {
|
//int main(int argc, const char * argv[]) {
|
||||||
void VoxelServer::run() {
|
void VoxelServer::run() {
|
||||||
pthread_mutex_init(&::treeLock, NULL);
|
pthread_mutex_init(&_treeLock, NULL);
|
||||||
|
|
||||||
qInstallMessageHandler(sharedMessageHandler);
|
qInstallMessageHandler(sharedMessageHandler);
|
||||||
|
|
||||||
|
@ -118,7 +124,7 @@ void VoxelServer::run() {
|
||||||
printf("jurisdictionFile=%s\n", jurisdictionFile);
|
printf("jurisdictionFile=%s\n", jurisdictionFile);
|
||||||
|
|
||||||
printf("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
|
printf("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
|
||||||
jurisdiction = new JurisdictionMap(jurisdictionFile);
|
_jurisdiction = new JurisdictionMap(jurisdictionFile);
|
||||||
printf("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
|
printf("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
|
||||||
} else {
|
} else {
|
||||||
const char* JURISDICTION_ROOT = "--jurisdictionRoot";
|
const char* JURISDICTION_ROOT = "--jurisdictionRoot";
|
||||||
|
@ -134,28 +140,28 @@ void VoxelServer::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jurisdictionRoot || jurisdictionEndNodes) {
|
if (jurisdictionRoot || jurisdictionEndNodes) {
|
||||||
::jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
|
_jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// should we send environments? Default is yes, but this command line suppresses sending
|
// should we send environments? Default is yes, but this command line suppresses sending
|
||||||
const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove";
|
const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove";
|
||||||
::dumpVoxelsOnMove = cmdOptionExists(_argc, _argv, DUMP_VOXELS_ON_MOVE);
|
_dumpVoxelsOnMove = cmdOptionExists(_argc, _argv, DUMP_VOXELS_ON_MOVE);
|
||||||
printf("dumpVoxelsOnMove=%s\n", debug::valueOf(::dumpVoxelsOnMove));
|
printf("dumpVoxelsOnMove=%s\n", debug::valueOf(_dumpVoxelsOnMove));
|
||||||
|
|
||||||
// should we send environments? Default is yes, but this command line suppresses sending
|
// should we send environments? Default is yes, but this command line suppresses sending
|
||||||
const char* DONT_SEND_ENVIRONMENTS = "--dontSendEnvironments";
|
const char* DONT_SEND_ENVIRONMENTS = "--dontSendEnvironments";
|
||||||
bool dontSendEnvironments = getCmdOption(_argc, _argv, DONT_SEND_ENVIRONMENTS);
|
bool dontSendEnvironments = getCmdOption(_argc, _argv, DONT_SEND_ENVIRONMENTS);
|
||||||
if (dontSendEnvironments) {
|
if (dontSendEnvironments) {
|
||||||
printf("Sending environments suppressed...\n");
|
printf("Sending environments suppressed...\n");
|
||||||
::sendEnvironments = false;
|
_sendEnvironments = false;
|
||||||
} else {
|
} else {
|
||||||
// should we send environments? Default is yes, but this command line suppresses sending
|
// should we send environments? Default is yes, but this command line suppresses sending
|
||||||
const char* MINIMAL_ENVIRONMENT = "--MinimalEnvironment";
|
const char* MINIMAL_ENVIRONMENT = "--MinimalEnvironment";
|
||||||
::sendMinimalEnvironment = getCmdOption(_argc, _argv, MINIMAL_ENVIRONMENT);
|
_sendMinimalEnvironment = getCmdOption(_argc, _argv, MINIMAL_ENVIRONMENT);
|
||||||
printf("Using Minimal Environment=%s\n", debug::valueOf(::sendMinimalEnvironment));
|
printf("Using Minimal Environment=%s\n", debug::valueOf(_sendMinimalEnvironment));
|
||||||
}
|
}
|
||||||
printf("Sending environments=%s\n", debug::valueOf(::sendEnvironments));
|
printf("Sending environments=%s\n", debug::valueOf(_sendEnvironments));
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
nodeList->setOwnerType(NODE_TYPE_VOXEL_SERVER);
|
nodeList->setOwnerType(NODE_TYPE_VOXEL_SERVER);
|
||||||
|
@ -163,72 +169,72 @@ void VoxelServer::run() {
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
// tell our NodeList about our desire to get notifications
|
// tell our NodeList about our desire to get notifications
|
||||||
nodeList->addHook(&nodeWatcher);
|
nodeList->addHook(&_nodeWatcher);
|
||||||
nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;
|
nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;
|
||||||
|
|
||||||
nodeList->startSilentNodeRemovalThread();
|
nodeList->startSilentNodeRemovalThread();
|
||||||
srand((unsigned)time(0));
|
srand((unsigned)time(0));
|
||||||
|
|
||||||
const char* DISPLAY_VOXEL_STATS = "--displayVoxelStats";
|
const char* DISPLAY_VOXEL_STATS = "--displayVoxelStats";
|
||||||
::displayVoxelStats = getCmdOption(_argc, _argv, DISPLAY_VOXEL_STATS);
|
_displayVoxelStats = getCmdOption(_argc, _argv, DISPLAY_VOXEL_STATS);
|
||||||
printf("displayVoxelStats=%s\n", debug::valueOf(::displayVoxelStats));
|
printf("displayVoxelStats=%s\n", debug::valueOf(_displayVoxelStats));
|
||||||
|
|
||||||
const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending";
|
const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending";
|
||||||
::debugVoxelSending = getCmdOption(_argc, _argv, DEBUG_VOXEL_SENDING);
|
_debugVoxelSending = getCmdOption(_argc, _argv, DEBUG_VOXEL_SENDING);
|
||||||
printf("debugVoxelSending=%s\n", debug::valueOf(::debugVoxelSending));
|
printf("debugVoxelSending=%s\n", debug::valueOf(_debugVoxelSending));
|
||||||
|
|
||||||
const char* DEBUG_VOXEL_RECEIVING = "--debugVoxelReceiving";
|
const char* DEBUG_VOXEL_RECEIVING = "--debugVoxelReceiving";
|
||||||
::debugVoxelReceiving = getCmdOption(_argc, _argv, DEBUG_VOXEL_RECEIVING);
|
_debugVoxelReceiving = getCmdOption(_argc, _argv, DEBUG_VOXEL_RECEIVING);
|
||||||
printf("debugVoxelReceiving=%s\n", debug::valueOf(::debugVoxelReceiving));
|
printf("debugVoxelReceiving=%s\n", debug::valueOf(_debugVoxelReceiving));
|
||||||
|
|
||||||
const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug";
|
const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug";
|
||||||
::shouldShowAnimationDebug = getCmdOption(_argc, _argv, WANT_ANIMATION_DEBUG);
|
_shouldShowAnimationDebug = getCmdOption(_argc, _argv, WANT_ANIMATION_DEBUG);
|
||||||
printf("shouldShowAnimationDebug=%s\n", debug::valueOf(::shouldShowAnimationDebug));
|
printf("shouldShowAnimationDebug=%s\n", debug::valueOf(_shouldShowAnimationDebug));
|
||||||
|
|
||||||
// By default we will voxel persist, if you want to disable this, then pass in this parameter
|
// By default we will voxel persist, if you want to disable this, then pass in this parameter
|
||||||
const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
|
const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
|
||||||
if ( getCmdOption(_argc, _argv, NO_VOXEL_PERSIST)) {
|
if (getCmdOption(_argc, _argv, NO_VOXEL_PERSIST)) {
|
||||||
::wantVoxelPersist = false;
|
_wantVoxelPersist = false;
|
||||||
}
|
}
|
||||||
printf("wantVoxelPersist=%s\n", debug::valueOf(::wantVoxelPersist));
|
printf("wantVoxelPersist=%s\n", debug::valueOf(_wantVoxelPersist));
|
||||||
|
|
||||||
// if we want Voxel Persistence, load the local file now...
|
// if we want Voxel Persistence, load the local file now...
|
||||||
bool persistantFileRead = false;
|
bool persistantFileRead = false;
|
||||||
if (::wantVoxelPersist) {
|
if (_wantVoxelPersist) {
|
||||||
|
|
||||||
// Check to see if the user passed in a command line option for setting packet send rate
|
// Check to see if the user passed in a command line option for setting packet send rate
|
||||||
const char* VOXELS_PERSIST_FILENAME = "--voxelsPersistFilename";
|
const char* VOXELS_PERSIST_FILENAME = "--voxelsPersistFilename";
|
||||||
const char* voxelsPersistFilenameParameter = getCmdOption(_argc, _argv, VOXELS_PERSIST_FILENAME);
|
const char* voxelsPersistFilenameParameter = getCmdOption(_argc, _argv, VOXELS_PERSIST_FILENAME);
|
||||||
if (voxelsPersistFilenameParameter) {
|
if (voxelsPersistFilenameParameter) {
|
||||||
strcpy(voxelPersistFilename, voxelsPersistFilenameParameter);
|
strcpy(_voxelPersistFilename, voxelsPersistFilenameParameter);
|
||||||
} else {
|
} else {
|
||||||
//strcpy(voxelPersistFilename, ::wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
|
//strcpy(voxelPersistFilename, _wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
|
||||||
strcpy(voxelPersistFilename, LOCAL_VOXELS_PERSIST_FILE);
|
strcpy(_voxelPersistFilename, LOCAL_VOXELS_PERSIST_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("loading voxels from file: %s...\n", voxelPersistFilename);
|
printf("loading voxels from file: %s...\n", _voxelPersistFilename);
|
||||||
|
|
||||||
persistantFileRead = ::serverTree.readFromSVOFile(::voxelPersistFilename);
|
persistantFileRead = _serverTree.readFromSVOFile(_voxelPersistFilename);
|
||||||
if (persistantFileRead) {
|
if (persistantFileRead) {
|
||||||
PerformanceWarning warn(::shouldShowAnimationDebug,
|
PerformanceWarning warn(_shouldShowAnimationDebug,
|
||||||
"persistVoxelsWhenDirty() - reaverageVoxelColors()", ::shouldShowAnimationDebug);
|
"persistVoxelsWhenDirty() - reaverageVoxelColors()", _shouldShowAnimationDebug);
|
||||||
|
|
||||||
// after done inserting all these voxels, then reaverage colors
|
// after done inserting all these voxels, then reaverage colors
|
||||||
serverTree.reaverageVoxelColors(serverTree.rootNode);
|
_serverTree.reaverageVoxelColors(_serverTree.rootNode);
|
||||||
printf("Voxels reAveraged\n");
|
printf("Voxels reAveraged\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
::serverTree.clearDirtyBit(); // the tree is clean since we just loaded it
|
_serverTree.clearDirtyBit(); // the tree is clean since we just loaded it
|
||||||
printf("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
|
printf("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
|
||||||
unsigned long nodeCount = ::serverTree.rootNode->getSubTreeNodeCount();
|
unsigned long nodeCount = _serverTree.rootNode->getSubTreeNodeCount();
|
||||||
unsigned long internalNodeCount = ::serverTree.rootNode->getSubTreeInternalNodeCount();
|
unsigned long internalNodeCount = _serverTree.rootNode->getSubTreeInternalNodeCount();
|
||||||
unsigned long leafNodeCount = ::serverTree.rootNode->getSubTreeLeafNodeCount();
|
unsigned long leafNodeCount = _serverTree.rootNode->getSubTreeLeafNodeCount();
|
||||||
printf("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
|
printf("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
|
||||||
|
|
||||||
// now set up VoxelPersistThread
|
// now set up VoxelPersistThread
|
||||||
::voxelPersistThread = new VoxelPersistThread(&::serverTree, ::voxelPersistFilename);
|
_voxelPersistThread = new VoxelPersistThread(&_serverTree, _voxelPersistFilename);
|
||||||
if (::voxelPersistThread) {
|
if (_voxelPersistThread) {
|
||||||
::voxelPersistThread->initialize(true);
|
_voxelPersistThread->initialize(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,52 +243,52 @@ void VoxelServer::run() {
|
||||||
const char* INPUT_FILE = "-i";
|
const char* INPUT_FILE = "-i";
|
||||||
const char* voxelsFilename = getCmdOption(_argc, _argv, INPUT_FILE);
|
const char* voxelsFilename = getCmdOption(_argc, _argv, INPUT_FILE);
|
||||||
if (voxelsFilename) {
|
if (voxelsFilename) {
|
||||||
serverTree.readFromSVOFile(voxelsFilename);
|
_serverTree.readFromSVOFile(voxelsFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to see if the user passed in a command line option for setting packet send rate
|
// Check to see if the user passed in a command line option for setting packet send rate
|
||||||
const char* PACKETS_PER_SECOND = "--packetsPerSecond";
|
const char* PACKETS_PER_SECOND = "--packetsPerSecond";
|
||||||
const char* packetsPerSecond = getCmdOption(_argc, _argv, PACKETS_PER_SECOND);
|
const char* packetsPerSecond = getCmdOption(_argc, _argv, PACKETS_PER_SECOND);
|
||||||
if (packetsPerSecond) {
|
if (packetsPerSecond) {
|
||||||
PACKETS_PER_CLIENT_PER_INTERVAL = atoi(packetsPerSecond)/INTERVALS_PER_SECOND;
|
_packetsPerClientPerInterval = atoi(packetsPerSecond) / INTERVALS_PER_SECOND;
|
||||||
if (PACKETS_PER_CLIENT_PER_INTERVAL < 1) {
|
if (_packetsPerClientPerInterval < 1) {
|
||||||
PACKETS_PER_CLIENT_PER_INTERVAL = 1;
|
_packetsPerClientPerInterval = 1;
|
||||||
}
|
}
|
||||||
printf("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, PACKETS_PER_CLIENT_PER_INTERVAL);
|
printf("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, _packetsPerClientPerInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for now, initialize the environments with fixed values
|
// for now, initialize the environments with fixed values
|
||||||
environmentData[1].setID(1);
|
_environmentData[1].setID(1);
|
||||||
environmentData[1].setGravity(1.0f);
|
_environmentData[1].setGravity(1.0f);
|
||||||
environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE);
|
_environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE);
|
||||||
environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE);
|
_environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE);
|
||||||
environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f);
|
_environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f);
|
||||||
environmentData[2].setID(2);
|
_environmentData[2].setID(2);
|
||||||
environmentData[2].setGravity(1.0f);
|
_environmentData[2].setGravity(1.0f);
|
||||||
environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
|
_environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
|
||||||
environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
|
_environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
|
||||||
environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f);
|
_environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f);
|
||||||
environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue
|
_environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue
|
||||||
|
|
||||||
sockaddr senderAddress;
|
sockaddr senderAddress;
|
||||||
|
|
||||||
unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE];
|
unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE];
|
||||||
ssize_t packetLength;
|
ssize_t packetLength;
|
||||||
|
|
||||||
timeval lastDomainServerCheckIn = {};
|
timeval lastDomainServerCheckIn = {};
|
||||||
|
|
||||||
// set up our jurisdiction broadcaster...
|
// set up our jurisdiction broadcaster...
|
||||||
::jurisdictionSender = new JurisdictionSender(::jurisdiction);
|
_jurisdictionSender = new JurisdictionSender(_jurisdiction);
|
||||||
if (::jurisdictionSender) {
|
if (_jurisdictionSender) {
|
||||||
::jurisdictionSender->initialize(true);
|
_jurisdictionSender->initialize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up our VoxelServerPacketProcessor
|
// set up our VoxelServerPacketProcessor
|
||||||
::voxelServerPacketProcessor = new VoxelServerPacketProcessor();
|
_voxelServerPacketProcessor = new VoxelServerPacketProcessor(this);
|
||||||
if (::voxelServerPacketProcessor) {
|
if (_voxelServerPacketProcessor) {
|
||||||
::voxelServerPacketProcessor->initialize(true);
|
_voxelServerPacketProcessor->initialize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop to send to nodes requesting data
|
// loop to send to nodes requesting data
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
|
@ -313,46 +319,50 @@ void VoxelServer::run() {
|
||||||
nodeID);
|
nodeID);
|
||||||
|
|
||||||
NodeList::getInstance()->updateNodeWithData(node, packetData, packetLength);
|
NodeList::getInstance()->updateNodeWithData(node, packetData, packetLength);
|
||||||
|
|
||||||
|
VoxelNodeData* nodeData = (VoxelNodeData*) node->getLinkedData();
|
||||||
|
if (nodeData && !nodeData->isVoxelSendThreadInitalized()) {
|
||||||
|
nodeData->initializeVoxelSendThread(this);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (packetData[0] == PACKET_TYPE_PING) {
|
} else if (packetData[0] == PACKET_TYPE_PING) {
|
||||||
// If the packet is a ping, let processNodeData handle it.
|
// If the packet is a ping, let processNodeData handle it.
|
||||||
NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
|
NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
|
||||||
} else if (packetData[0] == PACKET_TYPE_DOMAIN) {
|
} else if (packetData[0] == PACKET_TYPE_DOMAIN) {
|
||||||
NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
|
NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
|
||||||
} else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
|
} else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
|
||||||
if (::jurisdictionSender) {
|
if (_jurisdictionSender) {
|
||||||
::jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength);
|
_jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength);
|
||||||
}
|
}
|
||||||
} else if (::voxelServerPacketProcessor) {
|
} else if (_voxelServerPacketProcessor) {
|
||||||
::voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength);
|
_voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength);
|
||||||
} else {
|
} else {
|
||||||
printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]);
|
printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (::jurisdiction) {
|
delete _jurisdiction;
|
||||||
delete ::jurisdiction;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (::jurisdictionSender) {
|
if (_jurisdictionSender) {
|
||||||
::jurisdictionSender->terminate();
|
_jurisdictionSender->terminate();
|
||||||
delete ::jurisdictionSender;
|
delete _jurisdictionSender;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (::voxelServerPacketProcessor) {
|
if (_voxelServerPacketProcessor) {
|
||||||
::voxelServerPacketProcessor->terminate();
|
_voxelServerPacketProcessor->terminate();
|
||||||
delete ::voxelServerPacketProcessor;
|
delete _voxelServerPacketProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (::voxelPersistThread) {
|
if (_voxelPersistThread) {
|
||||||
::voxelPersistThread->terminate();
|
_voxelPersistThread->terminate();
|
||||||
delete ::voxelPersistThread;
|
delete _voxelPersistThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tell our NodeList we're done with notifications
|
// tell our NodeList we're done with notifications
|
||||||
nodeList->removeHook(&nodeWatcher);
|
nodeList->removeHook(&_nodeWatcher);
|
||||||
|
|
||||||
pthread_mutex_destroy(&::treeLock);
|
pthread_mutex_destroy(&_treeLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,33 +11,79 @@
|
||||||
#define __voxel_server__VoxelServer__
|
#define __voxel_server__VoxelServer__
|
||||||
|
|
||||||
#include <Assignment.h>
|
#include <Assignment.h>
|
||||||
|
#include <EnvironmentData.h>
|
||||||
|
|
||||||
|
#include "NodeWatcher.h"
|
||||||
|
#include "VoxelPersistThread.h"
|
||||||
|
#include "VoxelSendThread.h"
|
||||||
|
#include "VoxelServerConsts.h"
|
||||||
|
#include "VoxelServerPacketProcessor.h"
|
||||||
|
|
||||||
/// Handles assignments of type VoxelServer - sending voxels to various clients.
|
/// Handles assignments of type VoxelServer - sending voxels to various clients.
|
||||||
class VoxelServer : public Assignment {
|
class VoxelServer : public Assignment {
|
||||||
public:
|
public:
|
||||||
VoxelServer(Assignment::Command command,
|
VoxelServer(Assignment::Command command,
|
||||||
Assignment::Location location = Assignment::GlobalLocation);
|
Assignment::Location location = Assignment::GlobalLocation);
|
||||||
|
|
||||||
VoxelServer(const unsigned char* dataBuffer, int numBytes);
|
VoxelServer(const unsigned char* dataBuffer, int numBytes);
|
||||||
|
|
||||||
/// runs the voxel server assignment
|
/// runs the voxel server assignment
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
/// allows setting of run arguments
|
/// allows setting of run arguments
|
||||||
static void setArguments(int argc, char** argv);
|
void setArguments(int argc, char** argv);
|
||||||
|
|
||||||
/// when VoxelServer class is used by voxel-server stand alone executable it calls this to specify the domain
|
/// when VoxelServer class is used by voxel-server stand alone executable it calls this to specify the domain
|
||||||
/// and port it is handling. When called by assignment-client, this is not needed because assignment-client
|
/// and port it is handling. When called by assignment-client, this is not needed because assignment-client
|
||||||
/// handles ports and domains automatically.
|
/// handles ports and domains automatically.
|
||||||
/// \param const char* domain domain name, IP address, or local to specify the domain the voxel server is serving
|
/// \param const char* domain domain name, IP address, or local to specify the domain the voxel server is serving
|
||||||
/// \param int port port the voxel server will listen on
|
/// \param int port port the voxel server will listen on
|
||||||
static void setupDomainAndPort(const char* domain, int port);
|
void setupStandAlone(const char* domain, int port);
|
||||||
|
|
||||||
|
bool wantsDebugVoxelSending() const { return _debugVoxelSending; }
|
||||||
|
bool wantsDebugVoxelReceiving() const { return _debugVoxelReceiving; }
|
||||||
|
bool wantShowAnimationDebug() const { return _shouldShowAnimationDebug; }
|
||||||
|
bool wantSendEnvironments() const { return _sendEnvironments; }
|
||||||
|
bool wantDumpVoxelsOnMove() const { return _dumpVoxelsOnMove; }
|
||||||
|
bool wantDisplayVoxelStats() const { return _displayVoxelStats; }
|
||||||
|
|
||||||
|
VoxelTree& getServerTree() { return _serverTree; }
|
||||||
|
JurisdictionMap* getJurisdiction() { return _jurisdiction; }
|
||||||
|
|
||||||
|
void lockTree() { pthread_mutex_lock(&_treeLock); }
|
||||||
|
void unlockTree() { pthread_mutex_unlock(&_treeLock); }
|
||||||
|
|
||||||
|
int getPacketsPerClientPerInterval() const { return _packetsPerClientPerInterval; }
|
||||||
|
bool getSendMinimalEnvironment() const { return _sendMinimalEnvironment; }
|
||||||
|
EnvironmentData* getEnvironmentData(int i) { return &_environmentData[i]; }
|
||||||
|
int getEnvironmentDataCount() const { return sizeof(_environmentData)/sizeof(EnvironmentData); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int _argc;
|
int _argc;
|
||||||
static const char** _argv;
|
const char** _argv;
|
||||||
static bool _dontKillOnMissingDomain;
|
bool _dontKillOnMissingDomain;
|
||||||
|
|
||||||
|
char _voxelPersistFilename[MAX_FILENAME_LENGTH];
|
||||||
|
int _packetsPerClientPerInterval;
|
||||||
|
VoxelTree _serverTree; // this IS a reaveraging tree
|
||||||
|
bool _wantVoxelPersist;
|
||||||
|
bool _wantLocalDomain;
|
||||||
|
bool _debugVoxelSending;
|
||||||
|
bool _shouldShowAnimationDebug;
|
||||||
|
bool _displayVoxelStats;
|
||||||
|
bool _debugVoxelReceiving;
|
||||||
|
bool _sendEnvironments;
|
||||||
|
bool _sendMinimalEnvironment;
|
||||||
|
bool _dumpVoxelsOnMove;
|
||||||
|
JurisdictionMap* _jurisdiction;
|
||||||
|
JurisdictionSender* _jurisdictionSender;
|
||||||
|
VoxelServerPacketProcessor* _voxelServerPacketProcessor;
|
||||||
|
VoxelPersistThread* _voxelPersistThread;
|
||||||
|
pthread_mutex_t _treeLock;
|
||||||
|
EnvironmentData _environmentData[3];
|
||||||
|
|
||||||
|
NodeWatcher _nodeWatcher; // used to cleanup AGENT data when agents are killed
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __voxel_server__VoxelServer__
|
#endif // __voxel_server__VoxelServer__
|
||||||
|
|
31
libraries/voxel-server-library/src/VoxelServerConsts.h
Normal file
31
libraries/voxel-server-library/src/VoxelServerConsts.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// VoxelServerConsts.h
|
||||||
|
// voxel-server
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 8/21/13
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __voxel_server__VoxelServerConsts__
|
||||||
|
#define __voxel_server__VoxelServerConsts__
|
||||||
|
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
#include <NodeList.h> // for MAX_PACKET_SIZE
|
||||||
|
#include <JurisdictionSender.h>
|
||||||
|
#include <VoxelTree.h>
|
||||||
|
|
||||||
|
#include "VoxelServerPacketProcessor.h"
|
||||||
|
|
||||||
|
|
||||||
|
const int MAX_FILENAME_LENGTH = 1024;
|
||||||
|
const int VOXEL_SIZE_BYTES = 3 + (3 * sizeof(float));
|
||||||
|
const int VOXELS_PER_PACKET = (MAX_PACKET_SIZE - 1) / VOXEL_SIZE_BYTES;
|
||||||
|
const int VOXEL_SEND_INTERVAL_USECS = 17 * 1000; // approximately 60fps
|
||||||
|
const int SENDING_TIME_TO_SPARE = 5 * 1000; // usec of sending interval to spare for calculating voxels
|
||||||
|
const int INTERVALS_PER_SECOND = 1000 * 1000 / VOXEL_SEND_INTERVAL_USECS;
|
||||||
|
const int ENVIRONMENT_SEND_INTERVAL_USECS = 1000000;
|
||||||
|
|
||||||
|
extern const char* LOCAL_VOXELS_PERSIST_FILE;
|
||||||
|
extern const char* VOXELS_PERSIST_FILE;
|
||||||
|
|
||||||
|
#endif // __voxel_server__VoxelServerConsts__
|
|
@ -12,33 +12,39 @@
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
|
||||||
#include "VoxelServer.h"
|
#include "VoxelServer.h"
|
||||||
#include "VoxelServerState.h"
|
#include "VoxelServerConsts.h"
|
||||||
#include "VoxelServerPacketProcessor.h"
|
#include "VoxelServerPacketProcessor.h"
|
||||||
|
|
||||||
|
|
||||||
|
VoxelServerPacketProcessor::VoxelServerPacketProcessor(VoxelServer* myServer) :
|
||||||
|
_myServer(myServer),
|
||||||
|
_receivedPacketCount(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||||
|
|
||||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||||
|
|
||||||
if (packetData[0] == PACKET_TYPE_SET_VOXEL || packetData[0] == PACKET_TYPE_SET_VOXEL_DESTRUCTIVE) {
|
if (packetData[0] == PACKET_TYPE_SET_VOXEL || packetData[0] == PACKET_TYPE_SET_VOXEL_DESTRUCTIVE) {
|
||||||
bool destructive = (packetData[0] == PACKET_TYPE_SET_VOXEL_DESTRUCTIVE);
|
bool destructive = (packetData[0] == PACKET_TYPE_SET_VOXEL_DESTRUCTIVE);
|
||||||
PerformanceWarning warn(::shouldShowAnimationDebug,
|
PerformanceWarning warn(_myServer->wantShowAnimationDebug(),
|
||||||
destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL",
|
destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL",
|
||||||
::shouldShowAnimationDebug);
|
_myServer->wantShowAnimationDebug());
|
||||||
|
|
||||||
::receivedPacketCount++;
|
_receivedPacketCount++;
|
||||||
|
|
||||||
unsigned short int itemNumber = (*((unsigned short int*)(packetData + numBytesPacketHeader)));
|
unsigned short int itemNumber = (*((unsigned short int*)(packetData + numBytesPacketHeader)));
|
||||||
if (::shouldShowAnimationDebug) {
|
if (_myServer->wantShowAnimationDebug()) {
|
||||||
printf("got %s - command from client receivedBytes=%ld itemNumber=%d\n",
|
printf("got %s - command from client receivedBytes=%ld itemNumber=%d\n",
|
||||||
destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL",
|
destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL",
|
||||||
packetLength, itemNumber);
|
packetLength, itemNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (::debugVoxelReceiving) {
|
if (_myServer->wantsDebugVoxelReceiving()) {
|
||||||
printf("got %s - %d command from client receivedBytes=%ld itemNumber=%d\n",
|
printf("got %s - %d command from client receivedBytes=%ld itemNumber=%d\n",
|
||||||
destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL",
|
destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL",
|
||||||
::receivedPacketCount, packetLength, itemNumber);
|
_receivedPacketCount, packetLength, itemNumber);
|
||||||
}
|
}
|
||||||
int atByte = numBytesPacketHeader + sizeof(itemNumber);
|
int atByte = numBytesPacketHeader + sizeof(itemNumber);
|
||||||
unsigned char* voxelData = (unsigned char*)&packetData[atByte];
|
unsigned char* voxelData = (unsigned char*)&packetData[atByte];
|
||||||
|
@ -48,7 +54,7 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned
|
||||||
int voxelDataSize = bytesRequiredForCodeLength(octets) + COLOR_SIZE_IN_BYTES;
|
int voxelDataSize = bytesRequiredForCodeLength(octets) + COLOR_SIZE_IN_BYTES;
|
||||||
int voxelCodeSize = bytesRequiredForCodeLength(octets);
|
int voxelCodeSize = bytesRequiredForCodeLength(octets);
|
||||||
|
|
||||||
if (::shouldShowAnimationDebug) {
|
if (_myServer->wantShowAnimationDebug()) {
|
||||||
int red = voxelData[voxelCodeSize + 0];
|
int red = voxelData[voxelCodeSize + 0];
|
||||||
int green = voxelData[voxelCodeSize + 1];
|
int green = voxelData[voxelCodeSize + 1];
|
||||||
int blue = voxelData[voxelCodeSize + 2];
|
int blue = voxelData[voxelCodeSize + 2];
|
||||||
|
@ -58,7 +64,7 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned
|
||||||
delete[] vertices;
|
delete[] vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
serverTree.readCodeColorBufferToTree(voxelData, destructive);
|
_myServer->getServerTree().readCodeColorBufferToTree(voxelData, destructive);
|
||||||
// skip to next
|
// skip to next
|
||||||
voxelData += voxelDataSize;
|
voxelData += voxelDataSize;
|
||||||
atByte += voxelDataSize;
|
atByte += voxelDataSize;
|
||||||
|
@ -73,9 +79,9 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned
|
||||||
} else if (packetData[0] == PACKET_TYPE_ERASE_VOXEL) {
|
} else if (packetData[0] == PACKET_TYPE_ERASE_VOXEL) {
|
||||||
|
|
||||||
// Send these bits off to the VoxelTree class to process them
|
// Send these bits off to the VoxelTree class to process them
|
||||||
pthread_mutex_lock(&::treeLock);
|
_myServer->lockTree();
|
||||||
::serverTree.processRemoveVoxelBitstream((unsigned char*)packetData, packetLength);
|
_myServer->getServerTree().processRemoveVoxelBitstream((unsigned char*)packetData, packetLength);
|
||||||
pthread_mutex_unlock(&::treeLock);
|
_myServer->unlockTree();
|
||||||
|
|
||||||
// Make sure our Node and NodeList knows we've heard from this node.
|
// Make sure our Node and NodeList knows we've heard from this node.
|
||||||
Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||||
|
|
|
@ -12,11 +12,20 @@
|
||||||
#define __voxel_server__VoxelServerPacketProcessor__
|
#define __voxel_server__VoxelServerPacketProcessor__
|
||||||
|
|
||||||
#include <ReceivedPacketProcessor.h>
|
#include <ReceivedPacketProcessor.h>
|
||||||
|
class VoxelServer;
|
||||||
|
|
||||||
/// Handles processing of incoming network packets for the voxel-server. As with other ReceivedPacketProcessor classes
|
/// Handles processing of incoming network packets for the voxel-server. As with other ReceivedPacketProcessor classes
|
||||||
/// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket()
|
/// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket()
|
||||||
class VoxelServerPacketProcessor : public ReceivedPacketProcessor {
|
class VoxelServerPacketProcessor : public ReceivedPacketProcessor {
|
||||||
|
|
||||||
|
public:
|
||||||
|
VoxelServerPacketProcessor(VoxelServer* myServer);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||||
|
|
||||||
|
private:
|
||||||
|
VoxelServer* _myServer;
|
||||||
|
int _receivedPacketCount;
|
||||||
};
|
};
|
||||||
#endif // __voxel_server__VoxelServerPacketProcessor__
|
#endif // __voxel_server__VoxelServerPacketProcessor__
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
// VoxelServer.h
|
|
||||||
// voxel-server
|
|
||||||
//
|
|
||||||
// Created by Brad Hefta-Gaub on 8/21/13
|
|
||||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __voxel_server__VoxelServerState__
|
|
||||||
#define __voxel_server__VoxelServerState__
|
|
||||||
|
|
||||||
#include <SharedUtil.h>
|
|
||||||
#include <NodeList.h> // for MAX_PACKET_SIZE
|
|
||||||
#include <JurisdictionSender.h>
|
|
||||||
#include <VoxelTree.h>
|
|
||||||
|
|
||||||
#include "VoxelServerPacketProcessor.h"
|
|
||||||
|
|
||||||
|
|
||||||
const int MAX_FILENAME_LENGTH = 1024;
|
|
||||||
const int VOXEL_SIZE_BYTES = 3 + (3 * sizeof(float));
|
|
||||||
const int VOXELS_PER_PACKET = (MAX_PACKET_SIZE - 1) / VOXEL_SIZE_BYTES;
|
|
||||||
const int MIN_BRIGHTNESS = 64;
|
|
||||||
const float DEATH_STAR_RADIUS = 4.0;
|
|
||||||
const float MAX_CUBE = 0.05f;
|
|
||||||
const int VOXEL_SEND_INTERVAL_USECS = 17 * 1000; // approximately 60fps
|
|
||||||
const int SENDING_TIME_TO_SPARE = 5 * 1000; // usec of sending interval to spare for calculating voxels
|
|
||||||
const int INTERVALS_PER_SECOND = 1000 * 1000 / VOXEL_SEND_INTERVAL_USECS;
|
|
||||||
const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4;
|
|
||||||
const int ENVIRONMENT_SEND_INTERVAL_USECS = 1000000;
|
|
||||||
|
|
||||||
extern const char* LOCAL_VOXELS_PERSIST_FILE;
|
|
||||||
extern const char* VOXELS_PERSIST_FILE;
|
|
||||||
extern char voxelPersistFilename[MAX_FILENAME_LENGTH];
|
|
||||||
extern int PACKETS_PER_CLIENT_PER_INTERVAL;
|
|
||||||
|
|
||||||
extern VoxelTree serverTree; // this IS a reaveraging tree
|
|
||||||
extern bool wantVoxelPersist;
|
|
||||||
extern bool wantLocalDomain;
|
|
||||||
extern bool debugVoxelSending;
|
|
||||||
extern bool shouldShowAnimationDebug;
|
|
||||||
extern bool displayVoxelStats;
|
|
||||||
extern bool debugVoxelReceiving;
|
|
||||||
extern bool sendEnvironments;
|
|
||||||
extern bool sendMinimalEnvironment;
|
|
||||||
extern bool dumpVoxelsOnMove;
|
|
||||||
extern int receivedPacketCount;
|
|
||||||
extern JurisdictionMap* jurisdiction;
|
|
||||||
extern JurisdictionSender* jurisdictionSender;
|
|
||||||
extern VoxelServerPacketProcessor* voxelServerPacketProcessor;
|
|
||||||
extern pthread_mutex_t treeLock;
|
|
||||||
|
|
||||||
#endif // __voxel_server__VoxelServerState__
|
|
|
@ -29,19 +29,19 @@ int main(int argc, const char * argv[]) {
|
||||||
}
|
}
|
||||||
printf("portParameter=%s listenPort=%d\n", portParameter, listenPort);
|
printf("portParameter=%s listenPort=%d\n", portParameter, listenPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VoxelServer ourVoxelServer(Assignment::CreateCommand);
|
||||||
|
|
||||||
if (wantLocalDomain) {
|
if (wantLocalDomain) {
|
||||||
VoxelServer::setupDomainAndPort(local, listenPort);
|
ourVoxelServer.setupStandAlone(local, listenPort);
|
||||||
} else {
|
} else {
|
||||||
if (domainIP) {
|
if (domainIP) {
|
||||||
VoxelServer::setupDomainAndPort(domainIP, listenPort);
|
ourVoxelServer.setupStandAlone(domainIP, listenPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelServer::setArguments(argc, const_cast<char**>(argv));
|
ourVoxelServer.setArguments(argc, const_cast<char**>(argv));
|
||||||
|
ourVoxelServer.run();
|
||||||
VoxelServer dummyAssignedVoxelServer(Assignment::CreateCommand);
|
|
||||||
dummyAssignedVoxelServer.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue