mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 17:24:24 +02:00
Merge branch 'master' of github.com:worklist/hifi into domain-web-server
This commit is contained in:
commit
df4973db6b
12 changed files with 364 additions and 279 deletions
|
@ -26,7 +26,6 @@ const char CHILD_TARGET_NAME[] = "assignment-client";
|
||||||
|
|
||||||
pid_t* childForks = NULL;
|
pid_t* childForks = NULL;
|
||||||
sockaddr_in customAssignmentSocket = {};
|
sockaddr_in customAssignmentSocket = {};
|
||||||
const char* assignmentPool = NULL;
|
|
||||||
int numForks = 0;
|
int numForks = 0;
|
||||||
|
|
||||||
void childClient() {
|
void childClient() {
|
||||||
|
@ -51,8 +50,10 @@ void childClient() {
|
||||||
unsigned char packetData[MAX_PACKET_SIZE];
|
unsigned char packetData[MAX_PACKET_SIZE];
|
||||||
ssize_t receivedBytes = 0;
|
ssize_t receivedBytes = 0;
|
||||||
|
|
||||||
|
sockaddr_in senderSocket = {};
|
||||||
|
|
||||||
// create a request assignment, accept all assignments, pass the desired pool (if it exists)
|
// create a request assignment, accept all assignments, pass the desired pool (if it exists)
|
||||||
Assignment requestAssignment(Assignment::Request, Assignment::All, assignmentPool);
|
Assignment requestAssignment(Assignment::RequestDirection, Assignment::AllTypes);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (usecTimestampNow() - usecTimestamp(&lastRequest) >= ASSIGNMENT_REQUEST_INTERVAL_USECS) {
|
if (usecTimestampNow() - usecTimestamp(&lastRequest) >= ASSIGNMENT_REQUEST_INTERVAL_USECS) {
|
||||||
|
@ -61,22 +62,34 @@ void childClient() {
|
||||||
nodeList->sendAssignment(requestAssignment);
|
nodeList->sendAssignment(requestAssignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodeList->getNodeSocket()->receive(packetData, &receivedBytes) &&
|
if (nodeList->getNodeSocket()->receive((sockaddr*) &senderSocket, packetData, &receivedBytes) &&
|
||||||
packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT && packetVersionMatch(packetData)) {
|
(packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT || packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT)
|
||||||
|
&& packetVersionMatch(packetData)) {
|
||||||
|
|
||||||
// construct the deployed assignment from the packet data
|
// construct the deployed assignment from the packet data
|
||||||
Assignment deployedAssignment(packetData, receivedBytes);
|
Assignment deployedAssignment(packetData, receivedBytes);
|
||||||
|
|
||||||
qDebug() << "Received an assignment -" << deployedAssignment << "\n";
|
qDebug() << "Received an assignment -" << deployedAssignment << "\n";
|
||||||
|
|
||||||
// switch our nodelist DOMAIN_IP to the ip receieved in the assignment
|
// switch our nodelist DOMAIN_IP
|
||||||
if (deployedAssignment.getAttachedPublicSocket()->sa_family == AF_INET) {
|
if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT ||
|
||||||
in_addr domainSocketAddr = ((sockaddr_in*) deployedAssignment.getAttachedPublicSocket())->sin_addr;
|
deployedAssignment.getAttachedPublicSocket()->sa_family == AF_INET) {
|
||||||
|
|
||||||
|
in_addr domainSocketAddr = {};
|
||||||
|
|
||||||
|
if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
|
||||||
|
// the domain server IP address is the address we got this packet from
|
||||||
|
domainSocketAddr = senderSocket.sin_addr;
|
||||||
|
} else {
|
||||||
|
// grab the domain server IP address from the packet from the AS
|
||||||
|
domainSocketAddr = ((sockaddr_in*) deployedAssignment.getAttachedPublicSocket())->sin_addr;
|
||||||
|
}
|
||||||
|
|
||||||
nodeList->setDomainIP(inet_ntoa(domainSocketAddr));
|
nodeList->setDomainIP(inet_ntoa(domainSocketAddr));
|
||||||
|
|
||||||
qDebug("Destination IP for assignment is %s\n", inet_ntoa(domainSocketAddr));
|
qDebug("Destination IP for assignment is %s\n", inet_ntoa(domainSocketAddr));
|
||||||
|
|
||||||
if (deployedAssignment.getType() == Assignment::AudioMixer) {
|
if (deployedAssignment.getType() == Assignment::AudioMixerType) {
|
||||||
AudioMixer::run();
|
AudioMixer::run();
|
||||||
} else {
|
} else {
|
||||||
AvatarMixer::run();
|
AvatarMixer::run();
|
||||||
|
@ -165,19 +178,23 @@ int main(int argc, const char* argv[]) {
|
||||||
// start the Logging class with the parent's target name
|
// start the Logging class with the parent's target name
|
||||||
Logging::setTargetName(PARENT_TARGET_NAME);
|
Logging::setTargetName(PARENT_TARGET_NAME);
|
||||||
|
|
||||||
|
const char CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION[] = "-a";
|
||||||
|
const char CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION[] = "-p";
|
||||||
|
|
||||||
// grab the overriden assignment-server hostname from argv, if it exists
|
// grab the overriden assignment-server hostname from argv, if it exists
|
||||||
const char* customAssignmentServer = getCmdOption(argc, argv, "-a");
|
const char* customAssignmentServerHostname = getCmdOption(argc, argv, CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION);
|
||||||
if (customAssignmentServer) {
|
|
||||||
::customAssignmentSocket = socketForHostnameAndHostOrderPort(customAssignmentServer, ASSIGNMENT_SERVER_PORT);
|
if (customAssignmentServerHostname) {
|
||||||
|
const char* customAssignmentServerPortString = getCmdOption(argc, argv, CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION);
|
||||||
|
unsigned short assignmentServerPort = customAssignmentServerPortString
|
||||||
|
? atoi(customAssignmentServerPortString) : ASSIGNMENT_SERVER_PORT;
|
||||||
|
|
||||||
|
::customAssignmentSocket = socketForHostnameAndHostOrderPort(customAssignmentServerHostname, assignmentServerPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* NUM_FORKS_PARAMETER = "-n";
|
const char* NUM_FORKS_PARAMETER = "-n";
|
||||||
const char* numForksString = getCmdOption(argc, argv, NUM_FORKS_PARAMETER);
|
const char* numForksString = getCmdOption(argc, argv, NUM_FORKS_PARAMETER);
|
||||||
|
|
||||||
// grab the assignment pool from argv, if it was passed
|
|
||||||
const char* ASSIGNMENT_POOL_PARAMETER = "-p";
|
|
||||||
::assignmentPool = getCmdOption(argc, argv, ASSIGNMENT_POOL_PARAMETER);
|
|
||||||
|
|
||||||
int processID = 0;
|
int processID = 0;
|
||||||
|
|
||||||
if (numForksString) {
|
if (numForksString) {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
|
|
||||||
#include <Assignment.h>
|
#include <Assignment.h>
|
||||||
|
#include <Logging.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <UDPSocket.h>
|
#include <UDPSocket.h>
|
||||||
|
@ -22,6 +23,8 @@ const long long NUM_DEFAULT_ASSIGNMENT_STALENESS_USECS = 10 * 1000 * 1000;
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
|
|
||||||
|
qInstallMessageHandler(Logging::verboseMessageHandler);
|
||||||
|
|
||||||
std::deque<Assignment*> assignmentQueue;
|
std::deque<Assignment*> assignmentQueue;
|
||||||
|
|
||||||
sockaddr_in senderSocket;
|
sockaddr_in senderSocket;
|
||||||
|
@ -39,8 +42,8 @@ int main(int argc, const char* argv[]) {
|
||||||
// construct the requested assignment from the packet data
|
// construct the requested assignment from the packet data
|
||||||
Assignment requestAssignment(senderData, receivedBytes);
|
Assignment requestAssignment(senderData, receivedBytes);
|
||||||
|
|
||||||
qDebug() << "Received request for assignment:" << requestAssignment;
|
qDebug() << "Received request for assignment:" << requestAssignment << "\n";
|
||||||
qDebug() << "Current queue size is" << assignmentQueue.size();
|
qDebug() << "Current queue size is" << assignmentQueue.size() << "\n";
|
||||||
|
|
||||||
// make sure there are assignments in the queue at all
|
// make sure there are assignments in the queue at all
|
||||||
if (assignmentQueue.size() > 0) {
|
if (assignmentQueue.size() > 0) {
|
||||||
|
@ -59,51 +62,38 @@ int main(int argc, const char* argv[]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool eitherHasPool = ((*assignment)->getPool() || requestAssignment.getPool());
|
// check if the requestor is on the same network as the destination for the assignment
|
||||||
bool bothHavePool = ((*assignment)->getPool() && requestAssignment.getPool());
|
if (senderSocket.sin_addr.s_addr ==
|
||||||
|
((sockaddr_in*) (*assignment)->getAttachedPublicSocket())->sin_addr.s_addr) {
|
||||||
// make sure there is a pool match for the created and requested assignment
|
// if this is the case we remove the public socket on the assignment by setting it to NULL
|
||||||
// or that neither has a designated pool
|
// this ensures the local IP and port sent to the requestor is the local address of destination
|
||||||
if ((eitherHasPool && bothHavePool
|
(*assignment)->setAttachedPublicSocket(NULL);
|
||||||
&& strcmp((*assignment)->getPool(), requestAssignment.getPool()) == 0)
|
|
||||||
|| !eitherHasPool) {
|
|
||||||
|
|
||||||
// check if the requestor is on the same network as the destination for the assignment
|
|
||||||
if (senderSocket.sin_addr.s_addr ==
|
|
||||||
((sockaddr_in*) (*assignment)->getAttachedPublicSocket())->sin_addr.s_addr) {
|
|
||||||
// if this is the case we remove the public socket on the assignment by setting it to NULL
|
|
||||||
// this ensures the local IP and port sent to the requestor is the local address of destination
|
|
||||||
(*assignment)->setAttachedPublicSocket(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int numAssignmentBytes = (*assignment)->packToBuffer(assignmentPacket + numSendHeaderBytes);
|
|
||||||
|
|
||||||
// send the assignment
|
|
||||||
serverSocket.send((sockaddr*) &senderSocket,
|
|
||||||
assignmentPacket,
|
|
||||||
numSendHeaderBytes + numAssignmentBytes);
|
|
||||||
|
|
||||||
|
|
||||||
// delete this assignment now that it has been sent out
|
|
||||||
delete *assignment;
|
|
||||||
// remove it from the deque and make the iterator the next assignment
|
|
||||||
assignmentQueue.erase(assignment);
|
|
||||||
|
|
||||||
// stop looping - we've handed out an assignment
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// push forward the iterator
|
|
||||||
assignment++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int numAssignmentBytes = (*assignment)->packToBuffer(assignmentPacket + numSendHeaderBytes);
|
||||||
|
|
||||||
|
// send the assignment
|
||||||
|
serverSocket.send((sockaddr*) &senderSocket,
|
||||||
|
assignmentPacket,
|
||||||
|
numSendHeaderBytes + numAssignmentBytes);
|
||||||
|
|
||||||
|
|
||||||
|
// delete this assignment now that it has been sent out
|
||||||
|
delete *assignment;
|
||||||
|
// remove it from the deque and make the iterator the next assignment
|
||||||
|
assignmentQueue.erase(assignment);
|
||||||
|
|
||||||
|
// stop looping - we've handed out an assignment
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (senderData[0] == PACKET_TYPE_CREATE_ASSIGNMENT && packetVersionMatch(senderData)) {
|
} else if (senderData[0] == PACKET_TYPE_CREATE_ASSIGNMENT && packetVersionMatch(senderData)) {
|
||||||
// construct the create assignment from the packet data
|
// construct the create assignment from the packet data
|
||||||
Assignment* createdAssignment = new Assignment(senderData, receivedBytes);
|
Assignment* createdAssignment = new Assignment(senderData, receivedBytes);
|
||||||
|
|
||||||
qDebug() << "Received a created assignment:" << *createdAssignment;
|
qDebug() << "Received a created assignment:" << *createdAssignment << "\n";
|
||||||
qDebug() << "Current queue size is" << assignmentQueue.size();
|
qDebug() << "Current queue size is" << assignmentQueue.size() << "\n";
|
||||||
|
|
||||||
// assignment server is likely on a public server
|
// assignment server is likely on a public server
|
||||||
// assume that the address we now have for the sender is the public address/port
|
// assume that the address we now have for the sender is the public address/port
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <queue>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -51,7 +52,11 @@ unsigned char* addNodeToBroadcastPacket(unsigned char* currentPosition, Node* no
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
|
|
||||||
|
qInstallMessageHandler(Logging::verboseMessageHandler);
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_DOMAIN, DOMAIN_LISTEN_PORT);
|
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_DOMAIN, DOMAIN_LISTEN_PORT);
|
||||||
|
|
||||||
// If user asks to run in "local" mode then we do NOT replace the IP
|
// If user asks to run in "local" mode then we do NOT replace the IP
|
||||||
// with the EC2 IP. Otherwise, we will replace the IP like we used to
|
// with the EC2 IP. Otherwise, we will replace the IP like we used to
|
||||||
// this allows developers to run a local domain without recompiling the
|
// this allows developers to run a local domain without recompiling the
|
||||||
|
@ -73,7 +78,6 @@ int main(int argc, const char* argv[]) {
|
||||||
char nodeType = '\0';
|
char nodeType = '\0';
|
||||||
|
|
||||||
unsigned char broadcastPacket[MAX_PACKET_SIZE];
|
unsigned char broadcastPacket[MAX_PACKET_SIZE];
|
||||||
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_DOMAIN);
|
|
||||||
|
|
||||||
unsigned char* currentBufferPos;
|
unsigned char* currentBufferPos;
|
||||||
unsigned char* startPointer;
|
unsigned char* startPointer;
|
||||||
|
@ -86,13 +90,8 @@ int main(int argc, const char* argv[]) {
|
||||||
nodeList->startSilentNodeRemovalThread();
|
nodeList->startSilentNodeRemovalThread();
|
||||||
|
|
||||||
timeval lastStatSendTime = {};
|
timeval lastStatSendTime = {};
|
||||||
|
|
||||||
const char ASSIGNMENT_POOL_OPTION[] = "-p";
|
|
||||||
const char ASSIGNMENT_SERVER_OPTION[] = "-a";
|
const char ASSIGNMENT_SERVER_OPTION[] = "-a";
|
||||||
|
|
||||||
// set our assignment pool from argv, if it exists
|
|
||||||
const char* assignmentPool = getCmdOption(argc, argv, ASSIGNMENT_POOL_OPTION);
|
|
||||||
|
|
||||||
// grab the overriden assignment-server hostname from argv, if it exists
|
// grab the overriden assignment-server hostname from argv, if it exists
|
||||||
const char* customAssignmentServer = getCmdOption(argc, argv, ASSIGNMENT_SERVER_OPTION);
|
const char* customAssignmentServer = getCmdOption(argc, argv, ASSIGNMENT_SERVER_OPTION);
|
||||||
if (customAssignmentServer) {
|
if (customAssignmentServer) {
|
||||||
|
@ -101,14 +100,23 @@ int main(int argc, const char* argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// use a map to keep track of iterations of silence for assignment creation requests
|
// use a map to keep track of iterations of silence for assignment creation requests
|
||||||
const long long ASSIGNMENT_SILENCE_MAX_USECS = 5 * 1000 * 1000;
|
const long long GLOBAL_ASSIGNMENT_REQUEST_INTERVAL_USECS = 1 * 1000 * 1000;
|
||||||
|
timeval lastGlobalAssignmentRequest = {};
|
||||||
|
|
||||||
|
// setup the assignment queue
|
||||||
|
std::deque<Assignment*> assignmentQueue;
|
||||||
|
|
||||||
// as a domain-server we will always want an audio mixer and avatar mixer
|
// as a domain-server we will always want an audio mixer and avatar mixer
|
||||||
// setup the create assignment pointers for those
|
// setup the create assignments for those
|
||||||
Assignment* audioAssignment = NULL;
|
Assignment audioMixerAssignment(Assignment::CreateDirection,
|
||||||
Assignment* avatarAssignment = NULL;
|
Assignment::AudioMixerType,
|
||||||
|
Assignment::LocalLocation);
|
||||||
|
|
||||||
// construct a local socket to send with our created assignments
|
Assignment avatarMixerAssignment(Assignment::CreateDirection,
|
||||||
|
Assignment::AvatarMixerType,
|
||||||
|
Assignment::LocalLocation);
|
||||||
|
|
||||||
|
// construct a local socket to send with our created assignments to the global AS
|
||||||
sockaddr_in localSocket = {};
|
sockaddr_in localSocket = {};
|
||||||
localSocket.sin_family = AF_INET;
|
localSocket.sin_family = AF_INET;
|
||||||
localSocket.sin_port = htons(nodeList->getInstance()->getNodeSocket()->getListeningPort());
|
localSocket.sin_port = htons(nodeList->getInstance()->getNodeSocket()->getListeningPort());
|
||||||
|
@ -126,135 +134,175 @@ int main(int argc, const char* argv[]) {
|
||||||
ctx = mg_start(&callbacks, NULL, options);
|
ctx = mg_start(&callbacks, NULL, options);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER)) {
|
|
||||||
if (!audioAssignment
|
// check if our audio-mixer or avatar-mixer are dead and we don't have existing assignments in the queue
|
||||||
|| usecTimestampNow() - usecTimestamp(&audioAssignment->getTime()) >= ASSIGNMENT_SILENCE_MAX_USECS) {
|
// so we can add those assignments back to the front of the queue since they are high-priority
|
||||||
|
if (!nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER) &&
|
||||||
if (!audioAssignment) {
|
std::find(assignmentQueue.begin(), assignmentQueue.end(), &avatarMixerAssignment) == assignmentQueue.end()) {
|
||||||
audioAssignment = new Assignment(Assignment::Create, Assignment::AudioMixer, assignmentPool);
|
qDebug("Missing an avatar mixer and assignment not in queue. Adding.\n");
|
||||||
audioAssignment->setAttachedLocalSocket((sockaddr*) &localSocket);
|
assignmentQueue.push_front(&avatarMixerAssignment);
|
||||||
}
|
|
||||||
|
|
||||||
nodeList->sendAssignment(*audioAssignment);
|
|
||||||
audioAssignment->setCreateTimeToNow();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER)) {
|
if (!nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER) &&
|
||||||
if (!avatarAssignment
|
std::find(assignmentQueue.begin(), assignmentQueue.end(), &audioMixerAssignment) == assignmentQueue.end()) {
|
||||||
|| usecTimestampNow() - usecTimestamp(&avatarAssignment->getTime()) >= ASSIGNMENT_SILENCE_MAX_USECS) {
|
qDebug("Missing an audio mixer and assignment not in queue. Adding.\n");
|
||||||
if (!avatarAssignment) {
|
assignmentQueue.push_front(&audioMixerAssignment);
|
||||||
avatarAssignment = new Assignment(Assignment::Create, Assignment::AvatarMixer, assignmentPool);
|
|
||||||
avatarAssignment->setAttachedLocalSocket((sockaddr*) &localSocket);
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeList->sendAssignment(*avatarAssignment);
|
|
||||||
|
|
||||||
// reset the create time on the assignment so re-request is in ASSIGNMENT_SILENCE_MAX_USECS
|
|
||||||
avatarAssignment->setCreateTimeToNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodeList->getNodeSocket()->receive((sockaddr *)&nodePublicAddress, packetData, &receivedBytes) &&
|
while (nodeList->getNodeSocket()->receive((sockaddr *)&nodePublicAddress, packetData, &receivedBytes) &&
|
||||||
(packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_TYPE_DOMAIN_LIST_REQUEST) &&
|
packetVersionMatch(packetData)) {
|
||||||
packetVersionMatch(packetData)) {
|
if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_TYPE_DOMAIN_LIST_REQUEST) {
|
||||||
// this is an RFD or domain list request packet, and there is a version match
|
// this is an RFD or domain list request packet, and there is a version match
|
||||||
std::map<char, Node *> newestSoloNodes;
|
std::map<char, Node *> newestSoloNodes;
|
||||||
|
|
||||||
int numBytesSenderHeader = numBytesForPacketHeader(packetData);
|
int numBytesSenderHeader = numBytesForPacketHeader(packetData);
|
||||||
|
|
||||||
nodeType = *(packetData + numBytesSenderHeader);
|
nodeType = *(packetData + numBytesSenderHeader);
|
||||||
int numBytesSocket = unpackSocket(packetData + numBytesSenderHeader + sizeof(NODE_TYPE),
|
int numBytesSocket = unpackSocket(packetData + numBytesSenderHeader + sizeof(NODE_TYPE),
|
||||||
(sockaddr*) &nodeLocalAddress);
|
(sockaddr*) &nodeLocalAddress);
|
||||||
|
|
||||||
sockaddr* destinationSocket = (sockaddr*) &nodePublicAddress;
|
sockaddr* destinationSocket = (sockaddr*) &nodePublicAddress;
|
||||||
|
|
||||||
// check the node public address
|
// check the node public address
|
||||||
// if it matches our local address we're on the same box
|
// if it matches our local address we're on the same box
|
||||||
// so hardcode the EC2 public address for now
|
// so hardcode the EC2 public address for now
|
||||||
if (nodePublicAddress.sin_addr.s_addr == serverLocalAddress) {
|
if (nodePublicAddress.sin_addr.s_addr == serverLocalAddress) {
|
||||||
// If we're not running "local" then we do replace the IP
|
// If we're not running "local" then we do replace the IP
|
||||||
// with 0. This designates to clients that the server is reachable
|
// with 0. This designates to clients that the server is reachable
|
||||||
// at the same IP address
|
// at the same IP address
|
||||||
if (!isLocalMode) {
|
if (!isLocalMode) {
|
||||||
nodePublicAddress.sin_addr.s_addr = 0;
|
nodePublicAddress.sin_addr.s_addr = 0;
|
||||||
destinationSocket = (sockaddr*) &nodeLocalAddress;
|
destinationSocket = (sockaddr*) &nodeLocalAddress;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Node* newNode = nodeList->addOrUpdateNode((sockaddr*) &nodePublicAddress,
|
|
||||||
(sockaddr*) &nodeLocalAddress,
|
|
||||||
nodeType,
|
|
||||||
nodeList->getLastNodeID());
|
|
||||||
|
|
||||||
// if addOrUpdateNode returns NULL this was a solo node we already have, don't talk back to it
|
|
||||||
if (newNode) {
|
|
||||||
if (newNode->getNodeID() == nodeList->getLastNodeID()) {
|
|
||||||
nodeList->increaseNodeID();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currentBufferPos = broadcastPacket + numHeaderBytes;
|
Node* newNode = nodeList->addOrUpdateNode((sockaddr*) &nodePublicAddress,
|
||||||
startPointer = currentBufferPos;
|
(sockaddr*) &nodeLocalAddress,
|
||||||
|
nodeType,
|
||||||
|
nodeList->getLastNodeID());
|
||||||
|
|
||||||
unsigned char* nodeTypesOfInterest = packetData + numBytesSenderHeader + sizeof(NODE_TYPE)
|
// if addOrUpdateNode returns NULL this was a solo node we already have, don't talk back to it
|
||||||
+ numBytesSocket + sizeof(unsigned char);
|
if (newNode) {
|
||||||
int numInterestTypes = *(nodeTypesOfInterest - 1);
|
if (newNode->getNodeID() == nodeList->getLastNodeID()) {
|
||||||
|
nodeList->increaseNodeID();
|
||||||
if (numInterestTypes > 0) {
|
}
|
||||||
// if the node has sent no types of interest, assume they want nothing but their own ID back
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_DOMAIN);
|
||||||
if (!node->matches((sockaddr*) &nodePublicAddress, (sockaddr*) &nodeLocalAddress, nodeType) &&
|
|
||||||
memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
|
currentBufferPos = broadcastPacket + numHeaderBytes;
|
||||||
// this is not the node themselves
|
startPointer = currentBufferPos;
|
||||||
// and this is an node of a type in the passed node types of interest
|
|
||||||
// or the node did not pass us any specific types they are interested in
|
unsigned char* nodeTypesOfInterest = packetData + numBytesSenderHeader + sizeof(NODE_TYPE)
|
||||||
|
+ numBytesSocket + sizeof(unsigned char);
|
||||||
if (memchr(SOLO_NODE_TYPES, node->getType(), sizeof(SOLO_NODE_TYPES)) == NULL) {
|
int numInterestTypes = *(nodeTypesOfInterest - 1);
|
||||||
// this is an node of which there can be multiple, just add them to the packet
|
|
||||||
// don't send avatar nodes to other avatars, that will come from avatar mixer
|
if (numInterestTypes > 0) {
|
||||||
if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) {
|
// if the node has sent no types of interest, assume they want nothing but their own ID back
|
||||||
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, &(*node));
|
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||||
}
|
if (!node->matches((sockaddr*) &nodePublicAddress, (sockaddr*) &nodeLocalAddress, nodeType) &&
|
||||||
|
memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
|
||||||
|
// this is not the node themselves
|
||||||
|
// and this is an node of a type in the passed node types of interest
|
||||||
|
// or the node did not pass us any specific types they are interested in
|
||||||
|
|
||||||
} else {
|
if (memchr(SOLO_NODE_TYPES, node->getType(), sizeof(SOLO_NODE_TYPES)) == NULL) {
|
||||||
// solo node, we need to only send newest
|
// this is an node of which there can be multiple, just add them to the packet
|
||||||
if (newestSoloNodes[node->getType()] == NULL ||
|
// don't send avatar nodes to other avatars, that will come from avatar mixer
|
||||||
newestSoloNodes[node->getType()]->getWakeMicrostamp() < node->getWakeMicrostamp()) {
|
if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) {
|
||||||
// we have to set the newer solo node to add it to the broadcast later
|
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, &(*node));
|
||||||
newestSoloNodes[node->getType()] = &(*node);
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// solo node, we need to only send newest
|
||||||
|
if (newestSoloNodes[node->getType()] == NULL ||
|
||||||
|
newestSoloNodes[node->getType()]->getWakeMicrostamp() < node->getWakeMicrostamp()) {
|
||||||
|
// we have to set the newer solo node to add it to the broadcast later
|
||||||
|
newestSoloNodes[node->getType()] = &(*node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (std::map<char, Node *>::iterator soloNode = newestSoloNodes.begin();
|
||||||
|
soloNode != newestSoloNodes.end();
|
||||||
|
soloNode++) {
|
||||||
|
// this is the newest alive solo node, add them to the packet
|
||||||
|
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, soloNode->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::map<char, Node *>::iterator soloNode = newestSoloNodes.begin();
|
// update last receive to now
|
||||||
soloNode != newestSoloNodes.end();
|
uint64_t timeNow = usecTimestampNow();
|
||||||
soloNode++) {
|
newNode->setLastHeardMicrostamp(timeNow);
|
||||||
// this is the newest alive solo node, add them to the packet
|
|
||||||
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, soloNode->second);
|
if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY
|
||||||
|
&& memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) {
|
||||||
|
newNode->setWakeMicrostamp(timeNow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add the node ID to the end of the pointer
|
||||||
|
currentBufferPos += packNodeId(currentBufferPos, newNode->getNodeID());
|
||||||
|
|
||||||
|
// send the constructed list back to this node
|
||||||
|
nodeList->getNodeSocket()->send(destinationSocket,
|
||||||
|
broadcastPacket,
|
||||||
|
(currentBufferPos - startPointer) + numHeaderBytes);
|
||||||
}
|
}
|
||||||
|
} else if (packetData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
||||||
|
|
||||||
// update last receive to now
|
qDebug("Received a request for assignment.\n");
|
||||||
uint64_t timeNow = usecTimestampNow();
|
|
||||||
newNode->setLastHeardMicrostamp(timeNow);
|
|
||||||
|
|
||||||
if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY
|
// this is an unassigned client talking to us directly for an assignment
|
||||||
&& memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) {
|
// go through our queue and see if there are any assignments to give out
|
||||||
newNode->setWakeMicrostamp(timeNow);
|
std::deque<Assignment*>::iterator assignment = assignmentQueue.begin();
|
||||||
|
|
||||||
|
while (assignment != assignmentQueue.end()) {
|
||||||
|
|
||||||
|
// give this assignment out, no conditions stop us from giving it to the local assignment client
|
||||||
|
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_CREATE_ASSIGNMENT);
|
||||||
|
int numAssignmentBytes = (*assignment)->packToBuffer(broadcastPacket + numHeaderBytes);
|
||||||
|
|
||||||
|
nodeList->getNodeSocket()->send((sockaddr*) &nodePublicAddress,
|
||||||
|
broadcastPacket,
|
||||||
|
numHeaderBytes + numAssignmentBytes);
|
||||||
|
|
||||||
|
// remove the assignment from the queue
|
||||||
|
assignmentQueue.erase(assignment);
|
||||||
|
|
||||||
|
// stop looping, we've handed out an assignment
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the node ID to the end of the pointer
|
|
||||||
currentBufferPos += packNodeId(currentBufferPos, newNode->getNodeID());
|
|
||||||
|
|
||||||
// send the constructed list back to this node
|
|
||||||
nodeList->getNodeSocket()->send(destinationSocket,
|
|
||||||
broadcastPacket,
|
|
||||||
(currentBufferPos - startPointer) + numHeaderBytes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if ASSIGNMENT_REQUEST_INTERVAL_USECS have passed since last global assignment request then fire off another
|
||||||
|
if (usecTimestampNow() - usecTimestamp(&lastGlobalAssignmentRequest) >= GLOBAL_ASSIGNMENT_REQUEST_INTERVAL_USECS) {
|
||||||
|
gettimeofday(&lastGlobalAssignmentRequest, NULL);
|
||||||
|
|
||||||
|
// go through our queue and see if there are any assignments to send to the global assignment server
|
||||||
|
std::deque<Assignment*>::iterator assignment = assignmentQueue.begin();
|
||||||
|
|
||||||
|
while (assignment != assignmentQueue.end()) {
|
||||||
|
|
||||||
|
if ((*assignment)->getLocation() != Assignment::LocalLocation) {
|
||||||
|
// attach our local socket to the assignment so the assignment-server can optionally hand it out
|
||||||
|
(*assignment)->setAttachedLocalSocket((sockaddr*) &localSocket);
|
||||||
|
|
||||||
|
nodeList->sendAssignment(*(*assignment));
|
||||||
|
|
||||||
|
// remove the assignment from the queue
|
||||||
|
assignmentQueue.erase(assignment);
|
||||||
|
|
||||||
|
// stop looping, we've handed out an assignment
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// push forward the iterator to check the next assignment
|
||||||
|
assignment++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (Logging::shouldSendStats()) {
|
if (Logging::shouldSendStats()) {
|
||||||
if (usecTimestampNow() - usecTimestamp(&lastStatSendTime) >= (NODE_COUNT_STAT_INTERVAL_MSECS * 1000)) {
|
if (usecTimestampNow() - usecTimestamp(&lastStatSendTime) >= (NODE_COUNT_STAT_INTERVAL_MSECS * 1000)) {
|
||||||
// time to send our count of nodes and servers to logstash
|
// time to send our count of nodes and servers to logstash
|
||||||
|
@ -266,9 +314,6 @@ int main(int argc, const char* argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete audioAssignment;
|
|
||||||
delete avatarAssignment;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,11 +370,11 @@ Menu::Menu() :
|
||||||
SLOT(setDepthOnly(bool)));
|
SLOT(setDepthOnly(bool)));
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu,
|
addCheckableActionToQMenuAndActionHash(developerMenu,
|
||||||
MenuOption::Faceshift,
|
MenuOption::FaceshiftTCP,
|
||||||
0,
|
0,
|
||||||
false,
|
false,
|
||||||
appInstance->getFaceshift(),
|
appInstance->getFaceshift(),
|
||||||
SLOT(setEnabled(bool)));
|
SLOT(setTCPEnabled(bool)));
|
||||||
|
|
||||||
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
|
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
|
||||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoAudio);
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoAudio);
|
||||||
|
|
|
@ -137,7 +137,7 @@ namespace MenuOption {
|
||||||
const QString ExportVoxels = "Export Voxels";
|
const QString ExportVoxels = "Export Voxels";
|
||||||
const QString HeadMouse = "Head Mouse";
|
const QString HeadMouse = "Head Mouse";
|
||||||
const QString FaceMode = "Cycle Face Mode";
|
const QString FaceMode = "Cycle Face Mode";
|
||||||
const QString Faceshift = "Faceshift";
|
const QString FaceshiftTCP = "Faceshift (TCP)";
|
||||||
const QString FalseColorByDistance = "FALSE Color By Distance";
|
const QString FalseColorByDistance = "FALSE Color By Distance";
|
||||||
const QString FalseColorBySource = "FALSE Color By Source";
|
const QString FalseColorBySource = "FALSE Color By Source";
|
||||||
const QString FalseColorEveryOtherVoxel = "FALSE Color Every Other Randomly";
|
const QString FalseColorEveryOtherVoxel = "FALSE Color Every Other Randomly";
|
||||||
|
|
|
@ -661,21 +661,22 @@ void Head::renderEyeBalls() {
|
||||||
glm::vec3 front = orientation * IDENTITY_FRONT;
|
glm::vec3 front = orientation * IDENTITY_FRONT;
|
||||||
|
|
||||||
// render left iris
|
// render left iris
|
||||||
|
glm::quat leftIrisRotation;
|
||||||
glPushMatrix(); {
|
glPushMatrix(); {
|
||||||
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position
|
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position
|
||||||
|
|
||||||
//rotate the eyeball to aim towards the lookat position
|
//rotate the eyeball to aim towards the lookat position
|
||||||
glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _leftEyePosition;
|
glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _leftEyePosition;
|
||||||
glm::quat rotation = rotationBetween(front, targetLookatVector) * orientation;
|
leftIrisRotation = rotationBetween(front, targetLookatVector) * orientation;
|
||||||
glm::vec3 rotationAxis = glm::axis(rotation);
|
glm::vec3 rotationAxis = glm::axis(leftIrisRotation);
|
||||||
glRotatef(glm::angle(rotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
glRotatef(glm::angle(leftIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
||||||
glTranslatef(0.0f, 0.0f, -_scale * IRIS_PROTRUSION);
|
glTranslatef(0.0f, 0.0f, -_scale * IRIS_PROTRUSION);
|
||||||
glScalef(_scale * IRIS_RADIUS * 2.0f,
|
glScalef(_scale * IRIS_RADIUS * 2.0f,
|
||||||
_scale * IRIS_RADIUS * 2.0f,
|
_scale * IRIS_RADIUS * 2.0f,
|
||||||
_scale * IRIS_RADIUS); // flatten the iris
|
_scale * IRIS_RADIUS); // flatten the iris
|
||||||
|
|
||||||
// this ugliness is simply to invert the model transform and get the eye position in model space
|
// this ugliness is simply to invert the model transform and get the eye position in model space
|
||||||
_irisProgram.setUniform(_eyePositionLocation, (glm::inverse(rotation) *
|
_irisProgram.setUniform(_eyePositionLocation, (glm::inverse(leftIrisRotation) *
|
||||||
(Application::getInstance()->getCamera()->getPosition() - _leftEyePosition) +
|
(Application::getInstance()->getCamera()->getPosition() - _leftEyePosition) +
|
||||||
glm::vec3(0.0f, 0.0f, _scale * IRIS_PROTRUSION)) * glm::vec3(1.0f / (_scale * IRIS_RADIUS * 2.0f),
|
glm::vec3(0.0f, 0.0f, _scale * IRIS_PROTRUSION)) * glm::vec3(1.0f / (_scale * IRIS_RADIUS * 2.0f),
|
||||||
1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS)));
|
1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS)));
|
||||||
|
@ -685,21 +686,22 @@ void Head::renderEyeBalls() {
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
// render right iris
|
// render right iris
|
||||||
|
glm::quat rightIrisRotation;
|
||||||
glPushMatrix(); {
|
glPushMatrix(); {
|
||||||
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
|
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
|
||||||
|
|
||||||
//rotate the eyeball to aim towards the lookat position
|
//rotate the eyeball to aim towards the lookat position
|
||||||
glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _rightEyePosition;
|
glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _rightEyePosition;
|
||||||
glm::quat rotation = rotationBetween(front, targetLookatVector) * orientation;
|
rightIrisRotation = rotationBetween(front, targetLookatVector) * orientation;
|
||||||
glm::vec3 rotationAxis = glm::axis(rotation);
|
glm::vec3 rotationAxis = glm::axis(rightIrisRotation);
|
||||||
glRotatef(glm::angle(rotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
glRotatef(glm::angle(rightIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
||||||
glTranslatef(0.0f, 0.0f, -_scale * IRIS_PROTRUSION);
|
glTranslatef(0.0f, 0.0f, -_scale * IRIS_PROTRUSION);
|
||||||
glScalef(_scale * IRIS_RADIUS * 2.0f,
|
glScalef(_scale * IRIS_RADIUS * 2.0f,
|
||||||
_scale * IRIS_RADIUS * 2.0f,
|
_scale * IRIS_RADIUS * 2.0f,
|
||||||
_scale * IRIS_RADIUS); // flatten the iris
|
_scale * IRIS_RADIUS); // flatten the iris
|
||||||
|
|
||||||
// this ugliness is simply to invert the model transform and get the eye position in model space
|
// this ugliness is simply to invert the model transform and get the eye position in model space
|
||||||
_irisProgram.setUniform(_eyePositionLocation, (glm::inverse(rotation) *
|
_irisProgram.setUniform(_eyePositionLocation, (glm::inverse(rightIrisRotation) *
|
||||||
(Application::getInstance()->getCamera()->getPosition() - _rightEyePosition) +
|
(Application::getInstance()->getCamera()->getPosition() - _rightEyePosition) +
|
||||||
glm::vec3(0.0f, 0.0f, _scale * IRIS_PROTRUSION)) * glm::vec3(1.0f / (_scale * IRIS_RADIUS * 2.0f),
|
glm::vec3(0.0f, 0.0f, _scale * IRIS_PROTRUSION)) * glm::vec3(1.0f / (_scale * IRIS_RADIUS * 2.0f),
|
||||||
1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS)));
|
1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS)));
|
||||||
|
@ -718,12 +720,13 @@ void Head::renderEyeBalls() {
|
||||||
// left eyelid
|
// left eyelid
|
||||||
glPushMatrix(); {
|
glPushMatrix(); {
|
||||||
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position
|
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position
|
||||||
glm::vec3 rotationAxis = glm::axis(orientation);
|
glm::vec3 rotationAxis = glm::axis(leftIrisRotation);
|
||||||
glRotatef(glm::angle(orientation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
glRotatef(glm::angle(leftIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
||||||
glScalef(_scale * EYELID_RADIUS, _scale * EYELID_RADIUS, _scale * EYELID_RADIUS);
|
glScalef(_scale * EYELID_RADIUS, _scale * EYELID_RADIUS, _scale * EYELID_RADIUS);
|
||||||
glRotatef(-40 - 50 * _leftEyeBlink, 1, 0, 0);
|
float angle = -67.5f - 50.0f * _leftEyeBlink;
|
||||||
|
glRotatef(angle, 1, 0, 0);
|
||||||
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
|
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
|
||||||
glRotatef(180 * _leftEyeBlink, 1, 0, 0);
|
glRotatef(glm::mix(-angle, 180.0f, max(0.0f, _leftEyeBlink)), 1, 0, 0);
|
||||||
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
|
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
@ -731,12 +734,13 @@ void Head::renderEyeBalls() {
|
||||||
// right eyelid
|
// right eyelid
|
||||||
glPushMatrix(); {
|
glPushMatrix(); {
|
||||||
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
|
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
|
||||||
glm::vec3 rotationAxis = glm::axis(orientation);
|
glm::vec3 rotationAxis = glm::axis(rightIrisRotation);
|
||||||
glRotatef(glm::angle(orientation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
glRotatef(glm::angle(rightIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
||||||
glScalef(_scale * EYELID_RADIUS, _scale * EYELID_RADIUS, _scale * EYELID_RADIUS);
|
glScalef(_scale * EYELID_RADIUS, _scale * EYELID_RADIUS, _scale * EYELID_RADIUS);
|
||||||
glRotatef(-40 - 50 * _rightEyeBlink, 1, 0, 0);
|
float angle = -67.5f - 50.0f * _rightEyeBlink;
|
||||||
|
glRotatef(angle, 1, 0, 0);
|
||||||
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
|
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
|
||||||
glRotatef(180 * _rightEyeBlink, 1, 0, 0);
|
glRotatef(glm::mix(-angle, 180.0f, max(0.0f, _rightEyeBlink)), 1, 0, 0);
|
||||||
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
|
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
|
@ -347,14 +347,19 @@ void MyAvatar::updateFromGyrosAndOrWebcam(bool gyroLook,
|
||||||
} else if (webcam->isActive()) {
|
} else if (webcam->isActive()) {
|
||||||
estimatedRotation = webcam->getEstimatedRotation();
|
estimatedRotation = webcam->getEstimatedRotation();
|
||||||
|
|
||||||
} else if (_leadingAvatar) {
|
|
||||||
_head.getFace().clearFrame();
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_head.setMousePitch(pitchFromTouch);
|
if (!_leadingAvatar) {
|
||||||
_head.setPitch(pitchFromTouch);
|
_head.setMousePitch(pitchFromTouch);
|
||||||
|
_head.setPitch(pitchFromTouch);
|
||||||
|
}
|
||||||
_head.getFace().clearFrame();
|
_head.getFace().clearFrame();
|
||||||
|
|
||||||
|
// restore rotation, lean to neutral positions
|
||||||
|
const float RESTORE_RATE = 0.05f;
|
||||||
|
_head.setYaw(glm::mix(_head.getYaw(), 0.0f, RESTORE_RATE));
|
||||||
|
_head.setRoll(glm::mix(_head.getRoll(), 0.0f, RESTORE_RATE));
|
||||||
|
_head.setLeanSideways(glm::mix(_head.getLeanSideways(), 0.0f, RESTORE_RATE));
|
||||||
|
_head.setLeanForward(glm::mix(_head.getLeanForward(), 0.0f, RESTORE_RATE));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_head.setMousePitch(pitchFromTouch);
|
_head.setMousePitch(pitchFromTouch);
|
||||||
|
|
|
@ -8,33 +8,50 @@
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
#include "Faceshift.h"
|
#include "Faceshift.h"
|
||||||
|
|
||||||
using namespace fs;
|
using namespace fs;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
const quint16 FACESHIFT_PORT = 33433;
|
||||||
|
|
||||||
Faceshift::Faceshift() :
|
Faceshift::Faceshift() :
|
||||||
_enabled(false),
|
_tcpEnabled(false),
|
||||||
|
_lastMessageReceived(0),
|
||||||
_eyeGazeLeftPitch(0.0f),
|
_eyeGazeLeftPitch(0.0f),
|
||||||
_eyeGazeLeftYaw(0.0f),
|
_eyeGazeLeftYaw(0.0f),
|
||||||
_eyeGazeRightPitch(0.0f),
|
_eyeGazeRightPitch(0.0f),
|
||||||
_eyeGazeRightYaw(0.0f),
|
_eyeGazeRightYaw(0.0f),
|
||||||
_leftBlink(0.0f),
|
_leftBlink(0.0f),
|
||||||
_rightBlink(0.0f),
|
_rightBlink(0.0f),
|
||||||
_leftBlinkIndex(-1),
|
_leftBlinkIndex(0), // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes
|
||||||
_rightBlinkIndex(-1),
|
_rightBlinkIndex(1),
|
||||||
|
_leftEyeOpenIndex(8),
|
||||||
|
_rightEyeOpenIndex(9),
|
||||||
_browHeight(0.0f),
|
_browHeight(0.0f),
|
||||||
_browUpCenterIndex(-1),
|
_browUpCenterIndex(16),
|
||||||
_mouthSize(0.0f),
|
_mouthSize(0.0f),
|
||||||
_jawOpenIndex(-1),
|
_jawOpenIndex(21),
|
||||||
_longTermAverageEyePitch(0.0f),
|
_longTermAverageEyePitch(0.0f),
|
||||||
_longTermAverageEyeYaw(0.0f),
|
_longTermAverageEyeYaw(0.0f),
|
||||||
_estimatedEyePitch(0.0f),
|
_estimatedEyePitch(0.0f),
|
||||||
_estimatedEyeYaw(0.0f)
|
_estimatedEyeYaw(0.0f)
|
||||||
{
|
{
|
||||||
connect(&_socket, SIGNAL(connected()), SLOT(noteConnected()));
|
connect(&_tcpSocket, SIGNAL(connected()), SLOT(noteConnected()));
|
||||||
connect(&_socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(noteError(QAbstractSocket::SocketError)));
|
connect(&_tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(noteError(QAbstractSocket::SocketError)));
|
||||||
connect(&_socket, SIGNAL(readyRead()), SLOT(readFromSocket()));
|
connect(&_tcpSocket, SIGNAL(readyRead()), SLOT(readFromSocket()));
|
||||||
|
|
||||||
|
connect(&_udpSocket, SIGNAL(readyRead()), SLOT(readPendingDatagrams()));
|
||||||
|
|
||||||
|
_udpSocket.bind(FACESHIFT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Faceshift::isActive() const {
|
||||||
|
const uint64_t ACTIVE_TIMEOUT_USECS = 1000000;
|
||||||
|
return (_tcpSocket.state() == QAbstractSocket::ConnectedState ||
|
||||||
|
(usecTimestampNow() - _lastMessageReceived) < ACTIVE_TIMEOUT_USECS) && _tracking;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Faceshift::update() {
|
void Faceshift::update() {
|
||||||
|
@ -51,28 +68,28 @@ void Faceshift::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Faceshift::reset() {
|
void Faceshift::reset() {
|
||||||
if (isActive()) {
|
if (_tcpSocket.state() == QAbstractSocket::ConnectedState) {
|
||||||
string message;
|
string message;
|
||||||
fsBinaryStream::encode_message(message, fsMsgCalibrateNeutral());
|
fsBinaryStream::encode_message(message, fsMsgCalibrateNeutral());
|
||||||
send(message);
|
send(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Faceshift::setEnabled(bool enabled) {
|
void Faceshift::setTCPEnabled(bool enabled) {
|
||||||
if ((_enabled = enabled)) {
|
if ((_tcpEnabled = enabled)) {
|
||||||
connectSocket();
|
connectSocket();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_socket.disconnectFromHost();
|
_tcpSocket.disconnectFromHost();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Faceshift::connectSocket() {
|
void Faceshift::connectSocket() {
|
||||||
if (_enabled) {
|
if (_tcpEnabled) {
|
||||||
qDebug("Faceshift: Connecting...\n");
|
qDebug("Faceshift: Connecting...\n");
|
||||||
|
|
||||||
const quint16 FACESHIFT_PORT = 33433;
|
_tcpSocket.connectToHost("localhost", FACESHIFT_PORT);
|
||||||
_socket.connectToHost("localhost", FACESHIFT_PORT);
|
_tracking = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,23 +103,39 @@ void Faceshift::noteConnected() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Faceshift::noteError(QAbstractSocket::SocketError error) {
|
void Faceshift::noteError(QAbstractSocket::SocketError error) {
|
||||||
qDebug() << "Faceshift: " << _socket.errorString() << "\n";
|
qDebug() << "Faceshift: " << _tcpSocket.errorString() << "\n";
|
||||||
|
|
||||||
// reconnect after a delay
|
// reconnect after a delay
|
||||||
if (_enabled) {
|
if (_tcpEnabled) {
|
||||||
QTimer::singleShot(1000, this, SLOT(connectSocket()));
|
QTimer::singleShot(1000, this, SLOT(connectSocket()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Faceshift::readPendingDatagrams() {
|
||||||
|
QByteArray buffer;
|
||||||
|
while (_udpSocket.hasPendingDatagrams()) {
|
||||||
|
buffer.resize(_udpSocket.pendingDatagramSize());
|
||||||
|
_udpSocket.readDatagram(buffer.data(), buffer.size());
|
||||||
|
receive(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Faceshift::readFromSocket() {
|
void Faceshift::readFromSocket() {
|
||||||
QByteArray buffer = _socket.readAll();
|
receive(_tcpSocket.readAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Faceshift::send(const std::string& message) {
|
||||||
|
_tcpSocket.write(message.data(), message.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Faceshift::receive(const QByteArray& buffer) {
|
||||||
_stream.received(buffer.size(), buffer.constData());
|
_stream.received(buffer.size(), buffer.constData());
|
||||||
fsMsgPtr msg;
|
fsMsgPtr msg;
|
||||||
for (fsMsgPtr msg; (msg = _stream.get_message()); ) {
|
for (fsMsgPtr msg; (msg = _stream.get_message()); ) {
|
||||||
switch (msg->id()) {
|
switch (msg->id()) {
|
||||||
case fsMsg::MSG_OUT_TRACKING_STATE: {
|
case fsMsg::MSG_OUT_TRACKING_STATE: {
|
||||||
const fsTrackingData& data = static_cast<fsMsgTrackingState*>(msg.get())->tracking_data();
|
const fsTrackingData& data = static_cast<fsMsgTrackingState*>(msg.get())->tracking_data();
|
||||||
if (data.m_trackingSuccessful) {
|
if ((_tracking = data.m_trackingSuccessful)) {
|
||||||
_headRotation = glm::quat(data.m_headRotation.w, -data.m_headRotation.x,
|
_headRotation = glm::quat(data.m_headRotation.w, -data.m_headRotation.x,
|
||||||
data.m_headRotation.y, -data.m_headRotation.z);
|
data.m_headRotation.y, -data.m_headRotation.z);
|
||||||
const float TRANSLATION_SCALE = 0.02f;
|
const float TRANSLATION_SCALE = 0.02f;
|
||||||
|
@ -113,11 +146,12 @@ void Faceshift::readFromSocket() {
|
||||||
_eyeGazeRightPitch = -data.m_eyeGazeRightPitch;
|
_eyeGazeRightPitch = -data.m_eyeGazeRightPitch;
|
||||||
_eyeGazeRightYaw = data.m_eyeGazeRightYaw;
|
_eyeGazeRightYaw = data.m_eyeGazeRightYaw;
|
||||||
|
|
||||||
|
const float EYE_OPEN_SCALE = 0.5f;
|
||||||
if (_leftBlinkIndex != -1) {
|
if (_leftBlinkIndex != -1) {
|
||||||
_leftBlink = data.m_coeffs[_leftBlinkIndex];
|
_leftBlink = data.m_coeffs[_leftBlinkIndex] - data.m_coeffs[_leftEyeOpenIndex] * EYE_OPEN_SCALE;
|
||||||
}
|
}
|
||||||
if (_rightBlinkIndex != -1) {
|
if (_rightBlinkIndex != -1) {
|
||||||
_rightBlink = data.m_coeffs[_rightBlinkIndex];
|
_rightBlink = data.m_coeffs[_rightBlinkIndex] - data.m_coeffs[_rightEyeOpenIndex] * EYE_OPEN_SCALE;
|
||||||
}
|
}
|
||||||
if (_browUpCenterIndex != -1) {
|
if (_browUpCenterIndex != -1) {
|
||||||
_browHeight = data.m_coeffs[_browUpCenterIndex];
|
_browHeight = data.m_coeffs[_browUpCenterIndex];
|
||||||
|
@ -136,7 +170,13 @@ void Faceshift::readFromSocket() {
|
||||||
|
|
||||||
} else if (names[i] == "EyeBlink_R") {
|
} else if (names[i] == "EyeBlink_R") {
|
||||||
_rightBlinkIndex = i;
|
_rightBlinkIndex = i;
|
||||||
|
|
||||||
|
} else if (names[i] == "EyeOpen_L") {
|
||||||
|
_leftEyeOpenIndex = i;
|
||||||
|
|
||||||
|
} else if (names[i] == "EyeOpen_R") {
|
||||||
|
_rightEyeOpenIndex = i;
|
||||||
|
|
||||||
} else if (names[i] == "BrowsU_C") {
|
} else if (names[i] == "BrowsU_C") {
|
||||||
_browUpCenterIndex = i;
|
_browUpCenterIndex = i;
|
||||||
|
|
||||||
|
@ -150,8 +190,5 @@ void Faceshift::readFromSocket() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
_lastMessageReceived = usecTimestampNow();
|
||||||
|
|
||||||
void Faceshift::send(const std::string& message) {
|
|
||||||
_socket.write(message.data(), message.size());
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define __interface__Faceshift__
|
#define __interface__Faceshift__
|
||||||
|
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
|
#include <QUdpSocket>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
@ -24,7 +25,7 @@ public:
|
||||||
|
|
||||||
Faceshift();
|
Faceshift();
|
||||||
|
|
||||||
bool isActive() const { return _socket.state() == QAbstractSocket::ConnectedState; }
|
bool isActive() const;
|
||||||
|
|
||||||
const glm::quat& getHeadRotation() const { return _headRotation; }
|
const glm::quat& getHeadRotation() const { return _headRotation; }
|
||||||
const glm::vec3& getHeadTranslation() const { return _headTranslation; }
|
const glm::vec3& getHeadTranslation() const { return _headTranslation; }
|
||||||
|
@ -50,22 +51,27 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void setEnabled(bool enabled);
|
void setTCPEnabled(bool enabled);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void connectSocket();
|
void connectSocket();
|
||||||
void noteConnected();
|
void noteConnected();
|
||||||
void noteError(QAbstractSocket::SocketError error);
|
void noteError(QAbstractSocket::SocketError error);
|
||||||
|
void readPendingDatagrams();
|
||||||
void readFromSocket();
|
void readFromSocket();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void send(const std::string& message);
|
void send(const std::string& message);
|
||||||
|
void receive(const QByteArray& buffer);
|
||||||
|
|
||||||
QTcpSocket _socket;
|
QTcpSocket _tcpSocket;
|
||||||
|
QUdpSocket _udpSocket;
|
||||||
fs::fsBinaryStream _stream;
|
fs::fsBinaryStream _stream;
|
||||||
bool _enabled;
|
bool _tcpEnabled;
|
||||||
|
bool _tracking;
|
||||||
|
uint64_t _lastMessageReceived;
|
||||||
|
|
||||||
glm::quat _headRotation;
|
glm::quat _headRotation;
|
||||||
glm::vec3 _headTranslation;
|
glm::vec3 _headTranslation;
|
||||||
|
@ -82,6 +88,9 @@ private:
|
||||||
int _leftBlinkIndex;
|
int _leftBlinkIndex;
|
||||||
int _rightBlinkIndex;
|
int _rightBlinkIndex;
|
||||||
|
|
||||||
|
int _leftEyeOpenIndex;
|
||||||
|
int _rightEyeOpenIndex;
|
||||||
|
|
||||||
float _browHeight;
|
float _browHeight;
|
||||||
|
|
||||||
int _browUpCenterIndex;
|
int _browUpCenterIndex;
|
||||||
|
|
|
@ -13,28 +13,19 @@
|
||||||
const char IPv4_ADDRESS_DESIGNATOR = 4;
|
const char IPv4_ADDRESS_DESIGNATOR = 4;
|
||||||
const char IPv6_ADDRESS_DESIGNATOR = 6;
|
const char IPv6_ADDRESS_DESIGNATOR = 6;
|
||||||
|
|
||||||
Assignment::Assignment(Assignment::Direction direction, Assignment::Type type, const char* pool) :
|
Assignment::Assignment(Assignment::Direction direction, Assignment::Type type, Assignment::Location location) :
|
||||||
_direction(direction),
|
_direction(direction),
|
||||||
_type(type),
|
_type(type),
|
||||||
_pool(NULL),
|
_location(location),
|
||||||
_attachedPublicSocket(NULL),
|
_attachedPublicSocket(NULL),
|
||||||
_attachedLocalSocket(NULL)
|
_attachedLocalSocket(NULL)
|
||||||
{
|
{
|
||||||
// set the create time on this assignment
|
// set the create time on this assignment
|
||||||
gettimeofday(&_time, NULL);
|
gettimeofday(&_time, NULL);
|
||||||
|
|
||||||
// copy the pool, if we got one
|
|
||||||
if (pool) {
|
|
||||||
int poolLength = strlen(pool);
|
|
||||||
|
|
||||||
// create the char array and make it large enough for string and null termination
|
|
||||||
_pool = new char[poolLength + sizeof(char)];
|
|
||||||
strcpy(_pool, pool);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
|
Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
|
||||||
_pool(NULL),
|
_location(GlobalLocation),
|
||||||
_attachedPublicSocket(NULL),
|
_attachedPublicSocket(NULL),
|
||||||
_attachedLocalSocket(NULL)
|
_attachedLocalSocket(NULL)
|
||||||
{
|
{
|
||||||
|
@ -44,11 +35,11 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
|
||||||
int numBytesRead = 0;
|
int numBytesRead = 0;
|
||||||
|
|
||||||
if (dataBuffer[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
if (dataBuffer[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
||||||
_direction = Assignment::Request;
|
_direction = Assignment::RequestDirection;
|
||||||
} else if (dataBuffer[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
|
} else if (dataBuffer[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
|
||||||
_direction = Assignment::Create;
|
_direction = Assignment::CreateDirection;
|
||||||
} else if (dataBuffer[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT) {
|
} else if (dataBuffer[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT) {
|
||||||
_direction = Assignment::Deploy;
|
_direction = Assignment::DeployDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
numBytesRead += numBytesForPacketHeader(dataBuffer);
|
numBytesRead += numBytesForPacketHeader(dataBuffer);
|
||||||
|
@ -56,15 +47,6 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
|
||||||
memcpy(&_type, dataBuffer + numBytesRead, sizeof(Assignment::Type));
|
memcpy(&_type, dataBuffer + numBytesRead, sizeof(Assignment::Type));
|
||||||
numBytesRead += sizeof(Assignment::Type);
|
numBytesRead += sizeof(Assignment::Type);
|
||||||
|
|
||||||
if (dataBuffer[numBytesRead] != 0) {
|
|
||||||
int poolLength = strlen((const char*) dataBuffer + numBytesRead);
|
|
||||||
_pool = new char[poolLength + sizeof(char)];
|
|
||||||
strcpy(_pool, (char*) dataBuffer + numBytesRead);
|
|
||||||
numBytesRead += poolLength + sizeof(char);
|
|
||||||
} else {
|
|
||||||
numBytesRead += sizeof(char);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numBytes > numBytesRead) {
|
if (numBytes > numBytesRead) {
|
||||||
|
|
||||||
sockaddr* newSocket = NULL;
|
sockaddr* newSocket = NULL;
|
||||||
|
@ -78,7 +60,7 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
|
||||||
qDebug("Received a socket that cannot be unpacked!\n");
|
qDebug("Received a socket that cannot be unpacked!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_direction == Assignment::Create) {
|
if (_direction == Assignment::CreateDirection) {
|
||||||
delete _attachedLocalSocket;
|
delete _attachedLocalSocket;
|
||||||
_attachedLocalSocket = newSocket;
|
_attachedLocalSocket = newSocket;
|
||||||
} else {
|
} else {
|
||||||
|
@ -91,7 +73,6 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
|
||||||
Assignment::~Assignment() {
|
Assignment::~Assignment() {
|
||||||
delete _attachedPublicSocket;
|
delete _attachedPublicSocket;
|
||||||
delete _attachedLocalSocket;
|
delete _attachedLocalSocket;
|
||||||
delete _pool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assignment::setAttachedPublicSocket(const sockaddr* attachedPublicSocket) {
|
void Assignment::setAttachedPublicSocket(const sockaddr* attachedPublicSocket) {
|
||||||
|
@ -124,16 +105,6 @@ int Assignment::packToBuffer(unsigned char* buffer) {
|
||||||
memcpy(buffer + numPackedBytes, &_type, sizeof(_type));
|
memcpy(buffer + numPackedBytes, &_type, sizeof(_type));
|
||||||
numPackedBytes += sizeof(_type);
|
numPackedBytes += sizeof(_type);
|
||||||
|
|
||||||
if (_pool) {
|
|
||||||
int poolLength = strlen(_pool);
|
|
||||||
strcpy((char*) buffer + numPackedBytes, _pool);
|
|
||||||
|
|
||||||
numPackedBytes += poolLength + sizeof(char);
|
|
||||||
} else {
|
|
||||||
buffer[numPackedBytes] = '\0';
|
|
||||||
numPackedBytes += sizeof(char);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_attachedPublicSocket || _attachedLocalSocket) {
|
if (_attachedPublicSocket || _attachedLocalSocket) {
|
||||||
sockaddr* socketToPack = (_attachedPublicSocket) ? _attachedPublicSocket : _attachedLocalSocket;
|
sockaddr* socketToPack = (_attachedPublicSocket) ? _attachedPublicSocket : _attachedLocalSocket;
|
||||||
|
|
||||||
|
@ -148,6 +119,6 @@ int Assignment::packToBuffer(unsigned char* buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const Assignment &assignment) {
|
QDebug operator<<(QDebug debug, const Assignment &assignment) {
|
||||||
debug << "T:" << assignment.getType() << "P:" << assignment.getPool();
|
debug << "T:" << assignment.getType();
|
||||||
return debug.nospace();
|
return debug.nospace();
|
||||||
}
|
}
|
|
@ -18,18 +18,25 @@ class Assignment {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
AudioMixer,
|
AudioMixerType,
|
||||||
AvatarMixer,
|
AvatarMixerType,
|
||||||
All
|
AllTypes
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Direction {
|
enum Direction {
|
||||||
Create,
|
CreateDirection,
|
||||||
Deploy,
|
DeployDirection,
|
||||||
Request
|
RequestDirection
|
||||||
};
|
};
|
||||||
|
|
||||||
Assignment(Assignment::Direction direction, Assignment::Type type, const char* pool = NULL);
|
enum Location {
|
||||||
|
GlobalLocation,
|
||||||
|
LocalLocation
|
||||||
|
};
|
||||||
|
|
||||||
|
Assignment(Assignment::Direction direction,
|
||||||
|
Assignment::Type type,
|
||||||
|
Assignment::Location location = Assignment::GlobalLocation);
|
||||||
|
|
||||||
/// Constructs an Assignment from the data in the buffer
|
/// Constructs an Assignment from the data in the buffer
|
||||||
/// \param dataBuffer the source buffer to un-pack the assignment from
|
/// \param dataBuffer the source buffer to un-pack the assignment from
|
||||||
|
@ -40,7 +47,7 @@ public:
|
||||||
|
|
||||||
Assignment::Direction getDirection() const { return _direction; }
|
Assignment::Direction getDirection() const { return _direction; }
|
||||||
Assignment::Type getType() const { return _type; }
|
Assignment::Type getType() const { return _type; }
|
||||||
const char* getPool() const { return _pool; }
|
Assignment::Location getLocation() const { return _location; }
|
||||||
const timeval& getTime() const { return _time; }
|
const timeval& getTime() const { return _time; }
|
||||||
|
|
||||||
const sockaddr* getAttachedPublicSocket() { return _attachedPublicSocket; }
|
const sockaddr* getAttachedPublicSocket() { return _attachedPublicSocket; }
|
||||||
|
@ -60,7 +67,7 @@ public:
|
||||||
private:
|
private:
|
||||||
Assignment::Direction _direction; /// the direction of the assignment (Create, Deploy, Request)
|
Assignment::Direction _direction; /// the direction of the assignment (Create, Deploy, Request)
|
||||||
Assignment::Type _type; /// the type of the assignment, defines what the assignee will do
|
Assignment::Type _type; /// the type of the assignment, defines what the assignee will do
|
||||||
char* _pool; /// the pool this assignment is for/from
|
Assignment::Location _location; /// the location of the assignment, allows a domain to preferentially use local ACs
|
||||||
sockaddr* _attachedPublicSocket; /// pointer to a public socket that relates to assignment, depends on direction
|
sockaddr* _attachedPublicSocket; /// pointer to a public socket that relates to assignment, depends on direction
|
||||||
sockaddr* _attachedLocalSocket; /// pointer to a local socket that relates to assignment, depends on direction
|
sockaddr* _attachedLocalSocket; /// pointer to a local socket that relates to assignment, depends on direction
|
||||||
timeval _time; /// time the assignment was created (set in constructor)
|
timeval _time; /// time the assignment was created (set in constructor)
|
||||||
|
|
|
@ -382,7 +382,7 @@ const sockaddr_in GLOBAL_ASSIGNMENT_SOCKET = socketForHostnameAndHostOrderPort(G
|
||||||
void NodeList::sendAssignment(Assignment& assignment) {
|
void NodeList::sendAssignment(Assignment& assignment) {
|
||||||
unsigned char assignmentPacket[MAX_PACKET_SIZE];
|
unsigned char assignmentPacket[MAX_PACKET_SIZE];
|
||||||
|
|
||||||
PACKET_TYPE assignmentPacketType = assignment.getDirection() == Assignment::Create
|
PACKET_TYPE assignmentPacketType = assignment.getDirection() == Assignment::CreateDirection
|
||||||
? PACKET_TYPE_CREATE_ASSIGNMENT
|
? PACKET_TYPE_CREATE_ASSIGNMENT
|
||||||
: PACKET_TYPE_REQUEST_ASSIGNMENT;
|
: PACKET_TYPE_REQUEST_ASSIGNMENT;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue