mirror of
https://github.com/lubosz/overte.git
synced 2025-04-08 03:42:09 +02:00
resolve conflicts on merge with upstream master
This commit is contained in:
commit
74a0b8a7b5
27 changed files with 503 additions and 335 deletions
|
@ -25,9 +25,11 @@ link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
|||
link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(voxel-server-library ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link the stk library
|
||||
set(STK_ROOT_DIR ${ROOT_DIR}/externals/stk)
|
||||
find_package(STK REQUIRED)
|
||||
target_link_libraries(${TARGET_NAME} ${STK_LIBRARIES})
|
||||
include_directories(${STK_INCLUDE_DIRS})
|
||||
include_directories(${STK_INCLUDE_DIRS})
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <VoxelServer.h>
|
||||
|
||||
const long long ASSIGNMENT_REQUEST_INTERVAL_USECS = 1 * 1000 * 1000;
|
||||
const char PARENT_TARGET_NAME[] = "assignment-client-monitor";
|
||||
|
@ -97,6 +98,8 @@ void childClient() {
|
|||
AudioMixer::run();
|
||||
} else if (deployedAssignment.getType() == Assignment::AvatarMixerType) {
|
||||
AvatarMixer::run();
|
||||
} else if (deployedAssignment.getType() == Assignment::VoxelServerType) {
|
||||
VoxelServer::run();
|
||||
} else {
|
||||
// figure out the URL for the script for this agent assignment
|
||||
QString scriptURLString("http://%1:8080/assignment/%2");
|
||||
|
|
|
@ -10,9 +10,9 @@ setup_hifi_project(${TARGET_NAME} TRUE)
|
|||
|
||||
# setup a library for civetweb and link it to the domain-server
|
||||
FILE(GLOB CIVETWEB_SRCS external/civetweb/src/*.c)
|
||||
add_library(CIVETWEB ${CIVETWEB_SRCS})
|
||||
add_library(civetweb ${CIVETWEB_SRCS})
|
||||
include_directories(external/civetweb/include)
|
||||
target_link_libraries(${TARGET_NAME} CIVETWEB)
|
||||
target_link_libraries(${TARGET_NAME} civetweb)
|
||||
|
||||
# remove and then copy the files for the webserver
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
|
@ -25,4 +25,9 @@ add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
|||
|
||||
# link the shared hifi library
|
||||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link dl library on UNIX for civetweb
|
||||
if (UNIX AND NOT APPLE)
|
||||
target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS})
|
||||
endif (UNIX AND NOT APPLE)
|
|
@ -155,6 +155,10 @@ int main(int argc, const char* argv[]) {
|
|||
Assignment avatarMixerAssignment(Assignment::CreateCommand,
|
||||
Assignment::AvatarMixerType,
|
||||
Assignment::LocalLocation);
|
||||
|
||||
Assignment voxelServerAssignment(Assignment::CreateCommand,
|
||||
Assignment::VoxelServerType,
|
||||
Assignment::LocalLocation);
|
||||
|
||||
// construct a local socket to send with our created assignments to the global AS
|
||||
sockaddr_in localSocket = {};
|
||||
|
@ -168,8 +172,6 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
QString documentRoot = QString("%1/resources/web").arg(QCoreApplication::applicationDirPath());
|
||||
|
||||
qDebug() << documentRoot << "\n";
|
||||
|
||||
// list of options. Last element must be NULL.
|
||||
const char *options[] = {"listening_ports", "8080",
|
||||
"document_root", documentRoot.toStdString().c_str(), NULL};
|
||||
|
@ -180,6 +182,9 @@ int main(int argc, const char* argv[]) {
|
|||
// Start the web server.
|
||||
ctx = mg_start(&callbacks, NULL, options);
|
||||
|
||||
// wait to check on voxel-servers till we've given our NodeList a chance to get a good list
|
||||
int checkForVoxelServerAttempt = 0;
|
||||
|
||||
while (true) {
|
||||
|
||||
::assignmentQueueMutex.lock();
|
||||
|
@ -196,6 +201,27 @@ int main(int argc, const char* argv[]) {
|
|||
qDebug("Missing an audio mixer and assignment not in queue. Adding.\n");
|
||||
::assignmentQueue.push_front(&audioMixerAssignment);
|
||||
}
|
||||
|
||||
// Now handle voxel servers. Couple of things are special about voxel servers.
|
||||
// 1) They can run standalone, and so we want to wait to ask for an assignment until we've given them sufficient
|
||||
// time to check in with us. So we will look for them, but we want actually add assignments unless we haven't
|
||||
// seen one after a few tries.
|
||||
// 2) They aren't soloNodeOfType() so we have to count them.
|
||||
int voxelServerCount = 0;
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
voxelServerCount++;
|
||||
}
|
||||
}
|
||||
const int MIN_VOXEL_SERVER_CHECKS = 10;
|
||||
if (checkForVoxelServerAttempt > MIN_VOXEL_SERVER_CHECKS &&
|
||||
voxelServerCount == 0 &&
|
||||
std::find(::assignmentQueue.begin(), ::assignmentQueue.end(), &voxelServerAssignment) == ::assignmentQueue.end()) {
|
||||
qDebug("Missing a Voxel Server and assignment not in queue. Adding.\n");
|
||||
::assignmentQueue.push_front(&voxelServerAssignment);
|
||||
}
|
||||
checkForVoxelServerAttempt++;
|
||||
|
||||
::assignmentQueueMutex.unlock();
|
||||
|
||||
while (nodeList->getNodeSocket()->receive((sockaddr *)&nodePublicAddress, packetData, &receivedBytes) &&
|
||||
|
|
|
@ -723,7 +723,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
// Always render other people, and render myself when beyond threshold distance
|
||||
if (b == BODY_BALL_HEAD_BASE) { // the head is rendered as a special
|
||||
if (alpha > 0.0f) {
|
||||
_head.render(alpha);
|
||||
_head.render(alpha, false);
|
||||
}
|
||||
} else if (alpha > 0.0f) {
|
||||
// Render the body ball sphere
|
||||
|
@ -767,7 +767,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
|
||||
if (alpha > 0.0f) {
|
||||
_voxels.render(false);
|
||||
_head.render(alpha);
|
||||
_head.render(alpha, false);
|
||||
}
|
||||
}
|
||||
_hand.render(lookingInMirror);
|
||||
|
|
|
@ -322,7 +322,7 @@ void Head::calculateGeometry() {
|
|||
+ up * _scale * NOSE_UPTURN;
|
||||
}
|
||||
|
||||
void Head::render(float alpha) {
|
||||
void Head::render(float alpha, bool isMine) {
|
||||
_renderAlpha = alpha;
|
||||
|
||||
if (!_face.render(alpha)) {
|
||||
|
@ -331,7 +331,7 @@ void Head::render(float alpha) {
|
|||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_RESCALE_NORMAL);
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::UsePerlinFace)) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::UsePerlinFace) && isMine) {
|
||||
_perlinFace.render();
|
||||
} else {
|
||||
renderMohawk();
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
void init();
|
||||
void reset();
|
||||
void simulate(float deltaTime, bool isMine, float gyroCameraSensitivity);
|
||||
void render(float alpha);
|
||||
void render(float alpha, bool isMine);
|
||||
void renderMohawk();
|
||||
|
||||
void setScale(float scale);
|
||||
|
|
|
@ -557,7 +557,7 @@ void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
// Always render other people, and render myself when beyond threshold distance
|
||||
if (b == BODY_BALL_HEAD_BASE) { // the head is rendered as a special
|
||||
if (alpha > 0.0f) {
|
||||
_head.render(alpha);
|
||||
_head.render(alpha, true);
|
||||
}
|
||||
} else if (alpha > 0.0f) {
|
||||
// Render the body ball sphere
|
||||
|
@ -614,7 +614,7 @@ void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
|
||||
if (alpha > 0.0f) {
|
||||
_voxels.render(false);
|
||||
_head.render(alpha);
|
||||
_head.render(alpha, true);
|
||||
}
|
||||
}
|
||||
_hand.render(lookingInMirror);
|
||||
|
|
|
@ -28,6 +28,10 @@ Faceshift::Faceshift() :
|
|||
_rightBlink(0.0f),
|
||||
_leftEyeOpen(0.0f),
|
||||
_rightEyeOpen(0.0f),
|
||||
_leftBlinkIndex(0), // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes
|
||||
_rightBlinkIndex(1),
|
||||
_leftEyeOpenIndex(8),
|
||||
_rightEyeOpenIndex(9),
|
||||
_browDownLeft(0.0f),
|
||||
_browDownRight(0.0f),
|
||||
_browUpCenter(0.0f),
|
||||
|
@ -35,6 +39,7 @@ Faceshift::Faceshift() :
|
|||
_browUpRight(0.0f),
|
||||
_browDownLeftIndex(-1),
|
||||
_browDownRightIndex(-1),
|
||||
_browUpCenterIndex(16),
|
||||
_browUpLeftIndex(-1),
|
||||
_browUpRightIndex(-1),
|
||||
_mouthSize(0.0f),
|
||||
|
@ -42,11 +47,6 @@ Faceshift::Faceshift() :
|
|||
_mouthSmileRight(0),
|
||||
_mouthSmileLeftIndex(-1),
|
||||
_mouthSmileRightIndex(0),
|
||||
_leftBlinkIndex(0), // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes
|
||||
_rightBlinkIndex(1),
|
||||
_leftEyeOpenIndex(8),
|
||||
_rightEyeOpenIndex(9),
|
||||
_browUpCenterIndex(16),
|
||||
_jawOpenIndex(21),
|
||||
_longTermAverageEyePitch(0.0f),
|
||||
_longTermAverageEyeYaw(0.0f),
|
||||
|
|
|
@ -23,6 +23,7 @@ public:
|
|||
AudioMixerType,
|
||||
AvatarMixerType,
|
||||
AgentType,
|
||||
VoxelServerType,
|
||||
AllTypes
|
||||
};
|
||||
|
||||
|
|
37
libraries/voxel-server-library/CMakeLists.txt
Normal file
37
libraries/voxel-server-library/CMakeLists.txt
Normal file
|
@ -0,0 +1,37 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
set(ROOT_DIR ../..)
|
||||
set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
|
||||
|
||||
# setup for find modules
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules/")
|
||||
|
||||
set(TARGET_NAME voxel-server-library)
|
||||
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
|
||||
include(${MACRO_DIR}/SetupHifiLibrary.cmake)
|
||||
setup_hifi_library(${TARGET_NAME})
|
||||
|
||||
qt5_use_modules(${TARGET_NAME} Widgets)
|
||||
|
||||
include(${MACRO_DIR}/IncludeGLM.cmake)
|
||||
include_glm(${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link ZLIB
|
||||
find_package(ZLIB)
|
||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES})
|
||||
|
||||
# link in the shared library
|
||||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link in the hifi voxels library
|
||||
link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link in the hifi avatars library
|
||||
link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR})
|
|
@ -11,9 +11,12 @@
|
|||
#include <NodeList.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <EnvironmentData.h>
|
||||
extern EnvironmentData environmentData[3];
|
||||
|
||||
#include "VoxelSendThread.h"
|
||||
#include "VoxelServer.h"
|
||||
#include "VoxelServerState.h"
|
||||
|
||||
VoxelSendThread::VoxelSendThread(uint16_t nodeID) :
|
||||
_nodeID(nodeID) {
|
349
libraries/voxel-server-library/src/VoxelServer.cpp
Normal file
349
libraries/voxel-server-library/src/VoxelServer.cpp
Normal file
|
@ -0,0 +1,349 @@
|
|||
//
|
||||
// VoxelServer.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 9/16/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#include <OctalCode.h>
|
||||
#include <NodeList.h>
|
||||
#include <NodeTypes.h>
|
||||
#include <EnvironmentData.h>
|
||||
#include <VoxelTree.h>
|
||||
#include "VoxelNodeData.h"
|
||||
#include <SharedUtil.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SceneUtils.h>
|
||||
#include <PerfStat.h>
|
||||
#include <JurisdictionSender.h>
|
||||
|
||||
#include "NodeWatcher.h"
|
||||
#include "VoxelPersistThread.h"
|
||||
#include "VoxelSendThread.h"
|
||||
#include "VoxelServerPacketProcessor.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Syssocket.h"
|
||||
#include "Systime.h"
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include "VoxelServer.h"
|
||||
#include "VoxelServerState.h"
|
||||
|
||||
const char* LOCAL_VOXELS_PERSIST_FILE = "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) {
|
||||
if (newNode->getLinkedData() == NULL) {
|
||||
newNode->setLinkedData(new VoxelNodeData(newNode));
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelServer::setArguments(int argc, char** argv) {
|
||||
_argc = argc;
|
||||
_argv = const_cast<const char**>(argv);
|
||||
}
|
||||
|
||||
void VoxelServer::setupDomainAndPort(const char* domain, int port) {
|
||||
NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, port);
|
||||
|
||||
// Handle Local Domain testing with the --local command line
|
||||
const char* local = "--local";
|
||||
::wantLocalDomain = strcmp(domain, local) == 0;
|
||||
if (::wantLocalDomain) {
|
||||
printf("Local Domain MODE!\n");
|
||||
NodeList::getInstance()->setDomainIPToLocalhost();
|
||||
} else {
|
||||
if (domain) {
|
||||
NodeList::getInstance()->setDomainHostname(domain);
|
||||
}
|
||||
}
|
||||
|
||||
// If we're running in standalone mode, we don't want to kill ourselves when we haven't heard from a domain
|
||||
_dontKillOnMissingDomain = true;
|
||||
}
|
||||
|
||||
//int main(int argc, const char * argv[]) {
|
||||
void VoxelServer::run() {
|
||||
pthread_mutex_init(&::treeLock, NULL);
|
||||
|
||||
qInstallMessageHandler(sharedMessageHandler);
|
||||
|
||||
const char* JURISDICTION_FILE = "--jurisdictionFile";
|
||||
const char* jurisdictionFile = getCmdOption(_argc, _argv, JURISDICTION_FILE);
|
||||
if (jurisdictionFile) {
|
||||
printf("jurisdictionFile=%s\n", jurisdictionFile);
|
||||
|
||||
printf("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
|
||||
jurisdiction = new JurisdictionMap(jurisdictionFile);
|
||||
printf("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
|
||||
} else {
|
||||
const char* JURISDICTION_ROOT = "--jurisdictionRoot";
|
||||
const char* jurisdictionRoot = getCmdOption(_argc, _argv, JURISDICTION_ROOT);
|
||||
if (jurisdictionRoot) {
|
||||
printf("jurisdictionRoot=%s\n", jurisdictionRoot);
|
||||
}
|
||||
|
||||
const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes";
|
||||
const char* jurisdictionEndNodes = getCmdOption(_argc, _argv, JURISDICTION_ENDNODES);
|
||||
if (jurisdictionEndNodes) {
|
||||
printf("jurisdictionEndNodes=%s\n", jurisdictionEndNodes);
|
||||
}
|
||||
|
||||
if (jurisdictionRoot || jurisdictionEndNodes) {
|
||||
::jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
|
||||
}
|
||||
}
|
||||
|
||||
// should we send environments? Default is yes, but this command line suppresses sending
|
||||
const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove";
|
||||
::dumpVoxelsOnMove = cmdOptionExists(_argc, _argv, DUMP_VOXELS_ON_MOVE);
|
||||
printf("dumpVoxelsOnMove=%s\n", debug::valueOf(::dumpVoxelsOnMove));
|
||||
|
||||
// should we send environments? Default is yes, but this command line suppresses sending
|
||||
const char* DONT_SEND_ENVIRONMENTS = "--dontSendEnvironments";
|
||||
bool dontSendEnvironments = getCmdOption(_argc, _argv, DONT_SEND_ENVIRONMENTS);
|
||||
if (dontSendEnvironments) {
|
||||
printf("Sending environments suppressed...\n");
|
||||
::sendEnvironments = false;
|
||||
} else {
|
||||
// should we send environments? Default is yes, but this command line suppresses sending
|
||||
const char* MINIMAL_ENVIRONMENT = "--MinimalEnvironment";
|
||||
::sendMinimalEnvironment = getCmdOption(_argc, _argv, MINIMAL_ENVIRONMENT);
|
||||
printf("Using Minimal Environment=%s\n", debug::valueOf(::sendMinimalEnvironment));
|
||||
}
|
||||
printf("Sending environments=%s\n", debug::valueOf(::sendEnvironments));
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
nodeList->setOwnerType(NODE_TYPE_VOXEL_SERVER);
|
||||
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
// tell our NodeList about our desire to get notifications
|
||||
nodeList->addHook(&nodeWatcher);
|
||||
nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;
|
||||
|
||||
nodeList->startSilentNodeRemovalThread();
|
||||
srand((unsigned)time(0));
|
||||
|
||||
const char* DISPLAY_VOXEL_STATS = "--displayVoxelStats";
|
||||
::displayVoxelStats = getCmdOption(_argc, _argv, DISPLAY_VOXEL_STATS);
|
||||
printf("displayVoxelStats=%s\n", debug::valueOf(::displayVoxelStats));
|
||||
|
||||
const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending";
|
||||
::debugVoxelSending = getCmdOption(_argc, _argv, DEBUG_VOXEL_SENDING);
|
||||
printf("debugVoxelSending=%s\n", debug::valueOf(::debugVoxelSending));
|
||||
|
||||
const char* DEBUG_VOXEL_RECEIVING = "--debugVoxelReceiving";
|
||||
::debugVoxelReceiving = getCmdOption(_argc, _argv, DEBUG_VOXEL_RECEIVING);
|
||||
printf("debugVoxelReceiving=%s\n", debug::valueOf(::debugVoxelReceiving));
|
||||
|
||||
const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug";
|
||||
::shouldShowAnimationDebug = getCmdOption(_argc, _argv, WANT_ANIMATION_DEBUG);
|
||||
printf("shouldShowAnimationDebug=%s\n", debug::valueOf(::shouldShowAnimationDebug));
|
||||
|
||||
// By default we will voxel persist, if you want to disable this, then pass in this parameter
|
||||
const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
|
||||
if ( getCmdOption(_argc, _argv, NO_VOXEL_PERSIST)) {
|
||||
::wantVoxelPersist = false;
|
||||
}
|
||||
printf("wantVoxelPersist=%s\n", debug::valueOf(::wantVoxelPersist));
|
||||
|
||||
// if we want Voxel Persistence, load the local file now...
|
||||
bool persistantFileRead = false;
|
||||
if (::wantVoxelPersist) {
|
||||
|
||||
// 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* voxelsPersistFilenameParameter = getCmdOption(_argc, _argv, VOXELS_PERSIST_FILENAME);
|
||||
if (voxelsPersistFilenameParameter) {
|
||||
strcpy(voxelPersistFilename, voxelsPersistFilenameParameter);
|
||||
} else {
|
||||
//strcpy(voxelPersistFilename, ::wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
|
||||
strcpy(voxelPersistFilename, LOCAL_VOXELS_PERSIST_FILE);
|
||||
}
|
||||
|
||||
printf("loading voxels from file: %s...\n", voxelPersistFilename);
|
||||
|
||||
persistantFileRead = ::serverTree.readFromSVOFile(::voxelPersistFilename);
|
||||
if (persistantFileRead) {
|
||||
PerformanceWarning warn(::shouldShowAnimationDebug,
|
||||
"persistVoxelsWhenDirty() - reaverageVoxelColors()", ::shouldShowAnimationDebug);
|
||||
|
||||
// after done inserting all these voxels, then reaverage colors
|
||||
serverTree.reaverageVoxelColors(serverTree.rootNode);
|
||||
printf("Voxels reAveraged\n");
|
||||
}
|
||||
|
||||
::serverTree.clearDirtyBit(); // the tree is clean since we just loaded it
|
||||
printf("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
|
||||
unsigned long nodeCount = ::serverTree.rootNode->getSubTreeNodeCount();
|
||||
unsigned long internalNodeCount = ::serverTree.rootNode->getSubTreeInternalNodeCount();
|
||||
unsigned long leafNodeCount = ::serverTree.rootNode->getSubTreeLeafNodeCount();
|
||||
printf("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
|
||||
|
||||
// now set up VoxelPersistThread
|
||||
::voxelPersistThread = new VoxelPersistThread(&::serverTree, ::voxelPersistFilename);
|
||||
if (::voxelPersistThread) {
|
||||
::voxelPersistThread->initialize(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the user passed in a command line option for loading an old style local
|
||||
// Voxel File. If so, load it now. This is not the same as a voxel persist file
|
||||
const char* INPUT_FILE = "-i";
|
||||
const char* voxelsFilename = getCmdOption(_argc, _argv, INPUT_FILE);
|
||||
if (voxelsFilename) {
|
||||
serverTree.readFromSVOFile(voxelsFilename);
|
||||
}
|
||||
|
||||
// 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* packetsPerSecond = getCmdOption(_argc, _argv, PACKETS_PER_SECOND);
|
||||
if (packetsPerSecond) {
|
||||
PACKETS_PER_CLIENT_PER_INTERVAL = atoi(packetsPerSecond)/INTERVALS_PER_SECOND;
|
||||
if (PACKETS_PER_CLIENT_PER_INTERVAL < 1) {
|
||||
PACKETS_PER_CLIENT_PER_INTERVAL = 1;
|
||||
}
|
||||
printf("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, PACKETS_PER_CLIENT_PER_INTERVAL);
|
||||
}
|
||||
|
||||
// for now, initialize the environments with fixed values
|
||||
environmentData[1].setID(1);
|
||||
environmentData[1].setGravity(1.0f);
|
||||
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].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f);
|
||||
environmentData[2].setID(2);
|
||||
environmentData[2].setGravity(1.0f);
|
||||
environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
|
||||
environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
|
||||
environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f);
|
||||
environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue
|
||||
|
||||
sockaddr senderAddress;
|
||||
|
||||
unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE];
|
||||
ssize_t packetLength;
|
||||
|
||||
timeval lastDomainServerCheckIn = {};
|
||||
|
||||
// set up our jurisdiction broadcaster...
|
||||
::jurisdictionSender = new JurisdictionSender(::jurisdiction);
|
||||
if (::jurisdictionSender) {
|
||||
::jurisdictionSender->initialize(true);
|
||||
}
|
||||
|
||||
// set up our VoxelServerPacketProcessor
|
||||
::voxelServerPacketProcessor = new VoxelServerPacketProcessor();
|
||||
if (::voxelServerPacketProcessor) {
|
||||
::voxelServerPacketProcessor->initialize(true);
|
||||
}
|
||||
|
||||
// loop to send to nodes requesting data
|
||||
while (true) {
|
||||
|
||||
if (!_dontKillOnMissingDomain &&
|
||||
NodeList::getInstance()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
|
||||
break;
|
||||
}
|
||||
|
||||
// send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
|
||||
if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
|
||||
gettimeofday(&lastDomainServerCheckIn, NULL);
|
||||
NodeList::getInstance()->sendDomainServerCheckIn();
|
||||
}
|
||||
|
||||
if (nodeList->getNodeSocket()->receive(&senderAddress, packetData, &packetLength) &&
|
||||
packetVersionMatch(packetData)) {
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
|
||||
if (packetData[0] == PACKET_TYPE_HEAD_DATA) {
|
||||
// If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we
|
||||
// need to make sure we have it in our nodeList.
|
||||
uint16_t nodeID = 0;
|
||||
unpackNodeId(packetData + numBytesPacketHeader, &nodeID);
|
||||
Node* node = NodeList::getInstance()->addOrUpdateNode(&senderAddress,
|
||||
&senderAddress,
|
||||
NODE_TYPE_AGENT,
|
||||
nodeID);
|
||||
|
||||
NodeList::getInstance()->updateNodeWithData(node, packetData, packetLength);
|
||||
} else if (packetData[0] == PACKET_TYPE_PING) {
|
||||
// If the packet is a ping, let processNodeData handle it.
|
||||
NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
|
||||
} else if (packetData[0] == PACKET_TYPE_DOMAIN) {
|
||||
NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
|
||||
} else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
|
||||
if (::jurisdictionSender) {
|
||||
::jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength);
|
||||
}
|
||||
} else if (::voxelServerPacketProcessor) {
|
||||
::voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength);
|
||||
} else {
|
||||
printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (::jurisdiction) {
|
||||
delete ::jurisdiction;
|
||||
}
|
||||
|
||||
if (::jurisdictionSender) {
|
||||
::jurisdictionSender->terminate();
|
||||
delete ::jurisdictionSender;
|
||||
}
|
||||
|
||||
if (::voxelServerPacketProcessor) {
|
||||
::voxelServerPacketProcessor->terminate();
|
||||
delete ::voxelServerPacketProcessor;
|
||||
}
|
||||
|
||||
if (::voxelPersistThread) {
|
||||
::voxelPersistThread->terminate();
|
||||
delete ::voxelPersistThread;
|
||||
}
|
||||
|
||||
// tell our NodeList we're done with notifications
|
||||
nodeList->removeHook(&nodeWatcher);
|
||||
|
||||
pthread_mutex_destroy(&::treeLock);
|
||||
}
|
||||
|
||||
|
36
libraries/voxel-server-library/src/VoxelServer.h
Normal file
36
libraries/voxel-server-library/src/VoxelServer.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
// 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__VoxelServer__
|
||||
#define __voxel_server__VoxelServer__
|
||||
|
||||
/// Handles assignments of type VoxelServer - sending voxels to various clients.
|
||||
class VoxelServer {
|
||||
public:
|
||||
/// runs the voxel server assignment
|
||||
static void run();
|
||||
|
||||
/// allows setting of run arguments
|
||||
static void setArguments(int argc, char** argv);
|
||||
|
||||
/// 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
|
||||
/// 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 int port port the voxel server will listen on
|
||||
static void setupDomainAndPort(const char* domain, int port);
|
||||
|
||||
private:
|
||||
static int _argc;
|
||||
static const char** _argv;
|
||||
static bool _dontKillOnMissingDomain;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // __voxel_server__VoxelServer__
|
|
@ -12,6 +12,7 @@
|
|||
#include <PerfStat.h>
|
||||
|
||||
#include "VoxelServer.h"
|
||||
#include "VoxelServerState.h"
|
||||
#include "VoxelServerPacketProcessor.h"
|
||||
|
||||
|
|
@ -6,12 +6,11 @@
|
|||
//
|
||||
//
|
||||
|
||||
#ifndef __voxel_server__VoxelServer__
|
||||
#define __voxel_server__VoxelServer__
|
||||
#ifndef __voxel_server__VoxelServerState__
|
||||
#define __voxel_server__VoxelServerState__
|
||||
|
||||
#include <SharedUtil.h>
|
||||
#include <NodeList.h> // for MAX_PACKET_SIZE
|
||||
#include <EnvironmentData.h>
|
||||
#include <JurisdictionSender.h>
|
||||
#include <VoxelTree.h>
|
||||
|
||||
|
@ -19,7 +18,6 @@
|
|||
|
||||
|
||||
const int MAX_FILENAME_LENGTH = 1024;
|
||||
const int VOXEL_LISTEN_PORT = 40106;
|
||||
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;
|
||||
|
@ -46,13 +44,10 @@ extern bool debugVoxelReceiving;
|
|||
extern bool sendEnvironments;
|
||||
extern bool sendMinimalEnvironment;
|
||||
extern bool dumpVoxelsOnMove;
|
||||
extern EnvironmentData environmentData[3];
|
||||
extern int receivedPacketCount;
|
||||
extern JurisdictionMap* jurisdiction;
|
||||
extern JurisdictionSender* jurisdictionSender;
|
||||
extern VoxelServerPacketProcessor* voxelServerPacketProcessor;
|
||||
extern pthread_mutex_t treeLock;
|
||||
|
||||
|
||||
|
||||
#endif // __voxel_server__VoxelServer__
|
||||
#endif // __voxel_server__VoxelServerState__
|
|
@ -24,8 +24,10 @@ const glm::vec3 IDENTITY_FRONT = glm::vec3( 0.0f, 0.0f,-1.0f);
|
|||
const bool LOW_RES_MONO = false; // while in "low res mode" do voxels switch to monochrome
|
||||
const uint64_t CHANGE_FUDGE = 1000 * 200; // useconds of fudge in determining if we want to resend changed voxels
|
||||
|
||||
const int TREE_SCALE = 128; // This is the number of meters of the 0.0 to 1.0 voxel universe
|
||||
const float VOXEL_SIZE_SCALE = 50000.0f; // This controls the LOD bigger will make smaller voxels visible at greater distance
|
||||
const int TREE_SCALE = 16384; // ~10 miles.. This is the number of meters of the 0.0 to 1.0 voxel universe
|
||||
|
||||
// This controls the LOD. Larger number will make smaller voxels visible at greater distance.
|
||||
const float VOXEL_SIZE_SCALE = TREE_SCALE * 400.0f;
|
||||
|
||||
const int NUMBER_OF_CHILDREN = 8;
|
||||
const int MAX_VOXEL_PACKET_SIZE = 1492;
|
||||
|
|
|
@ -26,3 +26,5 @@ link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR})
|
|||
# link in the hifi avatars library
|
||||
link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link in the hifi voxel-server-library
|
||||
link_hifi_library(voxel-server-library ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
|
|
@ -6,73 +6,18 @@
|
|||
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#include <OctalCode.h>
|
||||
#include <NodeList.h>
|
||||
#include <NodeTypes.h>
|
||||
#include <EnvironmentData.h>
|
||||
#include <VoxelTree.h>
|
||||
#include "VoxelNodeData.h"
|
||||
#include <SharedUtil.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SceneUtils.h>
|
||||
#include <PerfStat.h>
|
||||
#include <JurisdictionSender.h>
|
||||
#include <VoxelServer.h>
|
||||
const int VOXEL_LISTEN_PORT = 40106;
|
||||
|
||||
#include "NodeWatcher.h"
|
||||
#include "VoxelPersistThread.h"
|
||||
#include "VoxelSendThread.h"
|
||||
#include "VoxelServerPacketProcessor.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Syssocket.h"
|
||||
#include "Systime.h"
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include "VoxelServer.h"
|
||||
|
||||
const char* LOCAL_VOXELS_PERSIST_FILE = "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
|
||||
|
||||
void attachVoxelNodeDataToNode(Node* newNode) {
|
||||
if (newNode->getLinkedData() == NULL) {
|
||||
newNode->setLinkedData(new VoxelNodeData(newNode));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
pthread_mutex_init(&::treeLock, NULL);
|
||||
|
||||
qInstallMessageHandler(sharedMessageHandler);
|
||||
|
||||
|
||||
// Handle Local Domain testing with the --local command line
|
||||
const char* local = "--local";
|
||||
bool wantLocalDomain = cmdOptionExists(argc, argv, local);
|
||||
const char* domainIP = getCmdOption(argc, argv, "--domain");
|
||||
|
||||
int listenPort = VOXEL_LISTEN_PORT;
|
||||
// Check to see if the user passed in a command line option for setting listen port
|
||||
const char* PORT_PARAMETER = "--port";
|
||||
|
@ -85,255 +30,16 @@ int main(int argc, const char * argv[]) {
|
|||
printf("portParameter=%s listenPort=%d\n", portParameter, listenPort);
|
||||
}
|
||||
|
||||
const char* JURISDICTION_FILE = "--jurisdictionFile";
|
||||
const char* jurisdictionFile = getCmdOption(argc, argv, JURISDICTION_FILE);
|
||||
if (jurisdictionFile) {
|
||||
printf("jurisdictionFile=%s\n", jurisdictionFile);
|
||||
|
||||
printf("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
|
||||
jurisdiction = new JurisdictionMap(jurisdictionFile);
|
||||
printf("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
|
||||
if (wantLocalDomain) {
|
||||
VoxelServer::setupDomainAndPort(local, listenPort);
|
||||
} else {
|
||||
const char* JURISDICTION_ROOT = "--jurisdictionRoot";
|
||||
const char* jurisdictionRoot = getCmdOption(argc, argv, JURISDICTION_ROOT);
|
||||
if (jurisdictionRoot) {
|
||||
printf("jurisdictionRoot=%s\n", jurisdictionRoot);
|
||||
}
|
||||
|
||||
const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes";
|
||||
const char* jurisdictionEndNodes = getCmdOption(argc, argv, JURISDICTION_ENDNODES);
|
||||
if (jurisdictionEndNodes) {
|
||||
printf("jurisdictionEndNodes=%s\n", jurisdictionEndNodes);
|
||||
}
|
||||
|
||||
if (jurisdictionRoot || jurisdictionEndNodes) {
|
||||
::jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
|
||||
}
|
||||
}
|
||||
|
||||
// should we send environments? Default is yes, but this command line suppresses sending
|
||||
const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove";
|
||||
::dumpVoxelsOnMove = cmdOptionExists(argc, argv, DUMP_VOXELS_ON_MOVE);
|
||||
printf("dumpVoxelsOnMove=%s\n", debug::valueOf(::dumpVoxelsOnMove));
|
||||
|
||||
// should we send environments? Default is yes, but this command line suppresses sending
|
||||
const char* DONT_SEND_ENVIRONMENTS = "--dontSendEnvironments";
|
||||
bool dontSendEnvironments = cmdOptionExists(argc, argv, DONT_SEND_ENVIRONMENTS);
|
||||
if (dontSendEnvironments) {
|
||||
printf("Sending environments suppressed...\n");
|
||||
::sendEnvironments = false;
|
||||
} else {
|
||||
// should we send environments? Default is yes, but this command line suppresses sending
|
||||
const char* MINIMAL_ENVIRONMENT = "--MinimalEnvironment";
|
||||
::sendMinimalEnvironment = cmdOptionExists(argc, argv, MINIMAL_ENVIRONMENT);
|
||||
printf("Using Minimal Environment=%s\n", debug::valueOf(::sendMinimalEnvironment));
|
||||
}
|
||||
printf("Sending environments=%s\n", debug::valueOf(::sendEnvironments));
|
||||
|
||||
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, listenPort);
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
// tell our NodeList about our desire to get notifications
|
||||
nodeList->addHook(&nodeWatcher);
|
||||
|
||||
// Handle Local Domain testing with the --local command line
|
||||
const char* local = "--local";
|
||||
::wantLocalDomain = cmdOptionExists(argc, argv,local);
|
||||
if (::wantLocalDomain) {
|
||||
printf("Local Domain MODE!\n");
|
||||
nodeList->setDomainIPToLocalhost();
|
||||
} else {
|
||||
const char* domainIP = getCmdOption(argc, argv, "--domain");
|
||||
if (domainIP) {
|
||||
NodeList::getInstance()->setDomainHostname(domainIP);
|
||||
VoxelServer::setupDomainAndPort(domainIP, listenPort);
|
||||
}
|
||||
}
|
||||
|
||||
nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;
|
||||
nodeList->startSilentNodeRemovalThread();
|
||||
|
||||
srand((unsigned)time(0));
|
||||
|
||||
const char* DISPLAY_VOXEL_STATS = "--displayVoxelStats";
|
||||
::displayVoxelStats = cmdOptionExists(argc, argv, DISPLAY_VOXEL_STATS);
|
||||
printf("displayVoxelStats=%s\n", debug::valueOf(::displayVoxelStats));
|
||||
|
||||
const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending";
|
||||
::debugVoxelSending = cmdOptionExists(argc, argv, DEBUG_VOXEL_SENDING);
|
||||
printf("debugVoxelSending=%s\n", debug::valueOf(::debugVoxelSending));
|
||||
|
||||
const char* DEBUG_VOXEL_RECEIVING = "--debugVoxelReceiving";
|
||||
::debugVoxelReceiving = cmdOptionExists(argc, argv, DEBUG_VOXEL_RECEIVING);
|
||||
printf("debugVoxelReceiving=%s\n", debug::valueOf(::debugVoxelReceiving));
|
||||
|
||||
const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug";
|
||||
::shouldShowAnimationDebug = cmdOptionExists(argc, argv, WANT_ANIMATION_DEBUG);
|
||||
printf("shouldShowAnimationDebug=%s\n", debug::valueOf(::shouldShowAnimationDebug));
|
||||
|
||||
// By default we will voxel persist, if you want to disable this, then pass in this parameter
|
||||
const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
|
||||
if (cmdOptionExists(argc, argv, NO_VOXEL_PERSIST)) {
|
||||
::wantVoxelPersist = false;
|
||||
}
|
||||
printf("wantVoxelPersist=%s\n", debug::valueOf(::wantVoxelPersist));
|
||||
|
||||
// if we want Voxel Persistence, load the local file now...
|
||||
bool persistantFileRead = false;
|
||||
if (::wantVoxelPersist) {
|
||||
|
||||
// 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* voxelsPersistFilenameParameter = getCmdOption(argc, argv, VOXELS_PERSIST_FILENAME);
|
||||
if (voxelsPersistFilenameParameter) {
|
||||
strcpy(voxelPersistFilename, voxelsPersistFilenameParameter);
|
||||
} else {
|
||||
strcpy(voxelPersistFilename, ::wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
|
||||
}
|
||||
|
||||
printf("loading voxels from file: %s...\n", voxelPersistFilename);
|
||||
|
||||
persistantFileRead = ::serverTree.readFromSVOFile(::voxelPersistFilename);
|
||||
if (persistantFileRead) {
|
||||
PerformanceWarning warn(::shouldShowAnimationDebug,
|
||||
"persistVoxelsWhenDirty() - reaverageVoxelColors()", ::shouldShowAnimationDebug);
|
||||
|
||||
// after done inserting all these voxels, then reaverage colors
|
||||
serverTree.reaverageVoxelColors(serverTree.rootNode);
|
||||
printf("Voxels reAveraged\n");
|
||||
}
|
||||
|
||||
::serverTree.clearDirtyBit(); // the tree is clean since we just loaded it
|
||||
printf("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
|
||||
unsigned long nodeCount = ::serverTree.rootNode->getSubTreeNodeCount();
|
||||
unsigned long internalNodeCount = ::serverTree.rootNode->getSubTreeInternalNodeCount();
|
||||
unsigned long leafNodeCount = ::serverTree.rootNode->getSubTreeLeafNodeCount();
|
||||
printf("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
|
||||
|
||||
// now set up VoxelPersistThread
|
||||
::voxelPersistThread = new VoxelPersistThread(&::serverTree, ::voxelPersistFilename);
|
||||
if (::voxelPersistThread) {
|
||||
::voxelPersistThread->initialize(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the user passed in a command line option for loading an old style local
|
||||
// Voxel File. If so, load it now. This is not the same as a voxel persist file
|
||||
const char* INPUT_FILE = "-i";
|
||||
const char* voxelsFilename = getCmdOption(argc, argv, INPUT_FILE);
|
||||
if (voxelsFilename) {
|
||||
serverTree.readFromSVOFile(voxelsFilename);
|
||||
}
|
||||
|
||||
// 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* packetsPerSecond = getCmdOption(argc, argv, PACKETS_PER_SECOND);
|
||||
if (packetsPerSecond) {
|
||||
PACKETS_PER_CLIENT_PER_INTERVAL = atoi(packetsPerSecond)/INTERVALS_PER_SECOND;
|
||||
if (PACKETS_PER_CLIENT_PER_INTERVAL < 1) {
|
||||
PACKETS_PER_CLIENT_PER_INTERVAL = 1;
|
||||
}
|
||||
printf("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, PACKETS_PER_CLIENT_PER_INTERVAL);
|
||||
}
|
||||
|
||||
// for now, initialize the environments with fixed values
|
||||
environmentData[1].setID(1);
|
||||
environmentData[1].setGravity(1.0f);
|
||||
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].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f);
|
||||
environmentData[2].setID(2);
|
||||
environmentData[2].setGravity(1.0f);
|
||||
environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
|
||||
environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
|
||||
environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f);
|
||||
environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue
|
||||
|
||||
sockaddr senderAddress;
|
||||
|
||||
unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE];
|
||||
ssize_t packetLength;
|
||||
|
||||
timeval lastDomainServerCheckIn = {};
|
||||
|
||||
// set up our jurisdiction broadcaster...
|
||||
::jurisdictionSender = new JurisdictionSender(::jurisdiction);
|
||||
if (::jurisdictionSender) {
|
||||
::jurisdictionSender->initialize(true);
|
||||
}
|
||||
|
||||
// set up our VoxelServerPacketProcessor
|
||||
::voxelServerPacketProcessor = new VoxelServerPacketProcessor();
|
||||
if (::voxelServerPacketProcessor) {
|
||||
::voxelServerPacketProcessor->initialize(true);
|
||||
}
|
||||
|
||||
// loop to send to nodes requesting data
|
||||
while (true) {
|
||||
|
||||
// send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
|
||||
if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
|
||||
gettimeofday(&lastDomainServerCheckIn, NULL);
|
||||
NodeList::getInstance()->sendDomainServerCheckIn();
|
||||
}
|
||||
|
||||
if (nodeList->getNodeSocket()->receive(&senderAddress, packetData, &packetLength) &&
|
||||
packetVersionMatch(packetData)) {
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
|
||||
if (packetData[0] == PACKET_TYPE_HEAD_DATA) {
|
||||
// If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we
|
||||
// need to make sure we have it in our nodeList.
|
||||
uint16_t nodeID = 0;
|
||||
unpackNodeId(packetData + numBytesPacketHeader, &nodeID);
|
||||
Node* node = NodeList::getInstance()->addOrUpdateNode(&senderAddress,
|
||||
&senderAddress,
|
||||
NODE_TYPE_AGENT,
|
||||
nodeID);
|
||||
|
||||
NodeList::getInstance()->updateNodeWithData(node, packetData, packetLength);
|
||||
} else if (packetData[0] == PACKET_TYPE_PING) {
|
||||
// If the packet is a ping, let processNodeData handle it.
|
||||
NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
|
||||
} else if (packetData[0] == PACKET_TYPE_DOMAIN) {
|
||||
NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
|
||||
} else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
|
||||
if (::jurisdictionSender) {
|
||||
::jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength);
|
||||
}
|
||||
} else if (::voxelServerPacketProcessor) {
|
||||
::voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength);
|
||||
} else {
|
||||
printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (::jurisdiction) {
|
||||
delete ::jurisdiction;
|
||||
}
|
||||
|
||||
if (::jurisdictionSender) {
|
||||
::jurisdictionSender->terminate();
|
||||
delete ::jurisdictionSender;
|
||||
}
|
||||
|
||||
if (::voxelServerPacketProcessor) {
|
||||
::voxelServerPacketProcessor->terminate();
|
||||
delete ::voxelServerPacketProcessor;
|
||||
}
|
||||
|
||||
if (::voxelPersistThread) {
|
||||
::voxelPersistThread->terminate();
|
||||
delete ::voxelPersistThread;
|
||||
}
|
||||
|
||||
// tell our NodeList we're done with notifications
|
||||
nodeList->removeHook(&nodeWatcher);
|
||||
|
||||
pthread_mutex_destroy(&::treeLock);
|
||||
|
||||
return 0;
|
||||
VoxelServer::setArguments(argc, const_cast<char**>(argv));
|
||||
VoxelServer::run();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue